var ConcatSource = require('webpack/lib/ConcatSource'); var loaderUtils = require('loader-utils'); module.exports = CombineChunksPlugin; // opts.filename = 'vendor.[contenthash].js' function CombineChunksPlugin(opts) { if (opts) { this.filename = opts.filename ? opts.filename : 'vendor.bundle.js'; this.prelude = opts.prelude; } } CombineChunksPlugin.prototype.apply = function(compiler) { var filename = this.filename; var prelude = this.prelude; compiler.plugin('compilation', function(compilation) { // put chunks in correct order // prelude first - which will contain common chunk and webpackJsonp defn compilation.plugin('optimize-chunk-order', function(chunks) { chunks.sort(function(a, b) { if (a.name === prelude) return -1; if (b.name === prelude) return 1; return 0; }); }); // add our asset into compilation compilation.plugin('optimize-chunk-assets', function(chunks, callback) { var vendorSource = new ConcatSource(''); chunks.forEach(function(chunk) { chunk.files.forEach(function(file) { vendorSource.add(compilation.assets[file]); vendorSource.add('\n'); }); }); filename = filename.replace(/\[(?:(\w+):)?contenthash(?::([a-z]+\d*))?(?::(\d+))?\]/ig, function() { return loaderUtils.getHashDigest(vendorSource.source(), arguments[1], arguments[2], parseInt(arguments[3], 10)); }); compilation.assets[filename] = vendorSource; callback(); }); }); // now we can clean up other chunks that we don't require after the compilation is over // note that we don't iterate over compilation.assets // we do this just before emit giving chance for other plugins // to add its last file as the compilation results to preserve state compiler.plugin('after-compile', function(compilation, callback) { compilation.chunks.forEach(function(chunk) { chunk.files.forEach(function(file) { delete compilation.assets[file]; }); }); callback(); }); };