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

Webpack resolve support #17

Merged
merged 13 commits into from
Mar 8, 2016
Merged

Webpack resolve support #17

merged 13 commits into from
Mar 8, 2016

Conversation

ericclemmons
Copy link
Member

resolve: {
  alias: {
    'react': 'react-lite',
    'react-dom': 'react-lite',
  },
  ...
},

I have resolve.alias field in my webpack.
It should install react-lite instead of react + react-dom.
Is this gonna be supported? xP

@ericclemmons ericclemmons added this to the 2.1.0 milestone Jan 25, 2016
@ericclemmons
Copy link
Member

Yep! I use this feature too, but for other reasons:

https://medium.com/@ericclemmons/dogfooding-your-open-source-projects-9e6dc1e7d1c8#.1db8zz6bm

I'm afraid this will require hand-supporting the resolve object :(

Thanks for pointing me to:

https://github.com/Lucifier129/react-lite

@ericclemmons ericclemmons self-assigned this Jan 31, 2016
@ericclemmons ericclemmons changed the title resolve.alias support Webpack resolve support Jan 31, 2016
@ericclemmons
Copy link
Member

  • resolve.root support.
  • resolve.alias support.

@ericclemmons
Copy link
Member

I began work on this tonight, but will require more effort & largely repeating how Webpack already works:

https://github.com/webpack/enhanced-resolve

More stuff to do:

  • Split apart each test's prototype to make it easier to understand.

@ericclemmons
Copy link
Member

@ericclemmons ericclemmons changed the title Webpack resolve support [WIP] Webpack resolve support Feb 1, 2016
@dlmr
Copy link

dlmr commented Feb 1, 2016

I have looked a bit into this and made a working prototype that manages things like:

  • resolve.modulesDirectories
  • resolve.root
  • resolve.fallback
  • resolveLoader.modulesDirectories
  • resolveLoader.root
  • resolveLoader.fallback

The problem I have is that the current logic wants to check if the dependency is in the package.json and install it if it's not. This can be solved easily however then we might get false positives from transitive dependencies in npm3 and I'm unsure how to manage this in a good way.

If you want @ericclemmons I can look more into this and create a separate PR for this or maybe you want to manage this yourself.

@ericclemmons
Copy link
Member

@dlmr Sure, I'd like to see the PR! I'm trying to leverage as much of webpack's existing resolution logic as possible without re-implementing each option.

@dlmr
Copy link

dlmr commented Feb 5, 2016

An idea is to use https://www.npmjs.com/package/resolve instead of the normal require.resolve at https://github.com/ericclemmons/npm-install-webpack-plugin/blob/master/src/installer.js#L53 that uses the paths that has been given to Webpack resolve and resolveLoader. This might not however manage alias so something more is needed here.

I will look into this more and see if I can create a working PR that covers all the different cases.

@ericclemmons
Copy link
Member

Regarding checking package.json, that seemed to be the best way to know if the project itself has registered the dependency.

When this was a Webpack loader, I just did a require.resolve check, but sub-dependencies (e.g. lodash or something common) would end up flattened in node_modules so you couldn't be sure.

@dlmr
Copy link

dlmr commented Feb 5, 2016

The problem is that if we are checking package.json for installed dependencies and we have configured Webpack to resolve to a local directory using for instance resolve.fallback we will try to install it even though we actually managed to resolve it.

I guess the logical thing to do here is to only match resolved dependencies against package.json if they are resolved to the projects node_modules directory and not a directory which has been configured using Webpack.

@bebraw
Copy link

bebraw commented Feb 6, 2016

I guess the logical thing to do here is to only match resolved dependencies against package.json if they are resolved to the projects node_modules directory and not a directory which has been configured using Webpack.

That sounds sane behavior to me. I guess you should try to install only if this resolution process fails in order to follow Webpack semantics. This might not be the correct thing to do always (maybe the user forgot to copy something?), but at least it's logical.

@ericclemmons
Copy link
Member

I almost got this! The only problem I'm having is that, on the client-side builds, the dependencies install but the modules still aren't emitted in the bundle, unless you stop & restart the process:

Here you can see the server installs dependencies & starts correctly...

  npm start

> webpack --config webpack.config.server.babel.js --watch
Installing `babel-loader`...
Installing `express`...
Installing `webpack-dev-middleware`...
Installing `webpack-hot-middleware`...

Hash: 760d490bcc9ee593ad85
Version: webpack 1.12.11
Time: 17566ms
   Asset     Size  Chunks             Chunk Names
server.js  6.28 kB       0  [emitted]  server
   + 9 hidden modules
Listening on http://localhost:3000/

But then, as the client build starts, the first level of dependencies are installed and then the build fails:

Installing `react-lite`...
Installing `style-loader`...
Installing `css-loader`...
Installing `bootswatch`...

webpack built 3cc67e9e55c668174298 in 23903ms
Hash: 3cc67e9e55c668174298
Version: webpack 1.12.11
Time: 23903ms
   Asset    Size  Chunks             Chunk Names
client.js  141 kB       0  [emitted]  client

ERROR in ./src/client.js
Module not found: Error: Cannot resolve module 'react-lite' in /Users/Eric/Projects/ericclemmons/npm-install-webpack-plugin/example/src
@ ./src/client.js 3:13-29

ERROR in ./src/client.js
Module not found: Error: Cannot resolve module 'react-lite' in /Users/Eric/Projects/ericclemmons/npm-install-webpack-plugin/example/lib/App
@ ./src/client.js 7:16-36

ERROR in ./lib/App/index.js
Module not found: Error: Cannot resolve module 'react-lite' in /Users/Eric/Projects/ericclemmons/npm-install-webpack-plugin/example/node_modules/redbox-react/lib
@ ./lib/App/index.js 15:14-30

ERROR in ./~/redbox-react/lib/index.js
Module not found: Error: Cannot resolve module 'react-lite' in /Users/Eric/Projects/ericclemmons/npm-install-webpack-plugin/example/node_modules/redbox-react/lib
@ ./~/redbox-react/lib/index.js 13:13-29

ERROR in ./~/css-loader?{"localIdentName":"[name]-[local]--[hash:base64:5]"}!./lib/App/App.css
@ ./~/css-loader?{"localIdentName":"[name]-[local]--[hash:base64:5]"}!./lib/App/App.css 3:10-151
Module not found: Error: Cannot resolve module 'bootswatch/lumen/bootstrap.css' in /Users/Eric/Projects/ericclemmons/npm-install-webpack-plugin/example/lib/App
^C

However, if you start the process all over again:

  npm start

> webpack --config webpack.config.server.babel.js --watch

Hash: 760d490bcc9ee593ad85
Version: webpack 1.12.11
Time: 321ms
   Asset     Size  Chunks             Chunk Names
server.js  6.28 kB       0  [emitted]  server
   + 9 hidden modules
Listening on http://localhost:3000/

Installing `file-loader`...
Installing `url-loader`...

webpack built d2929b4e576906a4078c in 12198ms
^C

Everything works!

So, it seems like by leveraging Webpack's internal resolve function, the failure is cached &, even though it's installed, it doesn't work.

@ericclemmons
Copy link
Member

@bebraw See the above message.

I'm leveraging compiler.resolvers.normal.resolve to perform module resolution (so that alias and root are handled automatically), but this causes an issue with modules not being re-resolved on the client-side build.

(I'm assuming there's some sort of race condition?)

I just found out that compiler.inputFileSystem.purge() does a decent job of refreshing builds, as only a re-save is necessary to find the newly-installed modules.

@bebraw
Copy link

bebraw commented Feb 29, 2016

@ericclemmons I think @sokra might be able to help you the best here. Let's hope we manage to summon him. 😉

@ericclemmons
Copy link
Member

In that case, bullet points for @sokra!

  • Currently using Webpack v1.12.14.
  • This plugin attempts to trigger the normal & loader resolvers to install dependencies (particularly those that are specified as resolve.alias or in resolve.root) before they actually are fetched and potentially fail.
  • The issue is that, seemingly for the client-side build only, some of the newly installed dependencies aren't resolvable after installation. (See the output above from the /example folder)

I'll probably get the tests passing again & tag this in v3, because this is a potentially breaking change in behavior.

@ericclemmons ericclemmons modified the milestones: 3.0.0, 2.1.0 Feb 29, 2016
@ericclemmons
Copy link
Member

Yea, I like this enough that I'm gonna tag & release it anyway. I hope someone can help solve that weird nesting issue, but I can always just be like, "Uhhh...try saving again!"

@ericclemmons ericclemmons changed the title [WIP] Webpack resolve support Webpack resolve support Mar 8, 2016
ericclemmons added a commit that referenced this pull request Mar 8, 2016
@ericclemmons ericclemmons merged commit 88d447d into master Mar 8, 2016
@ericclemmons
Copy link
Member

v3.0.0 is out!

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

Successfully merging this pull request may close these issues.

3 participants