Skip to content

Commit ae8233a

Browse files
committedAug 25, 2018
feat: Add support for the [contenthash] placeholder inside htm file names
1 parent cef1502 commit ae8233a

File tree

2 files changed

+28
-5
lines changed

2 files changed

+28
-5
lines changed
 

‎index.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const vm = require('vm');
1414
const fs = require('fs');
1515
const _ = require('lodash');
1616
const path = require('path');
17+
const loaderUtils = require('loader-utils');
1718

1819
const htmlTagObjectToString = require('./lib/html-tags').htmlTagObjectToString;
1920

@@ -238,15 +239,21 @@ class HtmlWebpackPlugin {
238239
return self.options.showErrors ? prettyError(err, compiler.context).toHtml() : 'ERROR';
239240
})
240241
.then(html => {
242+
// Allow to use [contenthash] as placeholder for the html-webpack-plugin name
243+
// From https://github.com/webpack-contrib/extract-text-webpack-plugin/blob/8de6558e33487e7606e7cd7cb2adc2cccafef272/src/index.js#L212-L214
244+
const finalOutputName = self.childCompilationOutputName.replace(/\[(?:(\w+):)?contenthash(?::([a-z]+\d*))?(?::(\d+))?\]/ig, function () {
245+
return loaderUtils.getHashDigest(html, arguments[1], arguments[2], parseInt(arguments[3], 10));
246+
});
241247
// Replace the compilation result with the evaluated html code
242-
compilation.assets[self.childCompilationOutputName] = {
248+
compilation.assets[finalOutputName] = {
243249
source: () => html,
244250
size: () => html.length
245251
};
252+
return finalOutputName;
246253
})
247-
.then(() => getHtmlWebpackPluginHooks(compilation).afterEmit.promise({
254+
.then((finalOutputName) => getHtmlWebpackPluginHooks(compilation).afterEmit.promise({
248255
html: compilation.assets[self.childCompilationOutputName],
249-
outputName: self.childCompilationOutputName,
256+
outputName: finalOutputName,
250257
plugin: self
251258
}).catch(err => {
252259
console.error(err);

‎spec/basic.spec.js

+18-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ function testHtmlPlugin (webpackConfig, expectedResults, outputFile, done, expec
5050
expect(compilationWarnings).toBe('');
5151
}
5252
if (outputFile instanceof RegExp) {
53+
const fileNames = Object.keys(stats.compilation.assets);
5354
const matches = Object.keys(stats.compilation.assets).filter(item => outputFile.test(item));
54-
expect(matches.length).toBe(1);
55+
expect(matches[0] || fileNames).not.toEqual(fileNames);
5556
outputFile = matches[0];
5657
}
5758
expect(outputFile.indexOf('[hash]') === -1).toBe(true);
@@ -629,6 +630,22 @@ describe('HtmlWebpackPlugin', () => {
629630
}, ['<script src="index_bundle.js"'], /test-\S+\.html$/, done);
630631
});
631632

633+
it('will replace [contenthash] in the filename with a content hash of 32 hex characters', done => {
634+
testHtmlPlugin({
635+
mode: 'production',
636+
entry: {
637+
index: path.join(__dirname, 'fixtures/index.js')
638+
},
639+
output: {
640+
path: OUTPUT_DIR,
641+
filename: '[name]_bundle.js'
642+
},
643+
plugins: [
644+
new HtmlWebpackPlugin({filename: 'index.[contenthash].html'})
645+
]
646+
}, [], /index\.[a-f0-9]{32}\.html/, done);
647+
});
648+
632649
it('allows you to use an absolute output filename', done => {
633650
testHtmlPlugin({
634651
mode: 'production',
@@ -1264,7 +1281,6 @@ describe('HtmlWebpackPlugin', () => {
12641281
}, false,
12651282
shouldExpectWarnings);
12661283
});
1267-
12681284
it('works with commons chunk plugin', done => {
12691285
testHtmlPlugin({
12701286
mode: 'production',

0 commit comments

Comments
 (0)
Please sign in to comment.