Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug Report: babel-preset-env feature-detection error with dynamic import() statements. #7402

Closed
jgerigmeyer opened this issue Feb 20, 2018 · 13 comments
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: preset-env

Comments

@jgerigmeyer
Copy link

Bug Report:

When using babel-preset-env with useBuiltIns: 'usage' and webpack's dynamic imports (e.g. import('my-module').then(...)) -- along with @babel/plugin-syntax-dynamic-import -- feature-detection fails to include es6.promise, which is required for the code to work on IE11.

Input Code

import('my-module');

Compiled input code:

__webpack_require__.e/* import() */(2).then(__webpack_require__.bind(null, 155));

Elsewhere in the Webpack runtime:

/******/ 	__webpack_require__.e = function requireEnsure(chunkId) {
/******/ 		...
/******/ 		// setup Promise in chunk cache
/******/ 		var promise = new Promise(function(resolve, reject) {
/******/ 			installedChunkData = installedChunks[chunkId] = [resolve, reject];
/******/ 		});
/******/ 		installedChunkData[2] = promise;

Babel/Babylon Configuration (.babelrc, package.json, cli command)

{
  plugins: ['@babel/plugin-syntax-dynamic-import'],
  presets: [
    [
      '@babel/preset-env',
      {
        modules: false,
        useBuiltIns: 'usage',
      },
    ],
  ],
}

Expected Behavior

Using targets:
{
  "ie": "11"
}

Using modules transform: false

Using polyfills with `usage` option:
[/path/to/my/file.js] Added following polyfill:
  es6.promise { "ie":"11" }

No errors in IE 11.

Current Behavior

Using targets:
{
  "ie": "11"
}

Using modules transform: false

Using polyfills with `usage` option:
[/path/to/my/file.js] Based on your code and targets, none were added.

IE11 error: 'Promise' is undefined

Possible Solution

Not sure the ideal fix -- is this a bug in babel-loader, or @babel/preset-env, or @babel/plugin-syntax-dynamic-import, or even webpack? In the meantime, a workaround is to add either of the following in the input JS file:

const p = new Promise();

or

import 'core-js/modules/es6.promise';

Your Environment

software version(s)
Babel 7.0.0-beta.40
webpack 3.11.0
node 8.9.4
npm 5.6.0
yarn 1.3.2
Operating System macOS 10.13.3
@babel-bot
Copy link
Collaborator

Hey @jgerigmeyer! We really appreciate you taking the time to report an issue. The collaborators
on this project attempt to help as many people as possible, but we're a limited number of volunteers,
so it's possible this won't be addressed swiftly.

If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack
community that typically always has someone willing to help. You can sign-up here
for an invite.

@hzoo
Copy link
Member

hzoo commented Feb 21, 2018

So this is because it doesn't know that import is going to be turned into a Promise eventually and thus it doesn't add the polyfill.

Yeah you can even just do Promise; as a workaround. Or include it in the includes option. Not sure how we are supposed to deal with this, unless we also infer that you are using webpack, etc.

@jgerigmeyer
Copy link
Author

Yeah, that makes sense. At the very least it seems like a note about this should be added to the documentation, probably of @babel/plugin-syntax-dynamic-import?

@nathan-isaac
Copy link

nathan-isaac commented Oct 17, 2018

Just for future reference, IE required me to include promise and array iterator polyfills to make dynamic imports work.

This is what I did in my webpack config.

const config = {
    entry: [
        'core-js/modules/es6.promise',
        'core-js/modules/es6.array.iterator',
        path.resolve(__dirname, "src/main.js"),
    ],
    // ...
}

@existentialism
Copy link
Member

@nathanjisaac want to push a PR to the website repo adding this helpful tip?

@shane-tw
Copy link

I'm encountering this same issue with transform-runtime.
The above solution sadly wouldn't work as I'm pretty sure(?) that would mean polluting the global scope.
Is there a workaround for transform-runtime anyone recommends?

@nicolo-ribaudo
Copy link
Member

Babel doesn't run on the webpack runtime code, so transform-runtime can't work here (unless you run Babel on the file generated by webpack).

@zloirock
Copy link
Member

zloirock commented Feb 14, 2019

It's not a problem to include Promise dependencies on dynamic import statement in preset-env. I'll add it in #7646.

nicolo-ribaudo pushed a commit that referenced this issue Mar 19, 2019
### `@babel/runtime`
- Added `@babel/runtime-corejs3` package and `corejs: 3` options to `@babel/plugin-transform-runtime`.
- Added support of instance methods, fixes #8928.
- Added flag `proposals` (in `corejs: { version: 3, proposals: true }` format) for support all proposals polyfills from `core-js`.
- Used separate directories in runtime for `core-js` entry points with proposals and without.
- Used `get-iterator-method` helper for getting iterators, fixes #2500.
- As a cheap bonus, added support of IE8- (except some cases of `regenerator`).

### `@babel/polyfill`
- Should be deprecated in favor of separate usage required features from `core-js` and `regenerator-runtime` with an informative message.

### `@babel/preset-env`
- Uses for built-ins data from [`core-js-compat`](https://github.com/zloirock/core-js/tree/master/packages/core-js-compat) instead of `compat-table` since information from `compat-table` [is not enough](https://github.com/zloirock/core-js/tree/master/packages/core-js-compat).
- `useBuilIns` now requires direct setting of `corejs` version option, without it will be used `2` by default and shown deprecation warning.
- Added support of minor `core-js` versions for simplify updating in the future.
- For preventing some order-related problems, polyfills in the both `core-js@3` plugins added on `post` stage in the order of `core-js-compat` data.
- Divided plugins and polyfills parts of `preset-env`, instead of 2 internal plugins for adding polyfills, we have 6: usage and entry versions of plugins for `core-js@2`, ### Current state:
`core-js@3`, `regenerator-runtime`.
- Added support `samsung` target (for Samsung Internet) since `core-js-compat` and `compat-table` now contains mapping for this, fixes #6602.

#### `useBuilIns: entry` with `corejs: 3`
- No longer transforms `@babel/polyfill`.
- Transforms **all possible** `core-js` entry points to import of related modules (based on data from [`core-js-compat`](https://unpkg.com/core-js-compat@3.0.0-beta.15/entries.json)).
- Since of this, we no longer need `shippedProposals` / `proposals` flags with `useBuilIns: entry`.
- Removes `regenerator-runtime/runtime` import where it's not required.

#### `useBuilIns: usage` with `corejs: 3`
- In addition to `shippedProposals`, added flag `proposals`  (in `corejs: { version: 3, proposals: true }` format) for polyfill all proposals from `core-js`.
- Fixed list of dependencies in built-in definitions.
- Improved the way of determination method / built-in name and source of this method.
- Adds import of required polyfills on `MemberExpression`, `ObjectPattern`, `in` operator.
- Adds import of required polyfills on access to global object properties.
- Adds import of all required common iterators on all syntax features which use iterators protocol (`for-of`, destructuring, spread, `yield` delegation, etc.).
- Adds import of promises on syntax features which use promises (async functions/generators, dynamic import, etc.), fixes #9250, #7402, etc.

### `core-js@2` stuff
I didn't want to tough `core-js@2`-related stuff, however
- Fixed some serious errors in definitions which breaks `Object.getOwnPropertySymbols`, `Symbol.toStringTag` logic, `Promise#finally`, `Array#forEach`, etc.
- `Array#flatMap` and trim methods moved to stable features as a part of ES2019 and loaded by deprecated `@babel/polyfill` and `@babel/preset-env` with `corejs: 2` option.
@sarod
Copy link

sarod commented Apr 18, 2019

Edit: I was wrong it appears that this solution does not work.

For future reference I modified my preset-env include instead of modifying my webpack config as It allows me to collocate everything related to IE support:

{
   presets: [
      [
         '@babel/env',
         {
            "useBuiltIns": "usage",
            "corejs": {version: 3},
            "include": [
               // We need to include ie11 polyfills used by webpack dynamic import
               // because webpack generated code does not go through babel
               'es.promise',
               'es.array.iterator'
            ],
            "targets": [
               'ie >= 11',
               //...
            ]
         }
      ],
   ]
}

@zloirock
Copy link
Member

@sarod with core-js@3 it should work without include section. More other, include makes no sense with useBuiltIns: usage.

@sarod
Copy link

sarod commented Apr 18, 2019

@zloirock If I use a dynamic-import in my code it looks like "usage" does not include the promise automatically which would make sense according to @nicolo-ribaudo comment above given that the Promise is only used in webpack runtime code.

In any case I can make it work on IE11 by either:

But if I remove them both IE11 fails to load with "Unhandled promise rejection TypeError: Target is not iterable" raised from core-js/internal/iterate.js.
Debugging it it looks like the Promise polyfill is properly loaded but it is not iterable.

@sarod
Copy link

sarod commented Apr 18, 2019

After more tests it appears I was wrong: adding the "include" config in preset does not help. I probably had a caching issue somewhere. Sorry about that.

However I still need to modify my webpack entry even if I use core-js@3 & "useBuiltIns: usage" to include 'core-js/modules/es.array.iterator'
From what I understand @zloirock you think this is a bug right? If so should I create a separate issue?

@zloirock
Copy link
Member

@sarod it's tested and should work. So yes, it's another issue.

@lock lock bot added the outdated A closed issue/PR that is archived due to age. Recommended to make a new issue label Jul 18, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Jul 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated A closed issue/PR that is archived due to age. Recommended to make a new issue pkg: preset-env
Projects
None yet
Development

No branches or pull requests

10 participants