Robert Robert - 1 month ago 9
Javascript Question

Why is webpack trying to parse every file in my dependency's path?

I have a large project that I've been refactoring to use webpack and ES6 modules. Many of my dependencies are using commonJS or AMD modules, so I'm requiring them the old way.

For example,

const Pikaday = require("pikaday");


Unfortunately, when I now run

webpack --progress


it looks like webpack is trying to parse every single file in that path. I get several warnings that look like, for example:

Module parse failed: /path/to/node_modules/pikaday/index.html


Eventually, I get the following error:

ERROR in ./~/pikaday/tests/methods.js
Module not found: Error: Cannot resolve module 'expect.js' in
/Users/myuser/web/myproject/node_modules/pikaday/tests


I'm getting an error from a tests directory in this dependency, which I obviously don't care about parsing for my bundle. Why is webpack trying to parse every file in that path, and how do I correct this behavior?




For clarity, I'll post the important parts of my webpack.config.js file here.

var webpack = require("webpack");
var path = require("path");

module.exports = {
entry : {
main : './public/src/Main/main.js',
},
output : {
path : './public/build',
filename : '[name].bundle.js'
},
module : {
loaders : [
{
test : /\.json$/,
loader : 'json'
},
{
test : /\.js$/,
loader : "babel?presets[]=es2015"
},
{
test : /\.css$/,
loaders : [
'style',
'css'
]
},
{
test: /\.scss$/,
loaders: ["style", "css", "sass"]
},
{
test : /\.(svg|jpg|png|jpeg)$/,
loader : 'url'
},
{
test : /vendor\/.+\.(jsx|js)$/,
loader : 'imports?jQuery=jquery,$=jquery,this=>window'
}
]
},
"plugins" : [
new webpack.ProvidePlugin({
$ : "jquery",
jQuery : "jquery",
"window.jQuery" : "jquery"
}),
new webpack.ProvidePlugin({
$clamp : "clamp-js"
}),
new webpack.ProvidePlugin({

})
]
};

Answer

When processing modules, Webpack analyses all of the dependencies reachable from your own code, traversing through everything. It will attempt to process both AMD or CommonJS style code.

In this case, the module you are loading does not appear to use a format of loading dependencies what Webpack can analyse properly. When the code from here:

var id = 'moment';
try { moment = req(id); } catch (e) {}

runs, Webpack is not smart enough to see that req(id) is actually req('moment'). Because it has no way of knowing what id is, it will consider req(id) to possibly be loading any file inside the Pikaday module, which as you're seeing, includes the tests folder, and an index.html file, both of which are causing issues for you.

In this case you are lucky because while the AMD section of the module is not parsable, this module also includes a CommonJS prefix here, which is parsable by Webpack. Because of that, you should be able to follow instructions from Is there a way to disable AMDPlugin? which will make Webpack stop processing AMD modules, and thus use the CommonJS section of the code.

Keep in mind, if you actually need to depend on any AMD modules, this will break those, but most things are CommonJS these days anyway.

Either way, it would definitely be good to file a bug on the Pikaday module, since this should be a trivial fix in the module itself.

Comments