Loading the dev server output in IE11 keeps bundles from loading. It's a hard stop that prevents the base page from even attempting to continue.
Note: This is from what's generated by parcel, not my app source code or my dependencies. See this comment below.
.babelrc
The app works in FF + Chrome (used --no-cache
) without the custom .babelrc
.{
"presets": [
[
"env",
{
"modules": false,
"targets": {
"browsers": [
"> 1%",
"last 2 versions",
"ie 11",
"not ie <= 10"
]
}
}
]
]
}
package.json
here's the full package.json
, below is the scripts and deps only "scripts": {
"clean": "rimraf dist",
"dev": "parcel src/index.html",
"build": "run-s clean build:raw",
"build:raw": "parcel build --public-url . src/index.html",
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-preset-env": "^1.7.0",
"npm-run-all": "^4.1.5",
"parcel-bundler": "^1.10.3",
"rimraf": "^2.6.2"
},
"browserslist": [
"> 1%",
"last 2 versions",
"ie 11",
"not ie <= 10"
]
I start the local server with npm run dev
, which invokes parcel ./src/index.html
.
Note: my package.json
includes the relevant browserslist
, which specifies IE 11.
Bundles should load correctly, including in IE 11.
Bundled app stops loading in IE11 almost immediately. Cites "'Promise' is undefined" in JS console, clicking to the line number points to the loadBundles
function, which returns Promise.all(bundles.map(loadBundle))
.
Also used by Parcel's generated main js file, Promise.resolve
and fetch
. Specifying IE 11 support for targeted browser should ensure that no un-polyfilled APIs are used (Promise, fetch).
Raw console error:
SCRIPT5009: 'Promise' is undefined
main.1f19ae8e.js 394,27)
From the other linked "ie support" descriptions in the changelog and the corresponding culprits, it looks like this is has to do fundamentally with the un-polyfilled Promise
and global
objects, such as fetch
referenced when attempting to load necessary bundles. The loadBundles
fires before my app logic, so no polyfilling on my end will affect the outcome. By performing a build of my repro with manually added polyfills into the head
tag for Promise
and fetch
, this worked; but this isn't something I should have to do.
For my work apps am required to support IE11. I believe this should be achievable w/ parcel, but ran into some trouble. The app works great in Chrome and Firefox. The issues I'm experiencing deal with Parcel's direct use of Promise
and fetch
directly in the initialization of bundles from the built main.<hash>.js
.
I have an example repo:
https://github.com/edm00se/parcel-ie11-issue-demo
Steps to reproduce:
git clone https://github.com/edm00se/parcel-ie11-issue-demo.git
cd parcel-ie11-issue-demo
npm install
npm run dev
http://localhost:1234
in IE 11| Software | Version(s) |
| ------------- | ---------- |
| Parcel | 1.10.3 |
| Node | 10.13.0 |
| npm/Yarn | 6.4.1 |
| Operating System | Windows 10 |
I love parcel, it's a great and performant bundler that's enjoyable to use. When I set out on this crazy path, I wasn't expecting to get as far as I have, and I am 99.8% there!
*note: I've updated this description to point to a far more simple reproducible repo
@DeMoorJasper thanks. If you check my package.json
, it includes a browserslist
config which explicitly includes βie 11β. I believe thatβs all that should be needed. With that said, the generated output still attempts to use Promise.all
, Promise.resolve
, and fetch
to load the generated bundles.
Is there something else Iβm missing?
I also hit this very problem today - seems an issue with the pre-app serving code not the app code transpiling/polyfilling itself.
I was blown away π¨ by Parcel and how it completely simplified the build over webpack, but we pretty much exclusively target IE at work π€¦π»ββοΈ.
Yeah, sadly IE is often still the lowest common denominator. π
Like stated in the comment, every npm package you use that isn't commonjs should also have a browserlist or engines field in pkg.json to indicate what syntax the code is using.
Otherwise parcel would need to assume that all modules need to be compiled if a target isn't defined, which isn't very good for performance.
Iβm confused π€·π»ββοΈ-> isnβt the issue here that Parcel π¦ is trying to unpolyfilled Promise to load its bundles?
I understand running babel over modules which are not compiled down to es5, but isnβt the issue here that Parcel π¦ itself is trying to use the undefined Promise object?
Hereβs what I did to test π¬:
parcel build src/index.html
Tested in IE 11 =>produces error β
Added promise polyfill manually to dist/index.html ; as well as fetch
Works β
To me, that suggests that Promise is being used by Parcel π¦ before its possible to polyfill it (as opposed to any of the dependencies actually causing the issue).
@DeMoorJasper
I'm trying to use it on local (no npm package) scripts, imported via ES6 import.
The event() constructor new Event("event_name");
was easy to workaround, but I don't want to write workaround for every unsupported feature.
@masterwaffle Thatβs what Iβm seeing as well.
Manually dropping polyfills for Promise
and fetch
into the head
tag of my generated dist/index.html
allows the bundles to load/work correctly in IE.
<script src="https://unpkg.com/es6-promise/dist/es6-promise.auto.min.js"></script>
<script src="https://unpkg.com/unfetch/polyfill/index.js"></script>
I threw together a dead simple reproducible app, purely vanilla (no frameworks), but with configured babel which should match up with parcel's requirements from the app source perspective. This shows the same behavior I described, with less surrounding clutter. Specifically, with more than one bundle, Parcel itself relies directly on Promise
and fetch
.
source: https://github.com/edm00se/parcel-ie11-issue-demo
deployed: https://edm00se.codes/parcel-ie11-issue-demo/
I've updated the description of this to reflect the bare bones repro as outlined in my last comment.
To be clear, the bare bones example only has multiple bundles, because that's how it's done when requiring in html partial files.
Like stated in the comment, every npm package you use that isn't commonjs should also have a browserlist or engines field in pkg.json to indicate what syntax the code is using.
Otherwise parcel would need to assume that all modules need to be compiled if a target isn't defined, which isn't very good for performance.
@DeMoorJasper I have a repro.
It has:
Promise
and fetch
APIsbundle-loader.js
, not the app sourcehtml
fileIs there a better way of being able to require the html
content and ensure compatibility down to es5/IE11?
For any interested in this issue, I threw together a parcel plugin to add high level polyfills for both Promise
and fetch
to keep parcel's bundle loader working in IE(11).
repo: https://github.com/edm00se/parcel-plugin-goodie-bag
use: npm i -S parcel-plugin-goodie-bag
(auto loads into index.html
on build/dev)
TY @edm00se your plugin worked perfectly for me!
I'm glad to hear it @riverross.
In case it's not clear from above, part of the reason I had issues was due to:
babel-polyfill
, which is the v6 babel package, doesn't polyfill either Promise
or fetch
Promise
with the v7 package, @babel/polyfillfetch
polyfill will still be neededPromise
polyfill is still be needed _before_ our source code is hitbabel-polyfill
fires _after_ when Parcel will need it for a multi bundle scenarioI _wish_ there was an easier way of doing this, making Parcel more intelligent regarding browser support detection and doing this so I wouldn't have to. That said, it's behaving with what it was given as far as configuration. With any luck that might change in the future, until then we can work with the situation. π€
@edm00se Thank you for your comment!!
your comment was very helpful:)
What's the point on even having browserslist if it won't work as expected.
@tomasdev as a consumer of dev tooling, I agree.
I think what is central here is that parcel, at least v1's approach, seems to try to provide default enabled and configurable "other tools". My preference would look something along the lines of detecting the browserslist
definition and determining whether to need to polyfill Promise
and fetch
early in its generated code, providing a virtually seamless experience.
Further activity, to stave off the bots.
@edm00se I have the same issue, only worse. In a Typescript project, we need to support IE11, which means a lot more than Promise
and fetch
.
.babelrc
{
"presets": [
"@babel/preset-typescript",
"@babel/preset-react",
[
"@babel/preset-env",
{
"debug": true,
"corejs": {
"version": 3
},
"useBuiltIns": "entry"
}
]
],
"plugins": [
"@babel/plugin-transform-runtime"
]
}
.browserlist
last 2 versions
IE 11
not dead
src/index.ts (main entry point)
// IE11 polyfills >
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import 'whatwg-fetch';
// ...
This worked, but now I added a new dependency and that one doesn't get transpiled. There's an issue already open: #1655
The temporary fix for that was a postinstall script that modifies node_modules/**/package.json
. π
Hope this helps someone else and maybe someone points out a mistake in my code.
Most helpful comment
For any interested in this issue, I threw together a parcel plugin to add high level polyfills for both
Promise
andfetch
to keep parcel's bundle loader working in IE(11).repo: https://github.com/edm00se/parcel-plugin-goodie-bag
use:
npm i -S parcel-plugin-goodie-bag
(auto loads intoindex.html
on build/dev)