webpack: Uncaught SyntaxError: Unexpected token import

Bug

What is the current behavior? In case of development environment such code

if (process.env.NODE_ENV === 'testing') {
  import('somemodule');
}

is transformed by webpack 2.5.1 into this

if (false) {
  import('somemodule');
}

which leads to Uncaught SyntaxError: Unexpected token import error in the latest Chrome.

Node.JS 7.10.0, babel 6.24.1 has syntax-dynamic-import plugin

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 3
  • Comments: 20 (3 by maintainers)

Most upvoted comments

Fixed in 4.0.0-alpha.5.

Hey guys, maybe I’ll be a little help for you. @klimashkin Could you maybe share your webpack and babel configs? I just tried to run following code through webpack:

if (process.env.NODE_ENV === 'production') {
  import('./something.js');
}

and it gets transpiled properly. Just make sure(and it’s also a tip for @anlexN), that you have babel-loader included properly in module section in your configuration with syntax-dynamic-import plugin already mentioned above:

 module: {
    rules: [
      {
        test: /\.js(x?)$/,
        exclude: /(node_modules)/,
        use: [
          {
            loader: 'babel-loader',
          },
        ],
      },
  ],
}

and my .babelrc config(you can also include this configuration right within webpack.config.js, see https://github.com/babel/babel-loader#options):

{
  "presets": [
    [
      "env",
      {
        "modules": false,
        "targets": {
          "browsers": [
            "last 2 versions",
          ]
        }
      }
    ]
  ],
  "plugins": [
    "syntax-dynamic-import"
  ]
}

Babel should at least transpile dynamic import on unreachable blocks. This should solve that problem without this painful.

This completely breaks the entire concept of webpack.

This is 100% broken.

Because I use if (module.hot) my app does not work in production…so i am going in and manually deleting all that code everywhere each time i want to go to production… stupid as fuck lolz

Uglify does not work or i would use that… some it fails because some node module has some file that isnt actually included in anything that has some syntax error

I had this same problem (also with module.hot that was turned into false at transpile-time, creating an unreachable block).

I managed to work around it by including something that could not be evaluated to false at transpile-time, forcing webpack to transpile the contents of the if-block:

var alwaysFalse = false;
if (module.hot || alwaysFalse) {
  import('./SomeFile').then(() => {}); // Now this gets transpiled correctly
}

Maybe this can help someone else while this gets fixed.

@anlexN It is only needed if you want to use newer syntax and language future in your configuration. See https://webpack.js.org/configuration/configuration-languages/ for more info.

Don’t! It’s painful!. This is webpack authors’ wrong, not our developers’ wrong…

Running into this issue as well with latest version of webpack, a reasonable solution would be to use the UglifyJsPlugin to just strip the false conditional blocks since that is what you meant to do anyway, however, there doesn’t appear to be a straight forward way to do this without having your dev source mangled a bit and UglifyJs does add to the compilation time as well (in my case +65%).

new UglifyJsPlugin({
  compressor: {
    angular: false,
    booleans: false,
    cascade: false,
    collapse_vars: false,
    comparisons: false,
    conditionals: true,
    dead_code: true,
    drop_console: false,
    drop_debugger: false,
    evaluate: true,
    expression: false,
    global_defs: {},
    hoist_funs: false,
    hoist_vars: false,
    if_return: false,
    join_vars: false,
    keep_fargs: true,
    keep_fnames: false,
    keep_infinity: false,
    loops: false,
    negate_iife: false,
    passes: 1,
    properties: false,
    pure_getters: false,
    pure_funcs: null,
    reduce_vars: false,
    screw_ie8: false,
    sequences: false,
    side_effects: false,
    switches: false,
    top_retain: null,
    toplevel: false,
    unsafe: false,
    unsafe_comps: false,
    unsafe_math: false,
    unsafe_proto: false,
    unsafe_regexp: false,
    unused: false,
    warnings: false
  },
  mangle: false,
  output: {
    beautify: true,
    bracketize: true
  }
})

Any updates on this? I am having this issue as well with the following code. Chrome seems to throw an error any time it sees import.

if (module.hot) {
  module.hot.accept('./sagas', () => {
    // following line is the culprit
    import('./sagas').then(({ default: newSagas }) => {
      const promises = sagaTasks.map(task => {
        task.cancel();
        return task.done;
      });
      Promise.all(promises).then(() => {
        sagaTasks = newSagas.map(saga => sagaMiddleware.run(saga));
      });
    });
  });
}

I’ve tried using syntax-dynamic-import to fix the issue, but it persists even with that plugin. However, the issue is fixed when I use UglifyJSPlugin leading me to believe it changes the name of the import function and then the browser doesn’t care. FYI this is being built with a production webpack config (minus uglification), so the HMR plugins are not there.

@michael-ciniawsky, i don’t use babel anything! why rename webpack.config.js to webpack.config.babel.js?

Are you using the DefinePlugin to set process.env.NODE_ENV ?

@michael-ciniawsky Sure thats how

if (process.env.NODE_ENV === 'testing') {
  import('somemodule');
}

can be transformed to

if (false) {
  import('somemodule');
}

If you read first message of this thread