diff --git a/README.md b/README.md
index 7c832fe..01db6f0 100644
--- a/README.md
+++ b/README.md
@@ -263,3 +263,20 @@ plugins: [
]
```
+Events
+------
+
+To allow other plugins to alter the html this plugin executes the following events:
+
+ * `html-webpack-plugin-before-html-processing`
+ * `html-webpack-plugin-after-html-processing`
+ * `html-webpack-plugin-after-emit`
+
+Usage:
+
+```
+ compilation.plugin('html-webpack-plugin-before-html-processing', function(htmlPluginData, callback) {
+ htmlPluginData.html += 'The magic footer';
+ callback();
+ });
+```
diff --git a/index.js b/index.js
index 5859453..b45cb94 100644
--- a/index.js
+++ b/index.js
@@ -97,10 +97,30 @@ HtmlWebpackPlugin.prototype.apply = function(compiler) {
return typeof compilationResult !== 'function' ? compilationResult :
self.executeTemplate(compilationResult, chunks, assets, compilation);
})
+ // Allow plugins to change the html before assets are injected
+ .then(function(html) {
+ return new Promise(function(resolve){
+ var pluginArgs = {html: html, assets: assets, plugin: self};
+ compilation.applyPluginsAsyncWaterfall('html-webpack-plugin-before-html-processing', pluginArgs,
+ function() {
+ resolve(pluginArgs.html);
+ });
+ });
+ })
.then(function(html) {
// Add the stylesheets, scripts and so on to the resulting html
return self.postProcessHtml(html, assets);
})
+ // Allow plugins to change the html after assets are injected
+ .then(function(html) {
+ return new Promise(function(resolve){
+ var pluginArgs = {html: html, assets: assets, plugin: self};
+ compilation.applyPluginsAsyncWaterfall('html-webpack-plugin-after-html-processing', pluginArgs,
+ function() {
+ resolve(pluginArgs.html);
+ });
+ });
+ })
.catch(function(err) {
// In case anything went wrong the promise is resolved
// with the error message and an error is logged
@@ -118,7 +138,11 @@ HtmlWebpackPlugin.prototype.apply = function(compiler) {
return html.length;
}
};
- callback();
+ // Let other plugins know that we are done:
+ compilation.applyPluginsAsyncWaterfall('html-webpack-plugin-after-emit', {
+ html: compilation.assets[self.options.filename],
+ plugin: self
+ }, callback);
});
});
};
@@ -424,21 +448,12 @@ HtmlWebpackPlugin.prototype.htmlWebpackPluginAssets = function(compilation, chun
* Injects the assets into the given html string
*/
HtmlWebpackPlugin.prototype.injectAssetsIntoHtml = function(html, assets) {
- var 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) {
+ var scripts = assets.js.map(function(scriptPath) {
return '';
});
// Turn css files into link tags
- styles = styles.map(function(stylePath) {
+ var styles = assets.css.map(function(stylePath) {
return '';
});
// Injections
diff --git a/package.json b/package.json
index b55940e..4d39900 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "html-webpack-plugin",
- "version": "2.2.0",
+ "version": "2.3.0",
"description": "Simplifies creation of HTML files to serve your webpack bundles",
"main": "index.js",
"files": [
diff --git a/spec/HtmlWebpackPluginSpec.js b/spec/HtmlWebpackPluginSpec.js
index 95e728f..326750f 100644
--- a/spec/HtmlWebpackPluginSpec.js
+++ b/spec/HtmlWebpackPluginSpec.js
@@ -551,6 +551,159 @@ describe('HtmlWebpackPlugin', function() {
['Public path is https://cdn.com'], null, done);
});
+ it('fires the html-webpack-plugin-before-html-processing event', function(done) {
+ var eventFired = false;
+ var examplePlugin = {
+ apply: function(compiler) {
+ compiler.plugin('compilation', function(compilation) {
+ compilation.plugin('html-webpack-plugin-before-html-processing', function(object, callback) {
+ 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-after-html-processing event', function(done) {
+ var eventFired = false;
+ var examplePlugin = {
+ apply: function(compiler) {
+ compiler.plugin('compilation', function(compilation) {
+ compilation.plugin('html-webpack-plugin-after-html-processing', function(object, callback) {
+ 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-after-emit event', function(done) {
+ var eventFired = false;
+ var examplePlugin = {
+ apply: function(compiler) {
+ compiler.plugin('compilation', function(compilation) {
+ compilation.plugin('html-webpack-plugin-after-emit', function(object, callback) {
+ 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('allows to modify the html during html-webpack-plugin-after-html-processing event', function(done) {
+ var eventFired = false;
+ var examplePlugin = {
+ apply: function(compiler) {
+ compiler.plugin('compilation', function(compilation) {
+ compilation.plugin('html-webpack-plugin-after-html-processing', function(object, callback) {
+ eventFired = true;
+ object.html += 'Injected by plugin';
+ callback();
+ });
+ });
+ }
+ };
+ testHtmlPlugin({
+ entry: {
+ app: path.join(__dirname, 'fixtures/index.js')
+ },
+ output: {
+ path: OUTPUT_DIR,
+ filename: '[name]_bundle.js'
+ },
+ plugins: [
+ new HtmlWebpackPlugin(),
+ examplePlugin
+ ]
+ },['Injected by plugin'], null, function() {
+ expect(eventFired).toBe(true);
+ done();
+ });
+ });
+
+ it('allows to modify the html during html-webpack-plugin-before-html-processing event', function(done) {
+ var eventFired = false;
+ var examplePlugin = {
+ apply: function(compiler) {
+ compiler.plugin('compilation', function(compilation) {
+ compilation.plugin('html-webpack-plugin-before-html-processing', function(object, callback) {
+ eventFired = true;
+ object.assets.js.push('funky-script.js');
+ object.html += 'Injected by plugin';
+ callback();
+ });
+ });
+ }
+ };
+ testHtmlPlugin({
+ entry: {
+ app: path.join(__dirname, 'fixtures/index.js')
+ },
+ output: {
+ path: OUTPUT_DIR,
+ filename: '[name]_bundle.js'
+ },
+ plugins: [
+ new HtmlWebpackPlugin(),
+ examplePlugin
+ ]
+ },['Injected by plugin', '