Merge pull request #345 from ampedandwired/feature/alter-tags
Add 'html-webpack-plugin-alter-asset-tags'
This commit is contained in:
commit
fa25bd7718
|
|
@ -1,6 +1,10 @@
|
|||
Change History
|
||||
==============
|
||||
|
||||
v2.21.0
|
||||
----
|
||||
* Add `html-webpack-plugin-alter-asset-tags` event to allow plugins to adjust the script/link tags
|
||||
|
||||
v2.20.0
|
||||
----
|
||||
* Exclude chunks works now even if combined with dependency sort
|
||||
|
|
|
|||
|
|
@ -248,6 +248,7 @@ Async:
|
|||
|
||||
* `html-webpack-plugin-before-html-generation`
|
||||
* `html-webpack-plugin-before-html-processing`
|
||||
* `html-webpack-plugin-alter-asset-tags`
|
||||
* `html-webpack-plugin-after-html-processing`
|
||||
* `html-webpack-plugin-after-emit`
|
||||
|
||||
|
|
|
|||
75
index.js
75
index.js
|
|
@ -143,8 +143,15 @@ HtmlWebpackPlugin.prototype.apply = function (compiler) {
|
|||
});
|
||||
})
|
||||
.then(function (html) {
|
||||
// Add the stylesheets, scripts and so on to the resulting html
|
||||
return self.postProcessHtml(html, assets);
|
||||
// Prepare script and link tags
|
||||
var assetTags = self.generateAssetTags(assets);
|
||||
var pluginArgs = {head: assetTags.head, body: assetTags.body, plugin: self, chunks: chunks, outputName: self.childCompilationOutputName};
|
||||
// Allow plugins to change the assetTag definitions
|
||||
return applyPluginsAsyncWaterfall('html-webpack-plugin-alter-asset-tags', pluginArgs)
|
||||
.then(function () {
|
||||
// Add the stylesheets, scripts and so on to the resulting html
|
||||
return self.postProcessHtml(html, assets, { body: pluginArgs.body, head: pluginArgs.head });
|
||||
});
|
||||
})
|
||||
// Allow plugins to change the html after assets are injected
|
||||
.then(function (html) {
|
||||
|
|
@ -259,7 +266,7 @@ HtmlWebpackPlugin.prototype.executeTemplate = function (templateFunction, chunks
|
|||
*
|
||||
* Returns a promise
|
||||
*/
|
||||
HtmlWebpackPlugin.prototype.postProcessHtml = function (html, assets) {
|
||||
HtmlWebpackPlugin.prototype.postProcessHtml = function (html, assets, assetTags) {
|
||||
var self = this;
|
||||
if (typeof html !== 'string') {
|
||||
return Promise.reject('Expected html to be a string but got ' + JSON.stringify(html));
|
||||
|
|
@ -268,7 +275,7 @@ HtmlWebpackPlugin.prototype.postProcessHtml = function (html, assets) {
|
|||
// Inject
|
||||
.then(function () {
|
||||
if (self.options.inject) {
|
||||
return self.injectAssetsIntoHtml(html, assets);
|
||||
return self.injectAssetsIntoHtml(html, assets, assetTags);
|
||||
} else {
|
||||
return html;
|
||||
}
|
||||
|
|
@ -449,27 +456,45 @@ HtmlWebpackPlugin.prototype.htmlWebpackPluginAssets = function (compilation, chu
|
|||
/**
|
||||
* Injects the assets into the given html string
|
||||
*/
|
||||
HtmlWebpackPlugin.prototype.injectAssetsIntoHtml = function (html, assets) {
|
||||
HtmlWebpackPlugin.prototype.generateAssetTags = function (assets) {
|
||||
// Turn script files into script tags
|
||||
var scripts = assets.js.map(function (scriptPath) {
|
||||
return '<script type="text/javascript" src="' + scriptPath + '"></script>';
|
||||
return {
|
||||
tagName: 'script',
|
||||
closeTag: true,
|
||||
attributes: {
|
||||
type: 'text/javascript',
|
||||
src: scriptPath
|
||||
}
|
||||
};
|
||||
});
|
||||
// Make tags self-closing in case of xhtml
|
||||
var xhtml = this.options.xhtml ? '/' : '';
|
||||
var selfClosingTag = !!this.options.xhtml;
|
||||
// Turn css files into link tags
|
||||
var styles = assets.css.map(function (stylePath) {
|
||||
return '<link href="' + stylePath + '" rel="stylesheet"' + xhtml + '>';
|
||||
return {
|
||||
tagName: 'link',
|
||||
selfClosingTag: selfClosingTag,
|
||||
attributes: {
|
||||
href: stylePath,
|
||||
rel: 'stylesheet'
|
||||
}
|
||||
};
|
||||
});
|
||||
// Injections
|
||||
var htmlRegExp = /(<html[^>]*>)/i;
|
||||
// Injection targets
|
||||
var head = [];
|
||||
var headRegExp = /(<\/head>)/i;
|
||||
var body = [];
|
||||
var bodyRegExp = /(<\/body>)/i;
|
||||
|
||||
// If there is a favicon present, add it to the head
|
||||
if (assets.favicon) {
|
||||
head.push('<link rel="shortcut icon" href="' + assets.favicon + '"' + xhtml + '>');
|
||||
head.push({
|
||||
tagName: 'link',
|
||||
selfClosingTag: selfClosingTag,
|
||||
attributes: {
|
||||
rel: 'shortcut icon',
|
||||
href: assets.favicon
|
||||
}
|
||||
});
|
||||
}
|
||||
// Add styles to the head
|
||||
head = head.concat(styles);
|
||||
|
|
@ -479,6 +504,18 @@ HtmlWebpackPlugin.prototype.injectAssetsIntoHtml = function (html, assets) {
|
|||
} else {
|
||||
body = body.concat(scripts);
|
||||
}
|
||||
return {head: head, body: body};
|
||||
};
|
||||
|
||||
/**
|
||||
* Injects the assets into the given html string
|
||||
*/
|
||||
HtmlWebpackPlugin.prototype.injectAssetsIntoHtml = function (html, assets, assetTags) {
|
||||
var htmlRegExp = /(<html[^>]*>)/i;
|
||||
var headRegExp = /(<\/head>)/i;
|
||||
var bodyRegExp = /(<\/body>)/i;
|
||||
var body = assetTags.body.map(this.createHtmlTag);
|
||||
var head = assetTags.head.map(this.createHtmlTag);
|
||||
|
||||
if (body.length) {
|
||||
if (bodyRegExp.test(html)) {
|
||||
|
|
@ -533,6 +570,18 @@ HtmlWebpackPlugin.prototype.appendHash = function (url, hash) {
|
|||
return url + (url.indexOf('?') === -1 ? '?' : '&') + hash;
|
||||
};
|
||||
|
||||
/**
|
||||
* Turn a tag definition into a html string
|
||||
*/
|
||||
HtmlWebpackPlugin.prototype.createHtmlTag = function (tagDefinition) {
|
||||
var attributes = Object.keys(tagDefinition.attributes || {}).map(function (attributeName) {
|
||||
return attributeName + '="' + tagDefinition.attributes[attributeName] + '"';
|
||||
});
|
||||
return '<' + [tagDefinition.tagName].concat(attributes).join(' ') + (tagDefinition.selfClosingTag ? '/' : '') + '>' +
|
||||
(tagDefinition.innerHTML || '') +
|
||||
(tagDefinition.closeTag ? '</' + tagDefinition.tagName + '>' : '');
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to return the absolute template path with a fallback loader
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "html-webpack-plugin",
|
||||
"version": "2.20.0",
|
||||
"version": "2.21.0",
|
||||
"description": "Simplifies creation of HTML files to serve your webpack bundles",
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ var HtmlWebpackPlugin = require('../index.js');
|
|||
|
||||
var OUTPUT_DIR = path.join(__dirname, '../dist');
|
||||
|
||||
jasmine.getEnv().defaultTimeoutInterval = 10000;
|
||||
jasmine.getEnv().defaultTimeoutInterval = 30000;
|
||||
|
||||
function testHtmlPlugin (webpackConfig, expectedResults, outputFile, done, expectErrors, expectWarnings) {
|
||||
outputFile = outputFile || 'index.html';
|
||||
|
|
@ -717,6 +717,38 @@ describe('HtmlWebpackPlugin', function () {
|
|||
['Public path is https://cdn.com'], null, done);
|
||||
});
|
||||
|
||||
it('fires the html-webpack-plugin-alter-asset-tags event', function (done) {
|
||||
var eventFired = false;
|
||||
var examplePlugin = {
|
||||
apply: function (compiler) {
|
||||
compiler.plugin('compilation', function (compilation) {
|
||||
compilation.plugin('html-webpack-plugin-alter-asset-tags', function (object, callback) {
|
||||
expect(typeof object.body).toBe('object');
|
||||
expect(typeof object.head).toBe('object');
|
||||
eventFired = true;
|
||||
callback();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
testHtmlPlugin({
|
||||
entry: {
|
||||
app: path.join(__dirname, 'fixtures/index.js')
|
||||
},
|
||||
output: {
|
||||
path: OUTPUT_DIR,
|
||||
filename: '[name]_bundle.js'
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin(),
|
||||
examplePlugin
|
||||
]
|
||||
}, [], null, function () {
|
||||
expect(eventFired).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('fires the html-webpack-plugin-before-html-processing event', function (done) {
|
||||
var eventFired = false;
|
||||
var examplePlugin = {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ var HtmlWebpackPlugin = require('../index.js');
|
|||
|
||||
var OUTPUT_DIR = path.join(__dirname, '../dist');
|
||||
|
||||
jasmine.getEnv().defaultTimeoutInterval = 10000;
|
||||
jasmine.getEnv().defaultTimeoutInterval = 30000;
|
||||
|
||||
function setUpCompiler (htmlWebpackPlugin) {
|
||||
spyOn(htmlWebpackPlugin, 'evaluateCompilationResult').and.callThrough();
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ var webpackMajorVersion = require('webpack/package.json').version.split('.')[0];
|
|||
|
||||
var OUTPUT_DIR = path.join(__dirname, '../dist');
|
||||
|
||||
jasmine.getEnv().defaultTimeoutInterval = 10000;
|
||||
jasmine.getEnv().defaultTimeoutInterval = 30000;
|
||||
|
||||
function runExample (exampleName, done) {
|
||||
var examplePath = path.resolve(__dirname, '..', 'examples', exampleName);
|
||||
|
|
|
|||
Loading…
Reference in New Issue