-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
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
Add an explicit root to webpack.resolve so it searchs there first #1131
Conversation
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. |
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. |
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.) |
This directly contradicts the comment right below about how |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear to me how this works. If the comment right below is wrong let's fix it. Otherwise this is inconsistent.
@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. |
@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 |
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please specify explicit modulesDirectories
, consolidate three settings and unify their explanations into a single comment.
@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 ( |
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 |
Understanding this is my only blocker to getting this merged. |
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. |
This is the part I don't understand. If things required by |
Agreed, I don't understand this either. I suspected there was some something undocumented (?) in the resolution chain after root, modulesDirectories, and fallback. |
On my mac, the module resolves to myapp/node_modules/events/events.js. Does that file exist for you on linux @godmar? |
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 |
Does this mean that the fix here doesn't help unless one also installs |
Also, can the underlying problem still be reliably reproduced with 0.8.x? |
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. |
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. |
From the documentation, The reason this has different behavior on linux vs mac is because npm seems to resolve where to put the |
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 |
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. https://github.com/jimmyhmiller/debug-create-react-app-deps |
@jimmyhmiller |
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. |
0.8.1 is the version in package.json |
@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) |
@jimmyhmiller The original issue was with version 0.7 and @gaearon asked
So I thought maybe you can answer this question. |
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. |
@godmar So when you remove |
No, when I unset NODE_PATH (which is what |
Can you create two bundles, one with NODE_PATH unset and one normal, and post them so we can compare output byte by byte? |
Who, me? If NODE_PATH is set, I don't get a bundle if I import timers. |
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. |
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 |
Thank you very much for your help investigating this. |
you're welcome. |
This still needs (a lot) more work before it could be merged, but seems like a promising solution to #1023.