bower-webpack-plugin
bower-webpack-plugin copied to clipboard
Support for Webpack 2 ?
throw a exception in webpack 2.2.1
TypeError: Cannot read property 'plugin' of null
at BowerWebpackPlugin.apply (/Users/dfzq/fastman/fastman-application/node_modules/bower-webpack-plugin/lib/bower-plugin.js:70:30)
at Compiler.apply (/Users/dfzq/fastman/fastman-application/node_modules/tapable/lib/Tapable.js:306:16)
at webpack (/Users/dfzq/fastman/fastman-application/node_modules/webpack/lib/webpack.js:32:19)
at Object.
I've create a "monster" on my branch and I'm not proud of it, but it somehow "works" with webpack2 - I'm able to compile quite big project with it. It is nowhere near to a pull request. I'm not able to work on it right now so I'm going to shortly describe what I've discovered during my dark magic operation and maybe this will help someone else to create the real solution. I've to also admit that my knowledge of webpack internals is really limited so many of my conclusions can be just wrong. Here it goes (to simplify I'm using standard paths and filenames in this description):
-
This plugin works on two layers of webpack processing:
- during resolution phase - it resolves
request('example-library')
into manifestFile for examplebower_components/example-library/bower.json
, - during compilation phase - it recognizes it's previous resolution (thanks to it's internal cache) and loads all sources (because in
bower.json
in themain
attribute you can have an array of files) compiled into "artificial" javascript module,
- during resolution phase - it resolves
-
In new version of webpack these steps had been separated
- we have
resolve.plugins
option - in such a case pluginapply
method has access toResolver
instance - and main
plugins
option - in this caseapply
receivesComipler
as an argument
- we have
-
I'm not entirely sure, but it seems, that it is not straightforward to mix these two steps in single plugin any more (but I can be wrong and maybe it is possible from the main
plugin
level to register someresolve
plugins), -
On my branch I've just used the same instance in these two places and moved "resolution cache" to the instance level
-
And the last conclusion: It is real fun and pleasure to hack on this plugin because it has really nice test suite (code on my branch passes 50% of tests ;-) and you can check your progress all the time !!!
So here is my limited understanding of this plugin workflow after two hours of hacking on it and here are my modifications - many changes are hacks which are related to the test suite configuration. My branch misses multiple options (it doesn't read global resolve.modules
, it ignores exclude
packages, it doesn't handle custom manifest naming etc.), but the main processing works.
There is no need for a plugin anymore with webpack 2 --
https://github.com/webpack/webpack/issues/2324#issuecomment-209261160
{
modules: [path.resolve(__dirname, "app"), "node_modules"]
// (was split into `root`, `modulesDirectories` and `fallback` in the old options)
// In which folders the resolver look for modules
// relative paths are looked up in every parent folder (like node_modules)
// absolute paths are looked up directly
// the order is respected
descriptionFiles: ["package.json", "bower.json"],
// These JSON files are read in directories
mainFields: ["main", "browser"],
// These fields in the description files are looked up when trying to resolve the package directory
mainFiles: ["index"]
// These files are tried when trying to resolve a directory
aliasFields: ["browser"],
// These fields in the description files offer aliasing in this package
// The content of these fields is an object where requests to a key are mapped to the corresponding value
extensions: [".js", ".json"],
// These extensions are tried when resolving a file
enforceExtension: false,
// If false it will also try to use no extension from above
moduleExtensions: ["-loader"],
// These extensions are tried when resolving a module
enforceModuleExtension: false,
// If false it's also try to use no module extension from above
alias: {
jquery: path.resolve(__dirname, "vendor/jquery-2.0.0.js")
}
// These aliasing is used when trying to resolve a module
}
Does it support multiple main
files - I mean the situation when main
field in bower.json
is an array of values?