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

Set resolve modulesDirectories so module resolves default to Gatsby #299

Merged
merged 1 commit into from
May 29, 2016

Conversation

KyleAMathews
Copy link
Contributor

This was the previous behavior but
a387663
moved our resolve.modulesDirectories config to resolve.root which while
speeding up resolving (and bringing us in line with Webpack's suggested
setup https://webpack.github.io/docs/resolving.html) did break certain
important use cases.

I discovered this recently when my Gatsby site for React Headroom broke.
I rebuilt the react-headroom in Gatsby using 0.11.0. After making some
changes, I rebuilt it with 0.11.1. A user then pointed out that the site
was now broken
(KyleAMathews/react-headroom#82).

After investigating, the problem turned out that two copies of React
were being loaded. One from Gatsby and another from React Headroom. The
Gatsby site is in a subdirectory of the React Headroom and imported the
Headroom component from its src directory (i.e. import Headroom from '../../src/index.js'). This component in turn imported React.

The default Webpack module resolution algorithm is similar to the
node.js resolving process and looks for the nearest node_modules
directory. This is generally what we want but causes trouble when both
Gatsby and another node_modules directory provide the same module.

So to fix this, this commit makes Webpack default to looking inside the
Gatsby site's node_modules directory and only thereafter looks in the
node_modules relative to the module being resolved.

So for the React Headroom component, React is now being correctly
resolved from the Gatsby site preventing the "two copies of React"
problem but react-addons-pure-render-mixin, a direct dependency of React
Headroom that's not included in Gatsby, is resolved to the Headroom
node_modules directory.

This was the previous behavior but
a387663
moved our resolve.modulesDirectories config to resolve.root which while
speeding up resolving (and bringing us in line with Webpack's suggested
setup https://webpack.github.io/docs/resolving.html) did break certain
important use cases.

I discovered this recently when my Gatsby site for React Headroom broke.
I rebuilt the react-headroom in Gatsby using 0.11.0. After making some
changes, I rebuilt it with 0.11.1. A user then pointed out that the site
was now broken
(KyleAMathews/react-headroom#82).

After investigating, the problem turned out that two copies of React
were being loaded. One from Gatsby and another from React Headroom. The
Gatsby site is in a subdirectory of the React Headroom and imported the
Headroom component from its src directory (i.e. `import Headroom from
'../../src/index.js'`). This component in turn imported React.

The default Webpack module resolution algorithm is similar to the
node.js resolving process and looks for the nearest node_modules
directory. This is generally what we want but causes trouble when both
Gatsby and another node_modules directory provide the same module.

So to fix this, this commit makes Webpack default to looking inside the
Gatsby site's node_modules directory and only thereafter looks in the
node_modules relative to the module being resolved.

So for the React Headroom component, React is now being correctly
resolved from the Gatsby site preventing the "two copies of React"
problem but react-addons-pure-render-mixin, a direct dependency of React
Headroom that's not included in Gatsby, is resolved to the Headroom
node_modules directory.
@KyleAMathews
Copy link
Contributor Author

/cc @benstepp

@benstepp
Copy link
Contributor

I just cloned the react-headroom repo and this also works and seems to save ~0.5s over modulesDirectories.

      fallback: `${directory}/node_modules`,

@KyleAMathews
Copy link
Contributor Author

KyleAMathews commented May 28, 2016

Yes but that's not what we want. We need every module which imports React to use the same version of React and for that to happen, the modulesDirectories should consistently pull from Gatsby's node_modules. Using fallback causes the same you have multiple copies of React loaded (details: https://fb.me/react-refs-must-have-owner). error in the console (which breaks the site's JS)

@benstepp
Copy link
Contributor

I don't get a double React issue when I npm install and build the website, instead I get, which is why I suggested fallback instead of modulesDirectories.

Module not found: Error: Cannot resolve module 'react' in /Users/ben/Code/react-headroom/src
resolve module react in /Users/ben/Code/react-headroom/src
  looking for modules in /Users/ben/Code/react-headroom/website

I found with npm install react for a /react-headroom/node_modules/react the behavior is as you described with the double React being pulled. Sounds good to change back to modulesDirectories then.

It would be nice if webpack obeyed the resolve.root and always started resolving from the given root.

@KyleAMathews
Copy link
Contributor Author

Ah right, I did remove React as a devDependency from react-headroom yesterday.

Yeah, I agree that Webpack not using resolve.root as the start for looking for moduleDirectories is odd.

Thanks for the review!

@KyleAMathews KyleAMathews merged commit 4fd7aac into master May 29, 2016
@0x80 0x80 deleted the fix-require-outside-gatsby branch April 19, 2017 20:23
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

Successfully merging this pull request may close these issues.

2 participants