Add append option

This commit is contained in:
Jan Nicklas 2015-03-13 17:09:36 +01:00
parent e631065df8
commit 76d45eda48
3 changed files with 110 additions and 0 deletions

View File

@ -55,6 +55,10 @@ HtmlWebpackPlugin.prototype.emitHtml = function(compilation, htmlTemplateContent
} catch(e) {
compilation.errors.push(new Error('HtmlWebpackPlugin: template error ' + e));
}
// Append/Inject link and script elements into an existing html file
if (this.options.append) {
html = this.appendAssetsToHtml(html, templateParams, this.options.append);
}
compilation.assets[outputFilename] = {
source: function() {
return html;
@ -126,6 +130,51 @@ HtmlWebpackPlugin.prototype.htmlWebpackPluginAssets = function(compilation, webp
return assets;
};
/**
* Inject the assets into the given html string
*/
HtmlWebpackPlugin.prototype.appendAssetsToHtml = function(html, templateParams, chunks) {
var assets = templateParams.htmlWebpackPlugin.files;
// If chunks is set to true append all chunks
if (chunks === true) {
chunks = Object.keys(assets.chunks);
}
// Gather all css and script files
var styles = [];
var scripts = [];
chunks.forEach(function(chunkName) {
styles = styles.concat(assets.chunks[chunkName].css);
scripts.push(assets.chunks[chunkName].entry);
});
// Turn script files into script tags
scripts = scripts.map(function(scriptPath) {
return '<script src="' + scriptPath + '?' + templateParams.hash + '"></script>';
});
// Turn css files into link tags
styles = styles.map(function(stylePath) {
return '<link href="' + stylePath + '?' + templateParams.hash + '" rel="stylesheet">';
});
// Append scripts
html = html.replace(/(<\/body>)/i, function (match, start) {
return scripts.join('') + match;
});
// Append styles
html = html.replace(/(<\/head>)/i, function (match, start) {
return styles.join('') + match;
});
// Append manifest
if (assets.manifest) {
html = html.replace(/(<html.*)(>)/i, function (match, start, end) {
// Don't append a manifest if a manifest was already specified
if (match.test(/\smanifest\s*=/)) {
return match;
}
return start + ' manifest="' + assets.manifest + '?' + templateParams.hash + '"' + end;
});
}
return html;
};
/**
* A helper to support the templates written for html-webpack-plugin <= 1.1.0
*/

View File

@ -85,6 +85,57 @@ describe('HtmlWebpackPlugin', function() {
['<script src="app_bundle.js'], null, done);
});
it('allows you to append the assets to a given html file', function (done) {
testHtmlPlugin({
entry: {
util: path.join(__dirname, 'fixtures/util.js'),
app: path.join(__dirname, 'fixtures/index.js')
},
output: {
path: OUTPUT_DIR,
filename: '[name]_bundle.js'
},
plugins: [new HtmlWebpackPlugin({
append: true,
template: path.join(__dirname, 'fixtures/test.html')
})]
}, ['<script src="util_bundle.js?%hash%"', '<script src="app_bundle.js?%hash%"'], null, done);
});
it('allows you to append the assets to a html string', function (done) {
testHtmlPlugin({
entry: {
util: path.join(__dirname, 'fixtures/util.js'),
app: path.join(__dirname, 'fixtures/index.js')
},
output: {
path: OUTPUT_DIR,
filename: '[name]_bundle.js'
},
plugins: [new HtmlWebpackPlugin({
append: ['util', 'app'],
templateContent: fs.readFileSync(path.join(__dirname, 'fixtures/test.html'), 'utf8')
})]
}, ['<script src="util_bundle.js?%hash%"', '<script src="app_bundle.js?%hash%"'], null, done);
});
it('allows you to append a specified asset to a given html file', function (done) {
testHtmlPlugin({
entry: {
util: path.join(__dirname, 'fixtures/util.js'),
app: path.join(__dirname, 'fixtures/index.js')
},
output: {
path: OUTPUT_DIR,
filename: '[name]_bundle.js'
},
plugins: [new HtmlWebpackPlugin({
append: ['app'],
template: path.join(__dirname, 'fixtures/test.html')
})]
}, ['<script src="app_bundle.js?%hash%"'], null, done);
});
it('allows you to use the deprecated assets object', function (done) {
testHtmlPlugin({
entry: {

10
spec/fixtures/plain.html vendored Normal file
View File

@ -0,0 +1,10 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example Plain file</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
</body>
</html>