From cadad66359e5e5f3749592de832daabc93f6c440 Mon Sep 17 00:00:00 2001 From: Charles Blaxland Date: Mon, 20 Apr 2015 12:43:46 +1000 Subject: [PATCH] Order chunks to reflect their dependencies --- CHANGES.md | 1 + index.js | 25 ++++++++++++++++++++----- package.json | 3 ++- spec/HtmlWebpackPluginSpec.js | 25 +++++++++++++++++++++++++ spec/fixtures/common.js | 1 + spec/fixtures/index.js | 1 + spec/fixtures/util.js | 1 + 7 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 spec/fixtures/common.js diff --git a/CHANGES.md b/CHANGES.md index 6457dab..19eed1e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,3 +17,4 @@ v1.2.0 details. This new attribute deprecates the old `o.htmlWebpackPlugin.assets` attribute. * The `templateContent` option can now be a function that returns the template string to use * Expose webpack configuration to templates (`o.webpackConfig`) +* Sort chunks to honour dependencies between them (useful for use with CommonsChunkPlugin). diff --git a/index.js b/index.js index 9406a3b..feb9d2e 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ 'use strict'; var fs = require('fs'); var path = require('path'); +var _ = require('lodash'); var tmpl = require('blueimp-tmpl').tmpl; function HtmlWebpackPlugin(options) { @@ -83,28 +84,42 @@ HtmlWebpackPlugin.prototype.htmlWebpackPluginAssets = function(compilation, webp }; var publicPath = compilation.options.output.publicPath || ''; - for (var chunk in webpackStatsJson.assetsByChunkName) { - assets.chunks[chunk] = {}; + var chunks = webpackStatsJson.chunks.sort(function orderEntryLast(a, b) { + if (a.entry !== b.entry) { + return b.entry ? 1 : -1; + } else { + return b.id - a.id; + } + }); + + for (var i = 0; i < chunks.length; i++) { + var chunk = chunks[i]; + var chunkName = chunk.names[0]; + assets.chunks[chunkName] = {}; // Prepend the public path to all chunk files - var chunkFiles = [].concat(webpackStatsJson.assetsByChunkName[chunk]).map(function(chunkFile) { + var chunkFiles = [].concat(chunk.files).map(function(chunkFile) { return publicPath + chunkFile; }); // Webpack outputs an array for each chunk when using sourcemaps // But we need only the entry file var entry = chunkFiles[0]; - assets.chunks[chunk].entry = entry; + assets.chunks[chunkName].entry = entry; assets.js.push(entry); // Gather all css files var css = chunkFiles.filter(function(chunkFile){ return path.extname(chunkFile) === '.css'; }); - assets.chunks[chunk].css = css; + assets.chunks[chunkName].css = css; assets.css = assets.css.concat(css); } + // Duplicate css assets can occur on occasion if more than one chunk + // requires the same css. + assets.css = _.uniq(assets.css); + return assets; }; diff --git a/package.json b/package.json index 233d48d..04ad008 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "webpack": "^1.3.3-beta1" }, "dependencies": { - "blueimp-tmpl": "~2.5.4" + "blueimp-tmpl": "~2.5.4", + "lodash": "~3.6.0" } } diff --git a/spec/HtmlWebpackPluginSpec.js b/spec/HtmlWebpackPluginSpec.js index f5be671..0bea99b 100644 --- a/spec/HtmlWebpackPluginSpec.js +++ b/spec/HtmlWebpackPluginSpec.js @@ -3,6 +3,7 @@ var path = require('path'); var fs = require('fs'); var webpack = require('webpack'); var rm_rf = require('rimraf'); +var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin"); var HtmlWebpackPlugin = require('../index.js'); var OUTPUT_DIR = path.join(__dirname, '../dist'); @@ -299,4 +300,28 @@ describe('HtmlWebpackPlugin', function() { ['Public path is https://cdn.com'], null, done); }); + it('works with commons chunk plugin', function(done) { + testHtmlPlugin({ + debug: true, + verbose: true, + entry: { + util: path.join(__dirname, 'fixtures/util.js'), + index: path.join(__dirname, 'fixtures/index.js') + }, + output: { + path: OUTPUT_DIR, + filename: '[name]_bundle.js' + }, + plugins: [ + new CommonsChunkPlugin({ + name: 'common', + filename: "common_bundle.js", + }), + new HtmlWebpackPlugin() + ] + }, [ + /