-
-
Notifications
You must be signed in to change notification settings - Fork 26.8k
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
npm run build fails for EventEmitter #1023
Comments
Same issue when including "recharts": "^0.18.0". This package also includes EventEmitter. It looks as though at this point, the chances of successfully building a 'production' build with create-react-app are rather low. In related posts, it was mentioned as a work-around to include our own implementation of EventEmitter. Can someone describe how to do that? Specifically, I do not know how to ensure that dependencies such as recharts import the included implementation of EventEmitter rather than falling back onto node.js's. Is there a webpack setting? If so, react-scripts should probably include it. Would be great if this were addressed. Currently the only work-around is to disable the 'UglifyJSPlugin', but this requires reaching inside CRA (or ejecting). |
We replaced the node EventEmitter with EventEmitter3 for Cerebral2. But this was only possible because we are the authors of all dependencies which use the EventEmitter. |
Can you investigate where this problem is coming from? I'm sorry I don't have much time to investigate it right now but I'd be happy to accept a fix for it.
Well this problem never occurred before, so it must be something new. Can you take time to figure out why it happens and propose a fix? |
In particular I would expect Webpack to take EventEmitter implementation from some collection of shims. The question is, then, why those shims aren't in ES5 anymore and where they are located. This is not something you would require CRA maintainers to investigate—you could try to dig into it by yourself and figure out which package is responsible for that code and when it changed. |
Updated: comment deleted since I'm misunderstand the situation 😄 |
generally the webpack shims come from: https://github.com/webpack/node-libs-browser assuming something else isn't messing with the module resolution |
The question is, then, what changed there that the source of EventEmitter is no longer ES5. |
events.js uses template strings from node 6.0.0. |
So it comes from core node. |
@henri-hulski it seems webpack is supposed to not use that native implementation from NodeJS, but instead use one from |
In my case it uses the native implementation. |
And the example in the first post by @godmar gets also exactly the same error message as I from events.js:
|
right, but in my case it used the shim implementation. So there are some difference between our system that cause this issue, I guess? I'm using Mac OS Sierra, and my Node is 6.3.0, could that be the difference? |
A detailed description of my case you find in cerebral/cerebral#389. My system: In our team only 2 persons got this bug. |
The second configuration which got this error was: Kernel : Linux 4.4.0-45-generic (x86_64) npm: 3.10.8 |
Are all your team using the same version of distribution of Linux? There are people reported that they see similar issues in Ubuntu |
have to check with the webpack team I think, but I believe depending on the target it will: include a shim, use the native code, or include nothing. https://webpack.github.io/docs/configuration.html# node the docs would suggest that not all node modules have this behavior but the docs may be incomplete. newer node will have es6 code in the core implementations so maybe it's folks on newer node? the shims haven't been updated in 6 months so they probably aren't the problem. |
BTW Failed to compile.
static/js/main.c359f549.js from UglifyJs
Unexpected character '`' [/usr/lib/nodejs/internal/util.js:4,0] Failed to compile.
static/js/main.3335427e.js from UglifyJs
Unexpected character '`' [/usr/lib/nodejs/internal/util.js:30,0] Failed to compile.
static/js/main.cebb091d.js from UglifyJs
SyntaxError: Unexpected token: punc (.) [/usr/lib/nodejs/internal/util.js:64,0] And I also got error when using node v5.12.0 before: static/js/main.957b2071.js from UglifyJs
SyntaxError: Unexpected token: keyword (const) [/usr/lib/nodejs/util.js:564,0] |
@jquense So yeah I think you're right. |
So is there a solution that does not require dropping/commenting out UglifyJS? @dvkndn mentions shims for webpack - presumably, we need to tell it to transpile events.js into ES5 when loading it --- isn't this fundamentally at odds with @gaearon statement that 'dependencies' are not transpiled? The offending commit (pointed out by @henri-hulski c6656db352973d6aea24cb1a3c76adf042b25446) is from Jan 20, 2016, and presumably made it into node releases shortly after? That's 10 months (aka an eternity in this line of work ;-)) |
@godmar But as shown above I already had problems with node 5.12.0. |
@henri-hulski Where do you add the |
BTW, @henri-hulski node 5.12.0 was released 2016-06-23 so that's consistent with my statement since the commit is from Jan 2016. Also, why would include NodeSourcePlugin fix the issue; the documentation says that it "adds polyfills for process, console, Buffer and global if used." - but hasn't EventEmitter be moved outside process. in node.js 6.***? Should we file an issue with webpack and ask them what configuration is necessary? Presumably, it's not ok for webpack to assume that a build can use ES6, even if it went straight to the browser and didn't get caught up in UglifyJS, or is this ok to assume now? |
It should go on top level. But it's actually the default. So not sure what happens here. |
@TheLarkInn This diagram is webpack 2, but CRA uses webpack 1 which uses a different resolver impl.
|
Ah sorry I totally forgot cra is webpack 1. Apologize for the confusion. |
@sokra - this may sound blasphemous, but are you sure that webpack 1.13.2 works the way you describe? In particular, in the code, you do what I quoted above The plugins for the directories in 'root' and the plugins for the directories in 'fallback' are simply concatenated (unless modulesDirectories is set, which in CRA it is not). Once this reaches enhance-resolve, all you have is a list of plugins for each directory in root and each directory in fallback, concatenated - how can you look in 'node_modules' after root and before fallback? (Correction to this entry: I had overlooked that by not setting modulesDirectories, CRA is relying on the default setting including 'node_modules', see below) |
I tried it (1.13.3) and it does work. The order in which plugins are added is used. They are called in parallel but the results are used in order. |
@sokra - I see. It's done however iff the default setting for moduleDirectories is not overridden. In other words, it relies on the default setting of modulesDirectories being So if you accept PR #1131 then the search order would be:
is this correct? |
I have a working theory. If webpack attempts to resolve a module name such as I'm basing this on these observations: (1) NodeSourcePlugin (code) calls compiler.resolvers.normal.apply in "after-resolvers"
(2) WebPackOptionsApply (code)
This would explain why placing a shim manually in FWIW, the documentation of NodeSourcePlugin refers to it as providing If my theory is correct, then either the nodePaths patch should be reversed, or amended to include warnings if users' NODE_PATH contains the locations of node's built-in modules. On the other hand, we can't really tell if a user's NODE_PATH setting is intentional or not. It could be that a future version of node.js provides a perfectly usable module 'xyz' in /usr/lib/nodejs and the user wants to include it in their build. Maybe have a separate variable "RESPECT_NODE_PATH" for the use cases where NODE_PATH should be respected, and don't respect it by default. |
How about we intentionally deviate and only respect relative NODE_PATH. That's what our users use it for anyway. And global is always dangerous. |
Or maybe check that the path is inside the project folder? I think it would be less surprising than not allowing absolute paths, what matters is where the files are located, not how that location is represented (absolute vs relative). |
I can imagine people using something like ../shared or equivalent. This is in any case a stopgap solution before we remove NODE_PATH support altogether. |
Apparently this problem only exists when you install Node from source. |
Nope. Not from source but from NodeSource Node.js Binary Distributions. |
Right. But those distributions do include source, don't they? |
Fixed in #1194. |
@gaearon No it's not the source. In Linux libraries in general install themselves under |
Fixed in 0.8.2. https://github.com/facebookincubator/create-react-app/releases/tag/v0.8.2 |
My build now succeeds 👍 |
github is really cool. I filed an issue with nodesource/distributions, which now appears cross-linked here. Maybe we can find out why they have this/where it comes from. Just wanted to add one thing: events.js is also baked into the node executable in Linux. (This is done via its bootstrapping process where they take a snapshot of the heap that subsequent runs load from.) In other words, doing a |
¯\(ツ)/¯Thanks for all your help and for attempting to dig to the very root of the issue too. |
In my case, I was getting unable to minify ./node_modules/EventEmitter/src/index.js:16 and after a lot of research problem was still there. so at the end, I went to babel playground and converted the whole file to es5 and paste there and it worked, don't know why but it worked |
@gaearon asked that I file a separate issue.
How to reproduce: run
create-react-app fail-event-emitter
, add a lineto
src/index.js
and then runnpm run build
, which fails with:react-scripts 0.7.0 is used and node.js 6.9.1 (or 7.0)
The purported cause is that CRA does not transpile "dependencies" into ES5 and then the UglifyJS plugin fails when it encounters ES6 code.
The test case above was derived from a failure in react-bootstrap-tables, which includes a module that in turn references EventEmitter. Others have suggested to provide an alternate EventEmitter implementation in the application path, but it is not clear to me how react-bootstrap-table's dependencies can be made to use this alternate implementation.
The text was updated successfully, but these errors were encountered: