Uh oh!
There was an error while loading. Please reload this page.
Add an explicit root to webpack.resolve so it searchs there first - #1131
Add an explicit root to webpack.resolve so it searchs there first#1131jimmyhmiller wants to merge 2 commits into
Conversation
jimmyhmiller
commented
Dec 2, 2016
I might have more time to work on this tomorrow. If not I for sure will Sunday. But anyone can feel free take it if that isn't soon enough. |
godmar
commented
Dec 2, 2016
Two suggestions:
|
I've added a comment to explain why this change was made and point to #1023. I'm not sure about changing moduleDirectories. Unless we are going to set it to some value other than the default, it doesn't make sense to me to explicitly set it. I've tested the scenario listed in #1023 and the problem seems fixed. I've also tested to make sure local files don't shadow node_modules (npm install redux and have a file named redux.js). I've tested that you can still use NODE_PATHS to allow absolute imports. Everything seems to check out. |
godmar
commented
Dec 4, 2016
The reason I would explicitly set modulesDirectory is not only because the lack of the setting confused me until I discovered the default setting (which is hidden in the fine print of the webpack documentation), but because others were confused by this as well. For instance, the author of the first version of PR #476 was apparently confused as well about the role of root vs. fallback, leading to a patch that then had to be corrected. Perhaps for the same reason. ... I just noticed that was you. So, I'm not saying you were confused, but I certainly was. To debug the issue in #1023, I grepped for root and fallback and found the plugins I posted in the other thread, here. I briefly looked at modulesDirectories, but the plug-in code seemed to assume a non-empty setting, whereas we didn't have one. The default settings are applied elsewhere. Had I seen the setting, I would have found the problem much earlier because it would have provided an explanation for why installing events locally worked. If it explicitly specified root + modulesDirectories + fallback, the full resolution order would be clear and those issues might be easier to debug in the future. Interestingly, that's what they appear to be doing for webpack 2.0. But, with the speed everything moves, they'll probably have upgraded to wp 2.0 before this PR lands. (Just kidding.) |
gaearon
commented
Dec 5, 2016
This directly contradicts the comment right below about how |
gaearon
left a comment
There was a problem hiding this comment.
It's not clear to me how this works. If the comment right below is wrong let's fix it. Otherwise this is inconsistent.
jimmyhmiller
commented
Dec 5, 2016
@gaearon Not sure I see the contradict, but I'm sure it could be more clear.
So, here's how the First webpack checked root for This fixes that problem by specifying Hopefully that made sense. Happy to change the comment in any way to make that clear. |
godmar
commented
Dec 5, 2016
@jimmyhmiller almost correct. It didn't "check If we listed them, this would be more clear. What's wrong about your comment is: Without this, if NODE_PATH has the same module, webpack will use it before the dependency specified in our node modules. where 'this' refers to root. It's wrong because without a root, webpack might still not use NODE_PATH if the module exists in |
gaearon
commented
Dec 5, 2016
Apologies, I misunderstood the change. And if we listed those three settings together and wrote a single block describing the order webpack uses and why we picked those particular settings for each of the three keys. |
jimmyhmiller
commented
Dec 5, 2016
@godmar You seem to understand this a bit better than me. If you'd be willing to write up a comment on it, I'd be grateful. If not, I can certainly take a stab at it. |
How about: The paragraph ( |
gaearon
commented
Dec 6, 2016
Would this |
I don't understand what is the directory structure in which it would matter that How come the package exists in absolute In other words: why does the regular resolution mechanism via |
gaearon
commented
Dec 6, 2016
Understanding this is my only blocker to getting this merged. |
godmar
commented
Dec 6, 2016
You asked: Why doesn't it find the module in My understanding is that the dependency arose at the top-level (say in src/index.js), so looking in This is different, say, from dependencies that arose from packages within Let @sokra clarify. |
gaearon
commented
Dec 6, 2016
This is the part I don't understand. If things required by |
godmar
commented
Dec 6, 2016
Agreed, I don't understand this either. I suspected there was some something undocumented (?) in the resolution chain after root, modulesDirectories, and fallback. |
jimmyhmiller
commented
Dec 6, 2016
On my mac, the module resolves to myapp/node_modules/events/events.js. Does that file exist for you on linux @godmar? |
henri-hulski
commented
Dec 6, 2016
This is also true at least for node 5 and 6 so better leave it out. |
@jimmyhmiller 'event' can resolve to On my Linux box, I don't have that file in the CRA default configuration. In fact, doing a manual 'npm install events -S' put it there, and that was a work-around whose working we explained by the fact that the default setting of modulesDirectories included So... is it working on Macs because somehow there npm installs the browser shims in |
gaearon
commented
Dec 6, 2016
Does this mean that the fix here doesn't help unless one also installs |
gaearon
commented
Dec 6, 2016
Also, can the underlying problem still be reliably reproduced with 0.8.x? |
godmar
commented
Dec 6, 2016
Does this mean that the fix here doesn't help unless one also installs events (or similar shims) explicitly in that folder? No. This proposed patch does not require installing events at the top-level. |
gaearon
commented
Dec 6, 2016
One thing that worries me about this fix is: what happens if user depends on something that We could also hardcode two roots (app's modules, then own modules) but it feels like we have no idea what's going on. The better question to answer is how what imports these modules and why it can't find them by traversing parent directories, and instead goes to the fallback. |
jimmyhmiller
commented
Dec 6, 2016
From the documentation, The reason this has different behavior on linux vs mac is because npm seems to resolve where to put the |
godmar
commented
Dec 6, 2016
I think the Macintosh people need to answer the question why it works for them; in particular, if it turns out that npm on their machines installs all packages upon which node-libs-browser depends in Another option, of course, would be: (or |
jimmyhmiller
commented
Dec 6, 2016
I pushed a repo with my node_modules for the beginning create-react-app project. Just so we can have a comparison of mac vs linux. |
henri-hulski
commented
Dec 6, 2016
@jimmyhmiller |
jimmyhmiller
commented
Dec 6, 2016
It is a clean install. If by this version you mean master, yes I can reproduce it with master. Happy to try any configuration people might want to see. |
henri-hulski
commented
Dec 6, 2016
0.8.1 is the version in package.json |
jimmyhmiller
commented
Dec 6, 2016
@henri-hulski Sorry I'm probably being dense. You are right that it is version 0.8.1 in the package.json. That seems to be the latest version. That being said, this repo was not created from master, but from the create-react-app installed globally. Do you want me to run this from master? Do I need to update? (Sorry this PR is getting full of comments) |
henri-hulski
commented
Dec 6, 2016
@jimmyhmiller The original issue was with version 0.7 and @gaearon asked
So I thought maybe you can answer this question. |
godmar
commented
Dec 6, 2016
Linux (with NODE_PATH=/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript), node 6.9.1, npm 4.0.3, react-scripts 0.8.1. 'events' is present in myapp/node_modules/events and so still fails with: The correct resolution would be None of the proposed alternatives in this PR (setting root + modulesDirectory + fallback, or as I suggested setting only fallback to ownNodeModules + nodePaths) fixes the issue. This is not too surprising as the directory ownNodeModules ( Yet, We need a test that actually uses the referenced package. |
henri-hulski
commented
Dec 6, 2016
@godmar So when you remove |
godmar
commented
Dec 6, 2016
No, when I unset NODE_PATH (which is what |
gaearon
commented
Dec 6, 2016
Can you create two bundles, one with NODE_PATH unset and one normal, and post them so we can compare output byte by byte? |
godmar
commented
Dec 6, 2016
Who, me? If NODE_PATH is set, I don't get a bundle if I import timers. |
gaearon
commented
Dec 6, 2016
Oh right. I think this is the most confusing issue I have encountered for a long time. I'll try to reproduce it on some Linux machine tomorrow. |
gaearon
commented
Dec 6, 2016
Could it be that NODE_PATH matters not because we use it as fallback but because Webpack itself happens to resolve some module during compilation. And uses |
gaearon
commented
Dec 7, 2016
Thank you very much for your help investigating this. |
godmar
commented
Dec 7, 2016
you're welcome. |
This still needs (a lot) more work before it could be merged, but seems like a promising solution to #1023.