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

Webpack Parser failes to parse valid code #4231

Closed
sateffen opened this issue Feb 7, 2017 · 9 comments
Closed

Webpack Parser failes to parse valid code #4231

sateffen opened this issue Feb 7, 2017 · 9 comments

Comments

@sateffen
Copy link

sateffen commented Feb 7, 2017

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

Webpack fails to parse this file with the error:

Module parse failed: C:...\file.js The keyword 'await' is reserved (10924:20)
You may need an appropriate loader to handle this file type.
| return this;
| },
| await: function await(callback) {
| if (typeof callback !== "function" || this._call) throw new Error();
| this._call = function (error, results) {

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

  • download the above file, naming it file.js
  • setup a simple webpack config, like
module.exports = {
    entry: {
        'dist.js': './file.js' // the sourcefile is the file from pastebin
    },
    output: {
        filename: '[name]'
    }
};
  • execute webpack with this config

What is the expected behavior?

Webpack should parse the file just as normal, not throwing an error

Please mention other relevant information such as the browser version, Node.js version, webpack version and Operating System.

Webpack 2.2.1, Windows 7, Node 7.5.0, NPM 4.1.1

Additional Information

The file from pastebin is a generated file. It's generated, when using the babel loader in a configuration like:

{
    test: /\.js$/,
    use: {
        loader: 'babel-loader',
        options: {
            presets: [
                ['es2015', {modules: false}] // the modules: false is important! Otherwise no error occurs
            ],
            plugins: [
                'transform-runtime'
            ]
        }
    }
}

(dependencies: webpack, babel-loader, babel-core, babel-preset-es2015, babel-plugin-transform-runtime, babel-runtime)

and then requiring d3 v4.5.0 in a sourcefile. The file node_modules/d3/build/d3.js with the above babel-loader configuration results in the pastebin file, which fails bundling in webpack.

@TheLarkInn
Copy link
Member

Thanks for this report. Would you be able to provide a clonable repo which demonstrates/reproduces this issue? (It heavily expedites the triage and fixing process).

@sateffen
Copy link
Author

sateffen commented Feb 7, 2017

Yep, no problem: An example repository

@montogeek
Copy link
Member

After searching in the dependency repo, these issues appeared:
d3/d3-queue#55
d3/d3-queue#58

The solution is upgrade your d3-queue version

@sateffen
Copy link
Author

sateffen commented Feb 7, 2017

Sadly, I can't update d3-queue, because the sourcecode of d3-queue still is the same (containing the await), and I'm using d3 itself, which contains a bundled version with the code. But I guess that's a problem of d3 then.

I've published another config to the example repository, which can be triggered by calling npm run working. The setup is nearly the same, containing the same code (await: function await(callback)) but is no error. The working example just works.

Why is the code treated differently, while targeting the same platform? I think then, consequently, the code should be treated the same.

@sokra
Copy link
Member

sokra commented Feb 8, 2017

await is a reserved keyword in newer ES. Don't use it as function name!

I also tell you why your working example works: webpack automatically falls back to parsing your code with an older ES if it can't parsed in newer ES. The original example doesn't fallback because the code also includes import which are only available in newer ES. In the working example the babel-loader removes this importss.

@sokra sokra closed this as completed Feb 8, 2017
@sateffen
Copy link
Author

sateffen commented Feb 8, 2017

@sokra that is quite inconsistent. You assume, based purly on imports, what the use MIGHT want to target, but that is just a guess. In our case, the import statement is used, but the code itself is es5, so it's all valid. Just because of the import pattern webpack shouldn't fall back to parse the file with an older standard, because you can't know the target environment.

I won't say it's webpacks job to tell the user, that his code is properbly wrong, but I'd say it's inconsistent to tell the user "well, the exact same code goes through 2 different chains in webpack, and one tells you the problem in advance, the other doesn't" just based on some unrelated import stuff. That just feels not right.

Btw the main problem is babel, transpiling code from {await: function() {}} to {await: function await() {}}. In webpack it's just the lack of consistency.

@Flave
Copy link

Flave commented Feb 12, 2017

I'm having the exact same problem.

It seems to be fine when changing ['es2015', {"modules": false}] to ['es2015'] in the babel-loader query but I want to keep the {"modules": false}.

I don't really understand why this is happening. Is there fix to this?

@sateffen
Copy link
Author

Hey @Flave

The problem is, that not transpiling the modules down to common js leads webpack to parse the module as "es6 module" (because of the es6 imports), where await might be a reserved keyword. Parsing the imports to commonjs, webpack thinks it's a es5 module, and treats the module differently. That is quite inconsequent, but it's the way it is.

The main problem is babel generating the invalid code. The babel plugin babel-plugin-transform-es2015-function-name, which is present in the es2015 preset, creates the problem (transforming {await: function() {}} to {await: function await() {}}, so making invalid code based on valid).

The problem is known as issue on the babel repository, and there are multiple pullrequests as well, but the guys from babel are not responding somehow.

You can eigther create your own babel, containing this fix, create your own preset, or use other transpilers, just like buble (which genereates much better code, and is much faster).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants