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

Dynamic `import()` crashing in `ModuleConcatenationPlugin` #5663

Closed
akx opened this Issue Sep 11, 2017 · 7 comments

Comments

Projects
None yet
8 participants
@akx
Contributor

akx commented Sep 11, 2017

What is the current behavior?

Running a module with if(...) { import().then(...) } through ModuleConcatenationPlugin results in an Acorn exception with Webpack 3.5.2. The module has been run through Babel w/ babel-preset-env and modules=false.

ERROR in chunk global [initial]
[name].[hash].js
'import' and 'export' may only appear at the top level (112:2)
|
| if (false) {
|   import('react-addons-perf').then(function (Perf) {
|     window.Perf = Perf;
|   });
SyntaxError: 'import' and 'export' may only appear at the top level (112:2)
|
| if (false) {
|   import('react-addons-perf').then(function (Perf) {
|     window.Perf = Perf;
|   });
    at Parser.pp$4.raise (~/node_modules/webpack/node_modules/acorn/dist/acorn.js:2610:13)
    at Parser.pp$1.parseStatement (~/node_modules/webpack/node_modules/acorn/dist/acorn.js:780:16)
    at Parser.pp$1.parseBlock (~/node_modules/webpack/node_modules/acorn/dist/acorn.js:1076:23)
    at Parser.pp$1.parseStatement (~/node_modules/webpack/node_modules/acorn/dist/acorn.js:774:34)
    at Parser.pp$1.parseIfStatement (~/node_modules/webpack/node_modules/acorn/dist/acorn.js:901:26)
    at Parser.pp$1.parseStatement (~/node_modules/webpack/node_modules/acorn/dist/acorn.js:763:31)
    at Parser.pp$1.parseTopLevel (~/node_modules/webpack/node_modules/acorn/dist/acorn.js:690:23)
    at Parser.parse (~/node_modules/webpack/node_modules/acorn/dist/acorn.js:543:15)
    at Object.parse (~/node_modules/webpack/node_modules/acorn/dist/acorn.js:3669:37)
    at modulesWithInfo.forEach.info (~/node_modules/webpack/lib/optimize/ConcatenatedModule.js:418:18)
    at Array.forEach (<anonymous>)
    at ConcatenatedModule.source (~/node_modules/webpack/lib/optimize/ConcatenatedModule.js:411:19)
    at ModuleTemplate.render (~/node_modules/webpack/lib/ModuleTemplate.js:14:31)
    at ~/node_modules/webpack/lib/Template.js:116:28
    at Function.from (native)
    at Chunk.mapModules (~/node_modules/webpack/lib/Chunk.js:163:16)
    at ChunkTemplate.renderChunkModules (~/node_modules/webpack/lib/Template.js:113:26)
    at ChunkTemplate.render (~/node_modules/webpack/lib/ChunkTemplate.js:16:30)
    at Compilation.createChunkAssets (~/node_modules/webpack/lib/Compilation.js:1290:35)
    at sealPart2 (~/node_modules/webpack/lib/Compilation.js:646:10)
    at next (~/node_modules/tapable/lib/Tapable.js:202:11)
    at Compilation.compilation.plugin (~/node_modules/webpack/lib/ProgressPlugin.js:111:6)
    at Compilation.applyPluginsAsyncSeries (~/node_modules/tapable/lib/Tapable.js:206:13)
    at Compilation.seal (~/node_modules/webpack/lib/Compilation.js:596:8)
    at applyPluginsParallel.err (~/node_modules/webpack/lib/Compiler.js:514:17)
    at ~/node_modules/tapable/lib/Tapable.js:289:11
    at _addModuleChain (~/node_modules/webpack/lib/Compilation.js:498:11)
    at processModuleDependencies.err (~/node_modules/webpack/lib/Compilation.js:468:14)
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)

If the current behavior is a bug, please provide the steps to reproduce.

I'm unfortunately unable to reproduce this using a minimal repo – a minimal repo I tried to make works fine ☹️

What is the expected behavior?

No crashing :)

Naturally the workaround is to disable ModuleConcatenationPlugin.

@sokra sokra added this to the webpack 3 milestone Sep 12, 2017

@tarelli

This comment has been minimized.

Show comment
Hide comment
@tarelli

tarelli Sep 26, 2017

I have the same error with Webpack 3.6.0 and babel-preset-env. In my case the code has nothing to do with ModuleConcatenationPlugin but it's just application code where we have the import.

Module build failed: SyntaxError: 'import' and 'export' may only appear at the top level (143:16)

  141 | 				var that = this;
  142 | 	            		if(componentType=="CONSOLE"){
> 143 | 	            			import(/* webpackChunkName: "console" */ './interface/console/Console').then(
      | 	            			^
  144 | 	            					loadedModule => {
                                                                                                  ...

Webpack config:

 {
                test: /\.(js)$/, exclude: [/node_modules/, /build/, /\.bundle/, /ami.min.js/], 
                loader: 'babel-loader',
                query: {
                    presets: ['react', ['babel-preset-env', { "modules": false }]]
                }
}

Am I missing something? Thanks!

tarelli commented Sep 26, 2017

I have the same error with Webpack 3.6.0 and babel-preset-env. In my case the code has nothing to do with ModuleConcatenationPlugin but it's just application code where we have the import.

Module build failed: SyntaxError: 'import' and 'export' may only appear at the top level (143:16)

  141 | 				var that = this;
  142 | 	            		if(componentType=="CONSOLE"){
> 143 | 	            			import(/* webpackChunkName: "console" */ './interface/console/Console').then(
      | 	            			^
  144 | 	            					loadedModule => {
                                                                                                  ...

Webpack config:

 {
                test: /\.(js)$/, exclude: [/node_modules/, /build/, /\.bundle/, /ami.min.js/], 
                loader: 'babel-loader',
                query: {
                    presets: ['react', ['babel-preset-env', { "modules": false }]]
                }
}

Am I missing something? Thanks!

@sgal

This comment has been minimized.

Show comment
Hide comment
@sgal

sgal Oct 5, 2017

@akx @tarelli Could you please share .babelrc contents (if used). And also try to use babel-plugin-dynamic-import.

I'm using both babel-preset-env and ModuleConcatenationPlugin and don't have this error.

Also, it would be nice to check webpack configs that you guys are using.

sgal commented Oct 5, 2017

@akx @tarelli Could you please share .babelrc contents (if used). And also try to use babel-plugin-dynamic-import.

I'm using both babel-preset-env and ModuleConcatenationPlugin and don't have this error.

Also, it would be nice to check webpack configs that you guys are using.

@thecodejack

This comment has been minimized.

Show comment
Hide comment
@thecodejack

thecodejack Oct 9, 2017

@sgal please check the latest comment of #5760 to reproduce this issue

thecodejack commented Oct 9, 2017

@sgal please check the latest comment of #5760 to reproduce this issue

@thecodejack

This comment has been minimized.

Show comment
Hide comment
@thecodejack

thecodejack Oct 12, 2017

Since #5760 is closed, copying same comment here

@sgal @donocode
Just got the usecase after observing my code failure and #5663. Code is failing only when we have dynamic imports inside if statement which has false set directly like following.

if (false) {
     module.hot.accept('./reducers', function () {
       import('./reducers').then(function (reducerModule) {
         var createReducers = reducerModule.default;
         var nextReducers = createReducers(store.asyncReducers);

When I set it to a variable like following, it doesn't throw any error.

const flag = false;
if (flag) {
     module.hot.accept('./reducers', function () {
       import('./reducers').then(function (reducerModule) {
         var createReducers = reducerModule.default;
         var nextReducers = createReducers(store.asyncReducers);

Not sure if this is a babel issue or webpack's acorn issue.

thecodejack commented Oct 12, 2017

Since #5760 is closed, copying same comment here

@sgal @donocode
Just got the usecase after observing my code failure and #5663. Code is failing only when we have dynamic imports inside if statement which has false set directly like following.

if (false) {
     module.hot.accept('./reducers', function () {
       import('./reducers').then(function (reducerModule) {
         var createReducers = reducerModule.default;
         var nextReducers = createReducers(store.asyncReducers);

When I set it to a variable like following, it doesn't throw any error.

const flag = false;
if (flag) {
     module.hot.accept('./reducers', function () {
       import('./reducers').then(function (reducerModule) {
         var createReducers = reducerModule.default;
         var nextReducers = createReducers(store.asyncReducers);

Not sure if this is a babel issue or webpack's acorn issue.

@matoilic

This comment has been minimized.

Show comment
Hide comment
@matoilic

matoilic Oct 18, 2017

I've run into the same issue. It seems that Webpack usually transforms import declarations and dynamic import calls before the code is passed to babel for transformation. But it skips the transformation when the import is within an unreachable code block. Babylon, Babel's JavaScript parser, then throws because it only allows import on the top level by default.

The question is if Babylon behaves correctly here. Even with allowImportExportEverywhere disabled, one would expect dynamic imports to work.

matoilic commented Oct 18, 2017

I've run into the same issue. It seems that Webpack usually transforms import declarations and dynamic import calls before the code is passed to babel for transformation. But it skips the transformation when the import is within an unreachable code block. Babylon, Babel's JavaScript parser, then throws because it only allows import on the top level by default.

The question is if Babylon behaves correctly here. Even with allowImportExportEverywhere disabled, one would expect dynamic imports to work.

@Kovensky

This comment has been minimized.

Show comment
Hide comment
@Kovensky

Kovensky Oct 20, 2017

Collaborator

Nope; babel will always process the code before webpack ever sees it; unless for some reason the file itself is being excluded from being processed by babel-loader.

This error is unrelated to babel; it's a webpack issue.

Collaborator

Kovensky commented Oct 20, 2017

Nope; babel will always process the code before webpack ever sees it; unless for some reason the file itself is being excluded from being processed by babel-loader.

This error is unrelated to babel; it's a webpack issue.

@ooflorent

This comment has been minimized.

Show comment
Hide comment
@ooflorent

ooflorent Jan 22, 2018

Member

Fixed in 4.0.0-alpha.5.

Member

ooflorent commented Jan 22, 2018

Fixed in 4.0.0-alpha.5.

@nl0 nl0 referenced this issue Feb 7, 2018

Merged

upgrade JS stuff #326

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment