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

Uglify errors in react scripts #73

Closed
harinair opened this issue Nov 6, 2018 · 29 comments
Closed

Uglify errors in react scripts #73

harinair opened this issue Nov 6, 2018 · 29 comments

Comments

@harinair
Copy link

harinair commented Nov 6, 2018

I am running into an Uglify error that was traced to autobind-decorator@2.2.1

autobind-decorator@2.1.0 works fine. The following is the error:

Failed to compile.

Failed to minify the bundle. Error: static/js/main.d366c2d2.js from UglifyJs
Unexpected token: name (fn) [static/js/main.d366c2d2.js:396674,6]
    at compiler.run (/Users/ugangha/Sandbox/Pearson/Cite/greenville/node_modules/@pearson-incubator/react-scripts/scripts/build.js:130:23)
    at emitRecords.err (/Users/ugangha/Sandbox/Pearson/Cite/greenville/node_modules/webpack/lib/Compiler.js:269:13)
    at Compiler.emitRecords (/Users/ugangha/Sandbox/Pearson/Cite/greenville/node_modules/webpack/lib/Compiler.js:375:38)
    at emitAssets.err (/Users/ugangha/Sandbox/Pearson/Cite/greenville/node_modules/webpack/lib/Compiler.js:262:10)
    at applyPluginsAsyncSeries1.err (/Users/ugangha/Sandbox/Pearson/Cite/greenville/node_modules/webpack/lib/Compiler.js:368:12)
    at next (/Users/ugangha/Sandbox/Pearson/Cite/greenville/node_modules/tapable/lib/Tapable.js:218:11)
    at Compiler.compiler.plugin (/Users/ugangha/Sandbox/Pearson/Cite/greenville/node_modules/webpack/lib/performance/SizeLimitsPlugin.js:99:4)
    at next (/Users/ugangha/Sandbox/Pearson/Cite/greenville/node_modules/tapable/lib/Tapable.js:220:14)
    at /Users/ugangha/Sandbox/Pearson/Cite/greenville/node_modules/sw-precache-webpack-plugin/lib/index.js:98:18
    at <anonymous>
Read more here: http://bit.ly/2tRViJ9

This error is happening in a "let" statement. From what I read I feel Uglify cannot handle ES6 code and create react scripts does not convert all node modules to ES5 before feeding to Uglify. My assumption is some build option is changed from 2.1.0 to 2.2.1 so that the build is provided in ES6 not pure ES5.

@jharris4
Copy link

jharris4 commented Nov 6, 2018

I just ran into the exact same issue.

It's definitely a bug related to the contents of the package.json now having "module": "src/index.js", as added in this commit:

9edeabf#diff-b9cfc7f2cdf78a7f4b91a753d10865a2

@jharris4
Copy link

jharris4 commented Nov 6, 2018

@stevemao could you please remove modules from package.json?

The code pointed to by modules needs to be ES5 code but with ES6 modules (import/export).

The problem here is that src had ES6 code (including let etc).

You can read more about it here: https://github.com/rollup/rollup/wiki/pkg.module#wait-it-just-means-import-and-export--not-other-future-javascript-features

@stevemao
Copy link
Collaborator

stevemao commented Nov 6, 2018 via email

@stevemao
Copy link
Collaborator

stevemao commented Nov 6, 2018 via email

@jharris4
Copy link

jharris4 commented Nov 6, 2018

Who says that? Module entry is supposed to point to scripts with Es modules. Tools usually use this entry for tree shaking.

Did you read the link I posted? Basically the authors of webpack & rollup ALL say that modules should point to ES5 code with ONLY es6 modules. And since they are the ones who added it to package.json and implemented tree shaking they're probably the best authority on the subject.

On the other hand, you are using a deprecated minifier and wrong webpack config.

I'm using the latest version of webpack and the latest minifier that it supports. I maintain several projects that use webpack, so I hardly think I'm using a wrong webpack config. It worked fine until the version of autobind-decorator that broke the rules.

If you need to support old environment, you can use Babel env to transpile modern JavaScript to old version.

That is not how the spec for modules in package.json modules works. If you don't want to believe that then I guess people will need to find alternatives if they want to use autobind decorators with modern tools like webpack or rollup.

Have you tried bundling the latest of autobind-decorator with either rollup or webpack? I suggest you try...

@stevemao
Copy link
Collaborator

stevemao commented Nov 6, 2018 via email

@jharris4
Copy link

jharris4 commented Nov 6, 2018

I guess a year and a half is a long time in JS land. lol For what it's worth, Dan Abromov (author of create react app) also said the same thing (a year ago): webpack/webpack#1979 (comment)

If you want to deviate from the original intention of the modules field then that's your prerogative, but you're going against the grain (I have never seen a single other package that exports raw es6 source via the modules field) and you're forcing people to compile all of their node_modules, which is certainly not standard.

I guess I'll leave it here and let other users of this package chime in if they feel the need to.

In any case, speaking of "modern javascript" the new "class properties" proposal & babel-plugin let you just replace:

class Foo {
  @autobind
  aMethod() { }
}

with:

class Foo {
  aMethod = () => { }
}

This is a simpler alternative for our projects than having to compile all source in node_modules to be able to use new versions of this package...

@stevemao
Copy link
Collaborator

stevemao commented Nov 6, 2018

I have never seen a single other package that exports raw es6 source via the modules field

I have seen many packages exporting modern javascript via the main field. This is also the reason why create-react-app compiles node_modules.

In any case, speaking of "modern javascript" the new "class properties" proposal & babel-plugin let you just replace:

That is already mentioned in the README and I think it's a good alternative
https://github.com/andreypopp/autobind-decorator#alternative

@harinair
Copy link
Author

harinair commented Nov 6, 2018

Related Bug:
react-dnd/react-dnd#1152

@jharris4
Copy link

jharris4 commented Nov 6, 2018

@stevemao interesting, can you share some examples of packages that are exporting es6 syntax (other than es6 modules) via the main or modules field? I’m curious if any of them are intended for use in the browser vs node.

@stevemao
Copy link
Collaborator

stevemao commented Nov 6, 2018

In any case, we only added a module entry to the package.json for modern browsers and tree shaking. So it's a new feature. The old main entry is still there any the files are not changed. If you want the old file you can still use the main entry so this is not a breaking change.

@jharris4
Copy link

jharris4 commented Nov 6, 2018

lol, except you can't use minification anymore with webpack without transpiling node modules first.

The right way to fix it is to use separate lib/es outputs like most other libraries do.

Happy to offer pointers if you're open to it. It's just a matter of forking your babel config to change the modules parameter to either preset-es2015 or preset-env...

A good example is here: https://github.com/react-bootstrap/react-bootstrap/blob/master/.babelrc.js

@stevemao
Copy link
Collaborator

stevemao commented Nov 6, 2018

@jharris4 They use jsx in the src so they have to compile it. For those who want to use modern javascript and only target modern browsers/env what's your recommendation?

@harinair
Copy link
Author

harinair commented Nov 7, 2018

@stevemao, For now, we need to look at a workaround. The default create-react-app / react scripts does not support this code. And most devs use the create-react-app. Hence a lot of people who have autobind-decorator dependency will run into this error soon. I personally wasted a day before I tracked this issue to this library.

My recommendation is to create a 3.x version with ES6 features and maintain a 2.x release for ES5 until react start supporting ES6 by default. What do you think?

@stevemao
Copy link
Collaborator

stevemao commented Nov 7, 2018

The default create-react-app / react scripts does not support this code.

It does. I'm using create-react-app too.

I think we can add a note on README.

@stevemao
Copy link
Collaborator

stevemao commented Nov 7, 2018

I have added a note just now on readme. let me know if it makes sense

@jharris4
Copy link

jharris4 commented Nov 7, 2018

ya, I wasted a couple of hours tracking this down myself.

Definitely should have been a version bump as this is definitely a breaking change.

As a workaround, I've just switched to class properties like I posted earlier. so I'm not using this package anymore...

@stevemao I don't have a good answer for how to allow npm packages to be consumed in es6+ only mode. As far as I know nobody has really solved this problem yet, but maybe a new next field in package json to complement the existing main and module fields would be the way to go. I've already weighed in on how module is NOT the place for es6 only code, so not much else I can add despite the fact that I understand your motivation here...

@stevemao
Copy link
Collaborator

stevemao commented Nov 7, 2018

Definitely should have been a version bump as this is definitely a breaking change.

If we pointed main to a ES6 script then it would have been a breaking change.

Thanks @jharris4 . I personally periodically improve my build script and look up create-react-app as a good reference. They have removed deprecated uglify-js and they also compile node_modules (but only from standard javascript).

@stevemao
Copy link
Collaborator

@shouvik44
Copy link

Related Bug:
react-dnd/react-dnd#1152

I couldn't build my app built on Create-React-App using React DnD. Thanks @harinair for pointing to the related thread. If others are experiencing this, the workaround with react dnd is to pin autobind-decorator to version 2.1.0. Since then, I'm able to build just fine.

@stevemao
Copy link
Collaborator

@shouvik44 did you read the blog I linked?

@shouvik44
Copy link

@stevemao I read through it, but I didn't understand how to take action. I can't stop using react-DnD, and the older version of autobind-decorator works well for my current needs.

@catamphetamine
Copy link

catamphetamine commented Nov 27, 2018

@stevemao

I don’t necessarily agree. That article was published a long time ago when es6 was new (the future javascript). Some people only want to target modern browsers (with full support of modern JavaScript), are they forced to run es5 code only?

LOL.
Most of the people only want their apps to just work and not break suddenly.
Are you forcing those people to hack around your preference of putting incompatible js syntax in the release just because you like it more?
The module entry is clearly for ES5 syntax with only ES6 modules, as @jharris4 already said.

@catamphetamine
Copy link

@stevemao

I have seen many packages exporting modern javascript via the main field. This is also the reason why create-react-app compiles node_modules.

And that means that they do it wrong.
If someone jumps from a bridge will you jump too?
I guess you do...

@catamphetamine
Copy link

catamphetamine commented Nov 27, 2018

@stevemao

In any case, we only added a module entry to the package.json for modern browsers and tree shaking. So it's a new feature. The old main entry is still there any the files are not changed. If you want the old file you can still use the main entry so this is not a breaking change.

Man, you don't get it: bundlers do always prefer the module entry ignoring main.
So you're consciously and willingly breaking everyone's projects because you know Webpack won't compile them and you're fine with that.
Well, no wonder react-dnd moved away from using this package.

@catamphetamine
Copy link

@stevemao

For those who want to use modern javascript and only target modern browsers/env what's your recommendation?

OBVIOUSLY, introduce a new main:next entry or whatever else and coordinate between bundlers so that they support it.

@catamphetamine
Copy link

catamphetamine commented Nov 27, 2018

@stevemao

If we pointed main to a ES6 script then it would have been a breaking change.

You don't get it, introducing module already is a breaking change because it takes priority over main.

@stevemao
Copy link
Collaborator

@catamphetamine If I have to argue with you I'll repeat what I have said. Your arguments haven't been constructive and convincing but rather mocking and attempting to taunt me. I suggest be patient and read the babel blog again rather than believing in what you think is right. Coz it's not.

Repository owner locked as resolved and limited conversation to collaborators Nov 27, 2018
@stevemao
Copy link
Collaborator

@catamphetamine If you want to learn how to discuss with people properly in a constructive way, have a look at #78 by @lroling8350. That issue so far has provided really good value. And I really appreciate everyone's inputs. Peace.

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

No branches or pull requests

5 participants