Created
February 17, 2016 17:04
-
-
Save gryzzly/36ede9d955dfa37bfa0c to your computer and use it in GitHub Desktop.
A version of HTMLWebpackPlugin that can inline the assets sources
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var minifyJS = require('uglify-js').minify; | |
var minifyHTML = require('html-minifier').minify; | |
// TODO: use lodash.template when Travis | |
// updates npm version to >= 3 | |
var _ = require('lodash'); | |
var path = require('path'); | |
var fs = require('fs'); | |
function toMinifiedSource(compilation, path) { | |
return minifyJS( | |
compilation.assets[path].source(), | |
{fromString: true} | |
).code; | |
} | |
function inlineSource(params, compilation) { | |
if (!params.inline) return params; | |
params.inline.forEach(function(param) { | |
params[param] = toMinifiedSource(compilation, params[param]); | |
}) | |
return params; | |
} | |
/** | |
* This plugin processes a template to a string and adds the result to the | |
* bundle. | |
* | |
* The options are: | |
* template {String} - path to the template | |
* getTemplateParams {Function} - When this function is invoked, it is passed | |
* `chunkMap`, which has the following layout per each chunk: | |
* | |
* `[chunkname]`: { | |
* js: file/[chunkname].[chunkhash].js, | |
* css: file/[chunkname].chunkhash].css | |
* } | |
* | |
* Use this hash to include the paths of the generated files into HTML files. | |
* It is possible to provide file source instead of file path to the template, | |
* and this can be used for inlining the source into HTML, which is useful for | |
* including webpack bootstraping code on the page. To do that specify the name | |
* of the chunk to be inlined: | |
* | |
* @example | |
* new HtmlWebpackPlugin({ | |
* // index.html is an underscore template | |
* template: path.resolve('.', 'src/index.html'), | |
* // - return the object that template will be processed with | |
* // - for `bootstrap` chunk, instead of the file path, get the source | |
* // to inline into html | |
* getTemplateParams: function(chunkMap) { | |
* return { | |
* css: chunkMap.app.css, | |
* app: chunkMap.app.js, | |
* vendor: chunkMap.vendor.js, | |
* bootstrap: chunkMap.bootstrap.js, | |
* inline: ['bootstrap'] | |
* }; | |
* } | |
* }) | |
* getTemplateParams: function(chunkMap) { | |
* return { | |
* css: chunkMap.app.css, | |
* app: chunkMap.app.js, | |
* vendor: chunkMap.vendor.js, | |
* bootstrap: chunkMap.bootstrap.js, | |
* inline: ['bootstrap'] | |
* }; | |
* } | |
* | |
**/ | |
var HtmlWebpackPlugin = function(options) { | |
this.options = options || {}; | |
}; | |
HtmlWebpackPlugin.prototype.apply = function(compiler) { | |
compiler.plugin('emit', function(compilation, compileCallback) { | |
var stats = compilation.getStats().toJson(); | |
var template = _.template(fs.readFileSync(this.options.template)); | |
var output = Object.keys(stats.assetsByChunkName).reduce(function(chunkMap, chunkName) { | |
var files = stats.assetsByChunkName[chunkName]; | |
files = Array.isArray(files) ? files : [files]; | |
chunkMap[chunkName] = files.reduce(function(chunksByType, file) { | |
chunksByType[path.extname(file).slice(1)] = file; | |
return chunksByType; | |
}, {}); | |
return chunkMap; | |
}, {}); | |
var templateParams = inlineSource( | |
this.options.getTemplateParams(output), | |
compilation | |
) | |
var html = template(templateParams); | |
html = minifyHTML(html, { | |
removeComments: true, | |
collapseWhitespace: true | |
}); | |
compilation.fileDependencies.push(this.options.template); | |
compilation.assets[path.basename(this.options.template)] = { | |
source: function() { | |
return html; | |
}, | |
size: function() { | |
return html.length; | |
} | |
}; | |
compileCallback(); | |
}.bind(this)); | |
}; | |
module.exports = HtmlWebpackPlugin; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment