The solution is to write a script that parses the .js.map files, since they contain a sources
entry which can be used to discern all files that were included in the chunk.
Here is a small gulp script that will get the job done,
var debugWebpackMapFile = function (file) {
var cleanupRules = {
// executed in order
'/src/client/javascript/node_modules/': '',
'/src/client/javascript/': 'static/'
};
return new Promise(function (resolve, reject) {
var match = /\/([^\/]+).js.map$/.exec(file);
if (match != null) {
var filename = match[1];
console.log("\n " + filename + "\n =======================\n");
var mapjson = JSON.parse(fs.readFileSync(file));
var dependencies = [];
var sourcefiles = [];
_.each(mapjson.sources, function (srcfile) {
srcfile = srcfile.replace('webpack://source-code', '', srcfile);
var match = /^\/node_modules\/([^\/]+)/.exec(srcfile);
if (match == null) {
match = /^(\/src\/.*\.js)(\?.*)?/.exec(srcfile);
if (match != null) {
// project source file
srcfile = match[1];
_.each(cleanupRules, function (to, from) {
srcfile = srcfile.replace(from, to);
});
// the sources are in random order in the map file,
// so we'll need to sort before displaying anything
sourcefiles.push(srcfile);
}
}
else {
// dependency
var pkg = match[1];
if (dependencies.indexOf(pkg) == -1) {
dependencies.push(pkg);
}
}
});
sourcefiles.sort();
_.each(sourcefiles, function (srcfile) {
console.log(" " + srcfile);
});
if (dependencies.length > 0) {
console.log("\n ---- 3rd Party ------------------\n");
dependencies.sort();
_.each(dependencies, function (pkg) {
console.log(" " + pkg);
});
}
}
console.log("\n\n");
resolve();
});
}
gulp.task('js:debug', function (cb) {
var conf = webpackConf.mainjs;
glob(conf.output.path + '/*.map', {}, function (er, files) {
var promises = [];
_.each(files, function (file) {
promises.push(debugWebpackMapFile(file));
});
Promise.all(promises).lastly(cb);
});
});
You'll need to modify the script to meet your own configuration.
Just in case its not obvious, the webpack://source-code
part is due to the devtool settings in webpack output
settings, namely:
devtoolModuleFilenameTemplate: "webpack://source-code/[resource-path]",
devtoolFallbackModuleFilenameTemplate: "webpack://source-code/[resource-path]?[hash]",
The webpack/internal
and node_modules
are from the following normalization script (I don't like webpack's "~" replacement feature).
var normalizeMaps = function (conf, cb) {
glob(conf.output.path + '/*.map', {}, function (er, files) {
var promises = [];
_.each(files, function (file) {
promises.push(replaceInFile(file, [
[ /\/~/g, '/node_modules' ],
[ /\.\//g, ''],
[ /source-code\/\(webpack\)/g, 'source-code/webpack/internal' ]
]));
});
Promise.all(promises).lastly(cb);
});
};