Merge pull request #279 from ampedandwired/feature/hash-names
Support hashes in filenames
This commit is contained in:
commit
37bf50d662
|
|
@ -1,6 +1,10 @@
|
|||
Change History
|
||||
==============
|
||||
|
||||
v2.16.0
|
||||
----
|
||||
* Add support for dynamic filenames like index[hash].html
|
||||
|
||||
v2.15.0
|
||||
----
|
||||
* Add full unit test coverage for the webpack 2 beta version
|
||||
|
|
|
|||
32
index.js
32
index.js
|
|
@ -48,13 +48,15 @@ HtmlWebpackPlugin.prototype.apply = function (compiler) {
|
|||
.catch(function (err) {
|
||||
compilation.errors.push(prettyError(err, compiler.context).toString());
|
||||
return {
|
||||
content: self.options.showErrors ? prettyError(err, compiler.context).toJsonHtml() : 'ERROR'
|
||||
content: self.options.showErrors ? prettyError(err, compiler.context).toJsonHtml() : 'ERROR',
|
||||
outputName: self.options.filename
|
||||
};
|
||||
})
|
||||
.then(function (compilationResult) {
|
||||
// If the compilation change didnt change the cache is valid
|
||||
isCompilationCached = compilationResult.hash && self.childCompilerHash === compilationResult.hash;
|
||||
self.childCompilerHash = compilationResult.hash;
|
||||
self.childCompilationOutputName = compilationResult.outputName;
|
||||
callback();
|
||||
return compilationResult.content;
|
||||
});
|
||||
|
|
@ -107,10 +109,14 @@ HtmlWebpackPlugin.prototype.apply = function (compiler) {
|
|||
// Allow plugins to make changes to the assets before invoking the template
|
||||
// This only makes sense to use if `inject` is `false`
|
||||
.then(function (compilationResult) {
|
||||
return applyPluginsAsyncWaterfall('html-webpack-plugin-before-html-generation', {assets: assets, plugin: self})
|
||||
.then(function () {
|
||||
return compilationResult;
|
||||
});
|
||||
return applyPluginsAsyncWaterfall('html-webpack-plugin-before-html-generation', {
|
||||
assets: assets,
|
||||
outputName: self.childCompilationOutputName,
|
||||
plugin: self
|
||||
})
|
||||
.then(function () {
|
||||
return compilationResult;
|
||||
});
|
||||
})
|
||||
// Execute the template
|
||||
.then(function (compilationResult) {
|
||||
|
|
@ -122,7 +128,7 @@ HtmlWebpackPlugin.prototype.apply = function (compiler) {
|
|||
})
|
||||
// Allow plugins to change the html before assets are injected
|
||||
.then(function (html) {
|
||||
var pluginArgs = {html: html, assets: assets, plugin: self};
|
||||
var pluginArgs = {html: html, assets: assets, plugin: self, outputName: self.childCompilationOutputName};
|
||||
return applyPluginsAsyncWaterfall('html-webpack-plugin-before-html-processing', pluginArgs)
|
||||
.then(function () {
|
||||
return pluginArgs.html;
|
||||
|
|
@ -134,7 +140,7 @@ HtmlWebpackPlugin.prototype.apply = function (compiler) {
|
|||
})
|
||||
// Allow plugins to change the html after assets are injected
|
||||
.then(function (html) {
|
||||
var pluginArgs = {html: html, assets: assets, plugin: self};
|
||||
var pluginArgs = {html: html, assets: assets, plugin: self, outputName: self.childCompilationOutputName};
|
||||
return applyPluginsAsyncWaterfall('html-webpack-plugin-after-html-processing', pluginArgs)
|
||||
.then(function () {
|
||||
return pluginArgs.html;
|
||||
|
|
@ -150,7 +156,7 @@ HtmlWebpackPlugin.prototype.apply = function (compiler) {
|
|||
})
|
||||
.then(function (html) {
|
||||
// Replace the compilation result with the evaluated html code
|
||||
compilation.assets[self.options.filename] = {
|
||||
compilation.assets[self.childCompilationOutputName] = {
|
||||
source: function () {
|
||||
return html;
|
||||
},
|
||||
|
|
@ -162,8 +168,14 @@ HtmlWebpackPlugin.prototype.apply = function (compiler) {
|
|||
.then(function () {
|
||||
// Let other plugins know that we are done:
|
||||
return applyPluginsAsyncWaterfall('html-webpack-plugin-after-emit', {
|
||||
html: compilation.assets[self.options.filename],
|
||||
html: compilation.assets[self.childCompilationOutputName],
|
||||
outputName: self.childCompilationOutputName,
|
||||
plugin: self
|
||||
}).catch(function (err) {
|
||||
console.error(err);
|
||||
return null;
|
||||
}).then(function () {
|
||||
return null;
|
||||
});
|
||||
})
|
||||
// Let webpack continue with it
|
||||
|
|
@ -349,7 +361,7 @@ HtmlWebpackPlugin.prototype.htmlWebpackPluginAssets = function (compilation, chu
|
|||
// If a hard coded public path exists use it
|
||||
? compilation.mainTemplate.getPublicPath({hash: webpackStatsJson.hash})
|
||||
// If no public path was set get a relative url path
|
||||
: path.relative(path.resolve(compilation.options.output.path, path.dirname(self.options.filename)), compilation.options.output.path)
|
||||
: path.relative(path.resolve(compilation.options.output.path, path.dirname(self.childCompilationOutputName)), compilation.options.output.path)
|
||||
.split(path.sep).join('/');
|
||||
|
||||
if (publicPath.length && publicPath.substr(-1, 1) !== '/') {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
'use strict';
|
||||
var Promise = require('bluebird');
|
||||
var _ = require('lodash');
|
||||
var path = require('path');
|
||||
var NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
|
||||
var NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
|
||||
|
|
@ -36,7 +37,8 @@ module.exports.compileTemplate = function compileTemplate (template, context, ou
|
|||
filename: outputFilename,
|
||||
publicPath: compilation.outputOptions.publicPath
|
||||
};
|
||||
var cachedAsset = compilation.assets[outputOptions.filename];
|
||||
// Store the result of the parent compilation before we start the child compilation
|
||||
var assetsBeforeCompilation = _.assign({}, compilation.assets[outputOptions.filename]);
|
||||
// Create an additional child compiler which takes the template
|
||||
// and turns it into an Node.JS html factory.
|
||||
// This allows us to use loaders during the compilation
|
||||
|
|
@ -66,9 +68,17 @@ module.exports.compileTemplate = function compileTemplate (template, context, ou
|
|||
// Compile and return a promise
|
||||
return new Promise(function (resolve, reject) {
|
||||
childCompiler.runAsChild(function (err, entries, childCompilation) {
|
||||
compilation.assets[outputOptions.filename] = cachedAsset;
|
||||
if (cachedAsset === undefined) {
|
||||
delete compilation.assets[outputOptions.filename];
|
||||
// Replace [hash] placeholders in filename
|
||||
var outputName = compilation.mainTemplate.applyPluginsWaterfall('asset-path', outputOptions.filename, {
|
||||
hash: childCompilation.hash,
|
||||
chunk: entries[0]
|
||||
});
|
||||
// Restore the parent compilation to the state like it
|
||||
// was before the child compilation
|
||||
compilation.assets[outputName] = assetsBeforeCompilation[outputName];
|
||||
if (assetsBeforeCompilation[outputName] === undefined) {
|
||||
// If it wasn't there - delete it
|
||||
delete compilation.assets[outputName];
|
||||
}
|
||||
// Resolve / reject the promise
|
||||
if (childCompilation && childCompilation.errors && childCompilation.errors.length) {
|
||||
|
|
@ -82,8 +92,10 @@ module.exports.compileTemplate = function compileTemplate (template, context, ou
|
|||
resolve({
|
||||
// Hash of the template entry point
|
||||
hash: entries[0].hash,
|
||||
// Output name
|
||||
outputName: outputName,
|
||||
// Compiled code
|
||||
content: childCompilation.assets[outputOptions.filename].source()
|
||||
content: childCompilation.assets[outputName].source()
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "html-webpack-plugin",
|
||||
"version": "2.15.0",
|
||||
"version": "2.16.0",
|
||||
"description": "Simplifies creation of HTML files to serve your webpack bundles",
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
|
|
|
|||
|
|
@ -38,6 +38,14 @@ function testHtmlPlugin (webpackConfig, expectedResults, outputFile, done, expec
|
|||
} else {
|
||||
expect(compilationWarnings).toBe('');
|
||||
}
|
||||
if (outputFile instanceof RegExp) {
|
||||
var matches = Object.keys(stats.compilation.assets).filter(function (item) {
|
||||
return outputFile.test(item);
|
||||
});
|
||||
expect(matches.length).toBe(1);
|
||||
outputFile = matches[0];
|
||||
}
|
||||
expect(outputFile.indexOf('[hash]') === -1).toBe(true);
|
||||
var outputFileExists = fs.existsSync(path.join(OUTPUT_DIR, outputFile));
|
||||
expect(outputFileExists).toBe(true);
|
||||
if (!outputFileExists) {
|
||||
|
|
@ -573,6 +581,19 @@ describe('HtmlWebpackPlugin', function () {
|
|||
}, ['<script src="index_bundle.js"'], 'test.html', done);
|
||||
});
|
||||
|
||||
it('will replace [hash] in the filename with the child compilation hash', function (done) {
|
||||
testHtmlPlugin({
|
||||
entry: path.join(__dirname, 'fixtures/index.js'),
|
||||
output: {
|
||||
path: OUTPUT_DIR,
|
||||
filename: 'index_bundle.js'
|
||||
},
|
||||
plugins: [new HtmlWebpackPlugin({
|
||||
filename: 'test-[hash].html'
|
||||
})]
|
||||
}, ['<script src="index_bundle.js"'], /test-\S+\.html$/, done);
|
||||
});
|
||||
|
||||
it('allows you to use an absolute output filename', function (done) {
|
||||
testHtmlPlugin({
|
||||
entry: path.join(__dirname, 'fixtures/index.js'),
|
||||
|
|
|
|||
Loading…
Reference in New Issue