diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-05-03 15:35:00 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-05-03 15:35:00 +0200 |
commit | de98e0b232509d5f40c135d540a70e415272ff85 (patch) | |
tree | a79222a5b58484ab3b80d18efcaaa7ccc4769b33 /node_modules/html-webpack-plugin | |
parent | e0c9d480a73fa629c1e4a47d3e721f1d2d345406 (diff) | |
download | wallet-core-de98e0b232509d5f40c135d540a70e415272ff85.tar.xz |
node_modules
Diffstat (limited to 'node_modules/html-webpack-plugin')
-rw-r--r-- | node_modules/html-webpack-plugin/CHANGELOG.md | 264 | ||||
-rw-r--r-- | node_modules/html-webpack-plugin/LICENSE | 21 | ||||
-rw-r--r-- | node_modules/html-webpack-plugin/README.md | 319 | ||||
-rw-r--r-- | node_modules/html-webpack-plugin/default_index.ejs | 9 | ||||
-rw-r--r-- | node_modules/html-webpack-plugin/index.js | 652 | ||||
-rw-r--r-- | node_modules/html-webpack-plugin/lib/chunksorter.js | 93 | ||||
-rw-r--r-- | node_modules/html-webpack-plugin/lib/compiler.js | 112 | ||||
-rw-r--r-- | node_modules/html-webpack-plugin/lib/errors.js | 23 | ||||
-rw-r--r-- | node_modules/html-webpack-plugin/lib/loader.js | 51 | ||||
l--------- | node_modules/html-webpack-plugin/node_modules/.bin/html-minifier | 1 | ||||
l--------- | node_modules/html-webpack-plugin/node_modules/.bin/webpack | 1 | ||||
-rw-r--r-- | node_modules/html-webpack-plugin/package.json | 68 |
12 files changed, 1614 insertions, 0 deletions
diff --git a/node_modules/html-webpack-plugin/CHANGELOG.md b/node_modules/html-webpack-plugin/CHANGELOG.md new file mode 100644 index 000000000..1aca56867 --- /dev/null +++ b/node_modules/html-webpack-plugin/CHANGELOG.md @@ -0,0 +1,264 @@ +Change History +============== + +v2.28.0 +--- +* Backport 3.x void tag for plugin authors + +v2.27.1 +--- +* Revert 2.25.0 loader resolving + +v2.27.0 +--- +* Fix a chunksorter webpack 2 issue (#569) +* Fix template path resolving(#542) + +v2.26.0 +--- +* Allow plugins to add attributes without values to the `<script>` and `<link>` tags + +v2.25.0 +--- +* Clearer loader output +* Add basic support for webpack 2 + +v2.24.1 +--- +* Hide event deprecated warning of 'applyPluginsAsyncWaterfall' for html-webpack-plugin-after-emit and improve the warning message. + +v2.24.0 +--- +* Update dependencies +* Add deprecate warning for plugins not returning a result +* Add [path] for favicons + +v2.23.0 +--- +* Update dependencies +* Stop automated tests for webpack 2 beta because of #401 + +v2.22.0 +--- +* Update dependencies + +v2.21.1 +--- +* Better error handling (#354) + +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 + +v2.19.0 +---- +* Add `html-webpack-plugin-alter-chunks` event for custom chunk sorting and interpolation + +v2.18.0 +---- +* Updated all dependencies + +v2.17.0 +---- +* Add `type` attribute to `script` element to prevent issues in Safari 9.1.1 + +v2.16.2 +---- +* Fix bug introduced by 2.16.2. Fixes #315 + +v2.16.1 +---- +* Fix hot module replacement for webpack 2.x + +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 +* For webpack 2 the default sort will be 'dependency' instead of 'id' +* Upgrade dependencies + +v2.14.0 +---- +* Export publicPath to the template +* Add example for inlining css and js + +v2.13.0 +---- +* Add support for absolute output file names +* Add support for relative file names outside the output path + +v2.12.0 +---- +* Basic Webpack 2.x support #225 + +v2.11.0 +---- +* Add `xhtml` option which is turned of by default. When activated it will inject self closed `<link href=".." />` tags instead of unclosed `<link href="..">` tags. https://github.com/ampedandwired/html-webpack-plugin/pull/255 +* Add support for webpack placeholders inside the public path e.g. `'/dist/[hash]/'`. https://github.com/ampedandwired/html-webpack-plugin/pull/249 + +v2.10.0 +---- +* Add `hash` field to the chunk object +* Add `compilation` field to the templateParam object (fixes https://github.com/ampedandwired/html-webpack-plugin/issues/237) +* Add `html-webpack-plugin-before-html-generation` event +* Improve error messages + +v2.9.0 +---- +* Fix favicon path (fixes https://github.com/ampedandwired/html-webpack-plugin/issues/185, https://github.com/ampedandwired/html-webpack-plugin/issues/208, https://github.com/ampedandwired/html-webpack-plugin/pull/215 ) + +v2.8.2 +---- +* Support relative URLs on Windows (fixes https://github.com/ampedandwired/html-webpack-plugin/issues/205 ) + +v2.8.1 +---- +* Caching improvements (fixes https://github.com/ampedandwired/html-webpack-plugin/issues/204 ) + +v2.8.0 +---- +* Add `dependency` mode for `chunksSortMode` to sort chunks based on their dependencies with each other + +v2.7.2 +---- +* Add support for require in js templates + +v2.7.1 +---- +* Refactoring +* Fix relative windows path + +v2.6.5 +---- +* Minor refactoring + +v2.6.4 +---- +* Fix for `"Uncaught TypeError: __webpack_require__(...) is not a function"` +* Fix incomplete cache modules causing "HtmlWebpackPlugin Error: No source available" +* Fix some issues on Windows + +v2.6.3 +---- +* Prevent parsing the base template with the html-loader + +v2.6.2 +---- +* Fix `lodash` resolve error (fixes https://github.com/ampedandwired/html-webpack-plugin/issues/172 ) + +v2.6.1 +---- +* Fix missing module (fixes https://github.com/ampedandwired/html-webpack-plugin/issues/164 ) + +v2.6.0 +---- +* Move compiler to its own file +* Improve error messages +* Fix global HTML_WEBPACK_PLUGIN variable + +v2.5.0 +---- +* Support `lodash` template's HTML _"escape"_ delimiter (`<%- %>`) +* Fix bluebird warning (fixes https://github.com/ampedandwired/html-webpack-plugin/issues/130 ) +* Fix an issue where incomplete cache modules were used + +v2.4.0 +---- +* Don't recompile if the assets didn't change + +v2.3.0 +---- +* Add events `html-webpack-plugin-before-html-processing`, `html-webpack-plugin-after-html-processing`, `html-webpack-plugin-after-emit` to allow other plugins to alter the html this plugin executes + +v2.2.0 +---- +* Inject css and js even if the html file is incomplete (fixes https://github.com/ampedandwired/html-webpack-plugin/issues/135 ) +* Update dependencies + +v2.1.0 +---- +* Synchronize with the stable `@1` version + +v2.0.4 +---- +* Fix `minify` option +* Fix missing hash interpolation in publicPath + +v2.0.3 +---- +* Add support for webpack.BannerPlugin + +v2.0.2 +---- +* Add support for loaders in templates (fixes https://github.com/ampedandwired/html-webpack-plugin/pull/41 ) +* Remove `templateContent` option from configuration +* Better error messages +* Update dependencies + + +v1.7.0 +---- +* Add `chunksSortMode` option to configuration to control how chunks should be sorted before they are included to the html +* Don't insert async chunks into html (fixes https://github.com/ampedandwired/html-webpack-plugin/issues/95 ) +* Update dependencies + +v1.6.2 +---- +* Fix paths on Windows +* Fix missing hash interpolation in publicPath +* Allow only `false` or `object` in `minify` configuration option + +v1.6.1 +---- +* Add `size` field to the chunk object +* Fix stylesheet `<link>`s being discarded when used with `"inject: 'head'"` +* Update dependencies + +v1.6.0 +---- +* Support placing templates in subfolders +* Don't include chunks with undefined name (fixes https://github.com/ampedandwired/html-webpack-plugin/pull/60 ) +* Don't include async chunks + +v1.5.2 +---- +* Update dependencies (lodash) + +v1.5.1 +---- +* Fix error when manifest is specified (fixes https://github.com/ampedandwired/html-webpack-plugin/issues/56 ) + +v1.5.0 +---- +* Allow to inject javascript files into the head of the html page +* Fix error reporting + +v1.4.0 +---- +* Add `favicon.ico` option +* Add html minifcation + +v1.2.0 +------ +* Set charset using HTML5 meta attribute +* Reload upon change when using webpack watch mode +* Generate manifest attribute when using + [appcache-webpack-plugin](https://github.com/lettertwo/appcache-webpack-plugin) +* Optionally add webpack hash as a query string to resources included in the HTML + (`hash: true`) for cache busting +* CSS files generated using webpack (for example, by using the + [extract-text-webpack-plugin](https://github.com/webpack/extract-text-webpack-plugin)) + are now automatically included into the generated HTML +* More detailed information about the files generated by webpack is now available + to templates in the `o.htmlWebpackPlugin.files` attribute. See readme for more + details. This new attribute deprecates the old `o.htmlWebpackPlugin.assets` attribute. +* The `templateContent` option can now be a function that returns the template string to use +* Expose webpack configuration to templates (`o.webpackConfig`) +* Sort chunks to honour dependencies between them (useful for use with CommonsChunkPlugin). diff --git a/node_modules/html-webpack-plugin/LICENSE b/node_modules/html-webpack-plugin/LICENSE new file mode 100644 index 000000000..665a79016 --- /dev/null +++ b/node_modules/html-webpack-plugin/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Charles Blaxland + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/html-webpack-plugin/README.md b/node_modules/html-webpack-plugin/README.md new file mode 100644 index 000000000..46259223e --- /dev/null +++ b/node_modules/html-webpack-plugin/README.md @@ -0,0 +1,319 @@ +HTML Webpack Plugin +=================== +[![npm version](https://badge.fury.io/js/html-webpack-plugin.svg)](http://badge.fury.io/js/html-webpack-plugin) [![Dependency Status](https://david-dm.org/ampedandwired/html-webpack-plugin.svg)](https://david-dm.org/ampedandwired/html-webpack-plugin) [![Build status](https://travis-ci.org/ampedandwired/html-webpack-plugin.svg)](https://travis-ci.org/ampedandwired/html-webpack-plugin) [![Windows build status](https://ci.appveyor.com/api/projects/status/github/ampedandwired/html-webpack-plugin?svg=true&branch=master)](https://ci.appveyor.com/project/jantimon/html-webpack-plugin) [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg?style=flat-square)](https://github.com/Flet/semistandard) [![bitHound Dependencies](https://www.bithound.io/github/ampedandwired/html-webpack-plugin/badges/dependencies.svg)](https://www.bithound.io/github/ampedandwired/html-webpack-plugin/master/dependencies/npm) [![license](https://img.shields.io/github/license/mashape/apistatus.svg?maxAge=2592000)]() + +[![NPM](https://nodei.co/npm/html-webpack-plugin.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/html-webpack-plugin/) + +This is a [webpack](http://webpack.github.io/) plugin that simplifies creation of HTML files to serve your +webpack bundles. This is especially useful for webpack bundles that include +a hash in the filename which changes every compilation. You can either let the plugin generate an HTML file for you, supply +your own template using lodash templates or use your own loader. + +Maintainer: Jan Nicklas [@jantimon](https://twitter.com/jantimon) + +Installation +------------ +Install the plugin with npm: +```shell +$ npm install html-webpack-plugin --save-dev +``` + +Third party addons: +------------- + +The html-webpack-plugin provides [hooks](https://github.com/ampedandwired/html-webpack-plugin#events) to extend it to your needs. +There are already some really powerful plugins which can be integrated with zero configuration: + + * [webpack-subresource-integrity](https://www.npmjs.com/package/webpack-subresource-integrity) for enhanced asset security + * [appcache-webpack-plugin](https://github.com/lettertwo/appcache-webpack-plugin) for iOS and Android offline usage + * [favicons-webpack-plugin](https://github.com/jantimon/favicons-webpack-plugin) which generates favicons and icons for iOS, Android and desktop browsers + * [html-webpack-harddisk-plugin](https://github.com/jantimon/html-webpack-harddisk-plugin) + * [html-webpack-inline-source-plugin](https://github.com/DustinJackson/html-webpack-inline-source-plugin) to inline your assets in the resulting HTML file + * [html-webpack-exclude-assets-plugin](https://github.com/jamesjieye/html-webpack-exclude-assets-plugin) for excluding assets using regular expressions + * [html-webpack-include-assets-plugin](https://github.com/jharris4/html-webpack-include-assets-plugin) for including lists of js or css file paths (such as those copied by the copy-webpack-plugin). + * [script-ext-html-webpack-plugin](https://github.com/numical/script-ext-html-webpack-plugin) to add `async`, `defer` or `module` attributes to your`<script>` elements, or even in-line them + * [style-ext-html-webpack-plugin](https://github.com/numical/style-ext-html-webpack-plugin) to convert your `<link>`s to external stylesheets into `<style>` elements containing internal CSS + * [resource-hints-webpack-plugin](https://github.com/jantimon/resource-hints-webpack-plugin) to add resource hints for faster initial page loads + +Basic Usage +----------- + +The plugin will generate an HTML5 file for you that includes all your webpack +bundles in the body using `script` tags. Just add the plugin to your webpack +config as follows: + +```javascript +var HtmlWebpackPlugin = require('html-webpack-plugin'); +var webpackConfig = { + entry: 'index.js', + output: { + path: 'dist', + filename: 'index_bundle.js' + }, + plugins: [new HtmlWebpackPlugin()] +}; +``` + +This will generate a file `dist/index.html` containing the following: +```html +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title>Webpack App</title> + </head> + <body> + <script src="index_bundle.js"></script> + </body> +</html> +``` + +If you have multiple webpack entry points, they will all be included with `script` +tags in the generated HTML. + +If you have any CSS assets in webpack's output (for example, CSS extracted +with the [ExtractTextPlugin](https://github.com/webpack/extract-text-webpack-plugin)) +then these will be included with `<link>` tags in the HTML head. + +Configuration +------------- +You can pass a hash of configuration options to `HtmlWebpackPlugin`. +Allowed values are as follows: + +- `title`: The title to use for the generated HTML document. +- `filename`: The file to write the HTML to. Defaults to `index.html`. + You can specify a subdirectory here too (eg: `assets/admin.html`). +- `template`: Webpack require path to the template. Please see the [docs](https://github.com/ampedandwired/html-webpack-plugin/blob/master/docs/template-option.md) for details. +- `inject`: `true | 'head' | 'body' | false` Inject all assets into the given `template` or `templateContent` - When passing `true` or `'body'` all javascript resources will be placed at the bottom of the body element. `'head'` will place the scripts in the head element. +- `favicon`: Adds the given favicon path to the output html. +- `minify`: `{...} | false` Pass a [html-minifier](https://github.com/kangax/html-minifier#options-quick-reference) options object to minify the output. +- `hash`: `true | false` if `true` then append a unique webpack compilation hash to all + included scripts and CSS files. This is useful for cache busting. +- `cache`: `true | false` if `true` (default) try to emit the file only if it was changed. +- `showErrors`: `true | false` if `true` (default) errors details will be written into the HTML page. +- `chunks`: Allows you to add only some chunks (e.g. only the unit-test chunk) +- `chunksSortMode`: Allows to control how chunks should be sorted before they are included to the html. Allowed values: 'none' | 'auto' | 'dependency' | {function} - default: 'auto' +- `excludeChunks`: Allows you to skip some chunks (e.g. don't add the unit-test chunk) +- `xhtml`: `true | false` If `true` render the `link` tags as self-closing, XHTML compliant. Default is `false` + +Here's an example webpack config illustrating how to use these options: +```javascript +{ + entry: 'index.js', + output: { + path: 'dist', + filename: 'index_bundle.js' + }, + plugins: [ + new HtmlWebpackPlugin({ + title: 'My App', + filename: 'assets/admin.html' + }) + ] +} +``` + +FAQ +---- + +* [Why is my HTML minified?](https://github.com/ampedandwired/html-webpack-plugin/blob/master/docs/template-option.md) +* [Why is my `<% ... %>` template not working?](https://github.com/ampedandwired/html-webpack-plugin/blob/master/docs/template-option.md) +* [How can I use handlebars/pug/ejs as template engine](https://github.com/ampedandwired/html-webpack-plugin/blob/master/docs/template-option.md) + +Generating Multiple HTML Files +------------------------------ +To generate more than one HTML file, declare the plugin more than +once in your plugins array: +```javascript +{ + entry: 'index.js', + output: { + path: 'dist', + filename: 'index_bundle.js' + }, + plugins: [ + new HtmlWebpackPlugin(), // Generates default index.html + new HtmlWebpackPlugin({ // Also generate a test.html + filename: 'test.html', + template: 'src/assets/test.html' + }) + ] +} +``` + +Writing Your Own Templates +-------------------------- +If the default generated HTML doesn't meet your needs you can supply +your own template. The easiest way is to use the `template` option and pass a custom HTML file. +The html-webpack-plugin will automatically inject all necessary CSS, JS, manifest +and favicon files into the markup. + +```javascript +plugins: [ + new HtmlWebpackPlugin({ + title: 'Custom template', + template: 'my-index.ejs', // Load a custom template (ejs by default see the FAQ for details) + }) +] +``` + +`my-index.ejs`: + +```html +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-type" content="text/html; charset=utf-8"/> + <title><%= htmlWebpackPlugin.options.title %></title> + </head> + <body> + </body> +</html> +``` + +If you already have a template loader, you can use it to parse the template. +Please note that this will also happen if you specifiy the html-loader and use `.html` file as template. + +```javascript +module: { + loaders: [ + { test: /\.hbs$/, loader: "handlebars" } + ] +}, +plugins: [ + new HtmlWebpackPlugin({ + title: 'Custom template using Handlebars', + template: 'my-index.hbs' + }) +] +``` + +You can use the lodash syntax out of the box. +If the `inject` feature doesn't fit your needs and you want full control over the asset placement use the [default template](https://github.com/jaketrent/html-webpack-template/blob/86f285d5c790a6c15263f5cc50fd666d51f974fd/index.html) of the [html-webpack-template project](https://github.com/jaketrent/html-webpack-template) as a starting point for writing your own. + +The following variables are available in the template: +- `htmlWebpackPlugin`: data specific to this plugin + - `htmlWebpackPlugin.files`: a massaged representation of the + `assetsByChunkName` attribute of webpack's [stats](https://github.com/webpack/docs/wiki/node.js-api#stats) + object. It contains a mapping from entry point name to the bundle filename, eg: + ```json + "htmlWebpackPlugin": { + "files": { + "css": [ "main.css" ], + "js": [ "assets/head_bundle.js", "assets/main_bundle.js"], + "chunks": { + "head": { + "entry": "assets/head_bundle.js", + "css": [ "main.css" ] + }, + "main": { + "entry": "assets/main_bundle.js", + "css": [] + }, + } + } + } + ``` + If you've set a publicPath in your webpack config this will be reflected + correctly in this assets hash. + + - `htmlWebpackPlugin.options`: the options hash that was passed to + the plugin. In addition to the options actually used by this plugin, + you can use this hash to pass arbitrary data through to your template. + +- `webpack`: the webpack [stats](https://github.com/webpack/docs/wiki/node.js-api#stats) + object. Note that this is the stats object as it was at the time the HTML template + was emitted and as such may not have the full set of stats that are available + after the wepback run is complete. + +- `webpackConfig`: the webpack configuration that was used for this compilation. This + can be used, for example, to get the `publicPath` (`webpackConfig.output.publicPath`). + + +Filtering chunks +---------------- + +To include only certain chunks you can limit the chunks being used: + +```javascript +plugins: [ + new HtmlWebpackPlugin({ + chunks: ['app'] + }) +] +``` + +It is also possible to exclude certain chunks by setting the `excludeChunks` option: + +```javascript +plugins: [ + new HtmlWebpackPlugin({ + excludeChunks: ['dev-helper'] + }) +] +``` + +Events +------ + +To allow other [plugins](https://github.com/webpack/docs/wiki/plugins) to alter the HTML this plugin executes the following events: + +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` + +Sync: + + * `html-webpack-plugin-alter-chunks` + +Example implementation: [html-webpack-harddisk-plugin](https://github.com/jantimon/html-webpack-harddisk-plugin) + +Usage: + +```javascript +// MyPlugin.js + +function MyPlugin(options) { + // Configure your plugin with options... +} + +MyPlugin.prototype.apply = function(compiler) { + // ... + compiler.plugin('compilation', function(compilation) { + console.log('The compiler is starting a new compilation...'); + + compilation.plugin('html-webpack-plugin-before-html-processing', function(htmlPluginData, callback) { + htmlPluginData.html += 'The magic footer'; + callback(null, htmlPluginData); + }); + }); + +}; + +module.exports = MyPlugin; +``` +Then in `webpack.config.js` + +```javascript +plugins: [ + new MyPlugin({options: ''}) +] +``` + +Note that the callback must be passed the htmlPluginData in order to pass this onto any other plugins listening on the same `html-webpack-plugin-before-html-processing` event. + + +# Contribution + +You're free to contribute to this project by submitting [issues](https://github.com/ampedandwired/html-webpack-plugin/issues) and/or [pull requests](https://github.com/ampedandwired/html-webpack-plugin/pulls). This project is test-driven, so keep in mind that every change and new feature should be covered by tests. +This project uses the [semistandard code style](https://github.com/Flet/semistandard). + +Before running the tests, make sure to execute `yarn link` and `yarn link html-webpack-plugin` (or the npm variant of this). + +# License + +This project is licensed under [MIT](https://github.com/ampedandwired/html-webpack-plugin/blob/master/LICENSE). diff --git a/node_modules/html-webpack-plugin/default_index.ejs b/node_modules/html-webpack-plugin/default_index.ejs new file mode 100644 index 000000000..f9466a461 --- /dev/null +++ b/node_modules/html-webpack-plugin/default_index.ejs @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="UTF-8"> + <title><%= htmlWebpackPlugin.options.title %></title> + </head> + <body> + </body> +</html>
\ No newline at end of file diff --git a/node_modules/html-webpack-plugin/index.js b/node_modules/html-webpack-plugin/index.js new file mode 100644 index 000000000..40633a68b --- /dev/null +++ b/node_modules/html-webpack-plugin/index.js @@ -0,0 +1,652 @@ +'use strict'; +var vm = require('vm'); +var fs = require('fs'); +var _ = require('lodash'); +var Promise = require('bluebird'); +var path = require('path'); +var childCompiler = require('./lib/compiler.js'); +var prettyError = require('./lib/errors.js'); +var chunkSorter = require('./lib/chunksorter.js'); +Promise.promisifyAll(fs); + +function HtmlWebpackPlugin (options) { + // Default options + this.options = _.extend({ + template: path.join(__dirname, 'default_index.ejs'), + filename: 'index.html', + hash: false, + inject: true, + compile: true, + favicon: false, + minify: false, + cache: true, + showErrors: true, + chunks: 'all', + excludeChunks: [], + title: 'Webpack App', + xhtml: false + }, options); +} + +HtmlWebpackPlugin.prototype.apply = function (compiler) { + var self = this; + var isCompilationCached = false; + var compilationPromise; + + this.options.template = this.getFullTemplatePath(this.options.template, compiler.context); + + // convert absolute filename into relative so that webpack can + // generate it at correct location + var filename = this.options.filename; + if (path.resolve(filename) === path.normalize(filename)) { + this.options.filename = path.relative(compiler.options.output.path, filename); + } + + compiler.plugin('make', function (compilation, callback) { + // Compile the template (queued) + compilationPromise = childCompiler.compileTemplate(self.options.template, compiler.context, self.options.filename, compilation) + .catch(function (err) { + compilation.errors.push(prettyError(err, compiler.context).toString()); + return { + 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; + }); + }); + + compiler.plugin('emit', function (compilation, callback) { + var applyPluginsAsyncWaterfall = self.applyPluginsAsyncWaterfall(compilation); + // Get all chunks + var allChunks = compilation.getStats().toJson().chunks; + // Filter chunks (options.chunks and options.excludeCHunks) + var chunks = self.filterChunks(allChunks, self.options.chunks, self.options.excludeChunks); + // Sort chunks + chunks = self.sortChunks(chunks, self.options.chunksSortMode); + // Let plugins alter the chunks and the chunk sorting + chunks = compilation.applyPluginsWaterfall('html-webpack-plugin-alter-chunks', chunks, { plugin: self }); + // Get assets + var assets = self.htmlWebpackPluginAssets(compilation, chunks); + // If this is a hot update compilation, move on! + // This solves a problem where an `index.html` file is generated for hot-update js files + // It only happens in Webpack 2, where hot updates are emitted separately before the full bundle + if (self.isHotUpdateCompilation(assets)) { + return callback(); + } + + // If the template and the assets did not change we don't have to emit the html + var assetJson = JSON.stringify(self.getAssetFiles(assets)); + if (isCompilationCached && self.options.cache && assetJson === self.assetJson) { + return callback(); + } else { + self.assetJson = assetJson; + } + + Promise.resolve() + // Favicon + .then(function () { + if (self.options.favicon) { + return self.addFileToAssets(self.options.favicon, compilation) + .then(function (faviconBasename) { + var publicPath = compilation.mainTemplate.getPublicPath({hash: compilation.hash}) || ''; + if (publicPath && publicPath.substr(-1) !== '/') { + publicPath += '/'; + } + assets.favicon = publicPath + faviconBasename; + }); + } + }) + // Wait for the compilation to finish + .then(function () { + return compilationPromise; + }) + .then(function (compiledTemplate) { + // Allow to use a custom function / string instead + if (self.options.templateContent !== undefined) { + return self.options.templateContent; + } + // Once everything is compiled evaluate the html factory + // and replace it with its content + return self.evaluateCompilationResult(compilation, compiledTemplate); + }) + // 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', false, { + assets: assets, + outputName: self.childCompilationOutputName, + plugin: self + }) + .then(function () { + return compilationResult; + }); + }) + // Execute the template + .then(function (compilationResult) { + // If the loader result is a function execute it to retrieve the html + // otherwise use the returned html + return typeof compilationResult !== 'function' + ? compilationResult + : self.executeTemplate(compilationResult, chunks, assets, compilation); + }) + // Allow plugins to change the html before assets are injected + .then(function (html) { + var pluginArgs = {html: html, assets: assets, plugin: self, outputName: self.childCompilationOutputName}; + return applyPluginsAsyncWaterfall('html-webpack-plugin-before-html-processing', true, pluginArgs); + }) + .then(function (result) { + var html = result.html; + var assets = result.assets; + var chunks = result.chunks; + // 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', true, pluginArgs) + .then(function (result) { + // Add the stylesheets, scripts and so on to the resulting html + return self.postProcessHtml(html, assets, { body: result.body, head: result.head }) + .then(function (html) { + return _.extend(result, {html: html, assets: assets}); + }); + }); + }) + // Allow plugins to change the html after assets are injected + .then(function (result) { + var html = result.html; + var assets = result.assets; + var pluginArgs = {html: html, assets: assets, plugin: self, outputName: self.childCompilationOutputName}; + return applyPluginsAsyncWaterfall('html-webpack-plugin-after-html-processing', true, pluginArgs) + .then(function (result) { + return result.html; + }); + }) + .catch(function (err) { + // In case anything went wrong the promise is resolved + // with the error message and an error is logged + compilation.errors.push(prettyError(err, compiler.context).toString()); + // Prevent caching + self.hash = null; + return self.options.showErrors ? prettyError(err, compiler.context).toHtml() : 'ERROR'; + }) + .then(function (html) { + // Replace the compilation result with the evaluated html code + compilation.assets[self.childCompilationOutputName] = { + source: function () { + return html; + }, + size: function () { + return html.length; + } + }; + }) + .then(function () { + // Let other plugins know that we are done: + return applyPluginsAsyncWaterfall('html-webpack-plugin-after-emit', false, { + 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 + .finally(function () { + callback(); + // Tell blue bird that we don't want to wait for callback. + // Fixes "Warning: a promise was created in a handler but none were returned from it" + // https://github.com/petkaantonov/bluebird/blob/master/docs/docs/warning-explanations.md#warning-a-promise-was-created-in-a-handler-but-none-were-returned-from-it + return null; + }); + }); +}; + +/** + * Evaluates the child compilation result + * Returns a promise + */ +HtmlWebpackPlugin.prototype.evaluateCompilationResult = function (compilation, source) { + if (!source) { + return Promise.reject('The child compilation didn\'t provide a result'); + } + + // The LibraryTemplatePlugin stores the template result in a local variable. + // To extract the result during the evaluation this part has to be removed. + source = source.replace('var HTML_WEBPACK_PLUGIN_RESULT =', ''); + var template = this.options.template.replace(/^.+!/, '').replace(/\?.+$/, ''); + var vmContext = vm.createContext(_.extend({HTML_WEBPACK_PLUGIN: true, require: require}, global)); + var vmScript = new vm.Script(source, {filename: template}); + // Evaluate code and cast to string + var newSource; + try { + newSource = vmScript.runInContext(vmContext); + } catch (e) { + return Promise.reject(e); + } + if (typeof newSource === 'object' && newSource.__esModule && newSource.default) { + newSource = newSource.default; + } + return typeof newSource === 'string' || typeof newSource === 'function' + ? Promise.resolve(newSource) + : Promise.reject('The loader "' + this.options.template + '" didn\'t return html.'); +}; + +/** + * Html post processing + * + * Returns a promise + */ +HtmlWebpackPlugin.prototype.executeTemplate = function (templateFunction, chunks, assets, compilation) { + var self = this; + return Promise.resolve() + // Template processing + .then(function () { + var templateParams = { + compilation: compilation, + webpack: compilation.getStats().toJson(), + webpackConfig: compilation.options, + htmlWebpackPlugin: { + files: assets, + options: self.options + } + }; + var html = ''; + try { + html = templateFunction(templateParams); + } catch (e) { + compilation.errors.push(new Error('Template execution failed: ' + e)); + return Promise.reject(e); + } + return html; + }); +}; + +/** + * Html post processing + * + * Returns a promise + */ +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)); + } + return Promise.resolve() + // Inject + .then(function () { + if (self.options.inject) { + return self.injectAssetsIntoHtml(html, assets, assetTags); + } else { + return html; + } + }) + // Minify + .then(function (html) { + if (self.options.minify) { + var minify = require('html-minifier').minify; + return minify(html, self.options.minify); + } + return html; + }); +}; + +/* + * Pushes the content of the given filename to the compilation assets + */ +HtmlWebpackPlugin.prototype.addFileToAssets = function (filename, compilation) { + filename = path.resolve(compilation.compiler.context, filename); + return Promise.props({ + size: fs.statAsync(filename), + source: fs.readFileAsync(filename) + }) + .catch(function () { + return Promise.reject(new Error('HtmlWebpackPlugin: could not load file ' + filename)); + }) + .then(function (results) { + var basename = path.basename(filename); + compilation.fileDependencies.push(filename); + compilation.assets[basename] = { + source: function () { + return results.source; + }, + size: function () { + return results.size.size; + } + }; + return basename; + }); +}; + +/** + * Helper to sort chunks + */ +HtmlWebpackPlugin.prototype.sortChunks = function (chunks, sortMode) { + // Sort mode auto by default: + if (typeof sortMode === 'undefined') { + sortMode = 'auto'; + } + // Custom function + if (typeof sortMode === 'function') { + return chunks.sort(sortMode); + } + // Disabled sorting: + if (sortMode === 'none') { + return chunkSorter.none(chunks); + } + // Check if the given sort mode is a valid chunkSorter sort mode + if (typeof chunkSorter[sortMode] !== 'undefined') { + return chunkSorter[sortMode](chunks); + } + throw new Error('"' + sortMode + '" is not a valid chunk sort mode'); +}; + +/** + * Return all chunks from the compilation result which match the exclude and include filters + */ +HtmlWebpackPlugin.prototype.filterChunks = function (chunks, includedChunks, excludedChunks) { + return chunks.filter(function (chunk) { + var chunkName = chunk.names[0]; + // This chunk doesn't have a name. This script can't handled it. + if (chunkName === undefined) { + return false; + } + // Skip if the chunk should be lazy loaded + if (!chunk.initial) { + return false; + } + // Skip if the chunks should be filtered and the given chunk was not added explicity + if (Array.isArray(includedChunks) && includedChunks.indexOf(chunkName) === -1) { + return false; + } + // Skip if the chunks should be filtered and the given chunk was excluded explicity + if (Array.isArray(excludedChunks) && excludedChunks.indexOf(chunkName) !== -1) { + return false; + } + // Add otherwise + return true; + }); +}; + +HtmlWebpackPlugin.prototype.isHotUpdateCompilation = function (assets) { + return assets.js.length && assets.js.every(function (name) { + return /\.hot-update\.js$/.test(name); + }); +}; + +HtmlWebpackPlugin.prototype.htmlWebpackPluginAssets = function (compilation, chunks) { + var self = this; + var webpackStatsJson = compilation.getStats().toJson(); + + // Use the configured public path or build a relative path + var publicPath = typeof compilation.options.output.publicPath !== 'undefined' + // 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.childCompilationOutputName)), compilation.options.output.path) + .split(path.sep).join('/'); + + if (publicPath.length && publicPath.substr(-1, 1) !== '/') { + publicPath += '/'; + } + + var assets = { + // The public path + publicPath: publicPath, + // Will contain all js & css files by chunk + chunks: {}, + // Will contain all js files + js: [], + // Will contain all css files + css: [], + // Will contain the html5 appcache manifest files if it exists + manifest: Object.keys(compilation.assets).filter(function (assetFile) { + return path.extname(assetFile) === '.appcache'; + })[0] + }; + + // Append a hash for cache busting + if (this.options.hash) { + assets.manifest = self.appendHash(assets.manifest, webpackStatsJson.hash); + assets.favicon = self.appendHash(assets.favicon, webpackStatsJson.hash); + } + + for (var i = 0; i < chunks.length; i++) { + var chunk = chunks[i]; + var chunkName = chunk.names[0]; + + assets.chunks[chunkName] = {}; + + // Prepend the public path to all chunk files + var chunkFiles = [].concat(chunk.files).map(function (chunkFile) { + return publicPath + chunkFile; + }); + + // Append a hash for cache busting + if (this.options.hash) { + chunkFiles = chunkFiles.map(function (chunkFile) { + return self.appendHash(chunkFile, webpackStatsJson.hash); + }); + } + + // Webpack outputs an array for each chunk when using sourcemaps + // But we need only the entry file + var entry = chunkFiles[0]; + assets.chunks[chunkName].size = chunk.size; + assets.chunks[chunkName].entry = entry; + assets.chunks[chunkName].hash = chunk.hash; + assets.js.push(entry); + + // Gather all css files + var css = chunkFiles.filter(function (chunkFile) { + // Some chunks may contain content hash in their names, for ex. 'main.css?1e7cac4e4d8b52fd5ccd2541146ef03f'. + // We must proper handle such cases, so we use regexp testing here + return /.css($|\?)/.test(chunkFile); + }); + assets.chunks[chunkName].css = css; + assets.css = assets.css.concat(css); + } + + // Duplicate css assets can occur on occasion if more than one chunk + // requires the same css. + assets.css = _.uniq(assets.css); + + return assets; +}; + +/** + * Injects the assets into the given html string + */ +HtmlWebpackPlugin.prototype.generateAssetTags = function (assets) { + // Turn script files into script tags + var scripts = assets.js.map(function (scriptPath) { + return { + tagName: 'script', + closeTag: true, + attributes: { + type: 'text/javascript', + src: scriptPath + } + }; + }); + // Make tags self-closing in case of xhtml + var selfClosingTag = !!this.options.xhtml; + // Turn css files into link tags + var styles = assets.css.map(function (stylePath) { + return { + tagName: 'link', + selfClosingTag: selfClosingTag, + attributes: { + href: stylePath, + rel: 'stylesheet' + } + }; + }); + // Injection targets + var head = []; + var body = []; + + // If there is a favicon present, add it to the head + if (assets.favicon) { + head.push({ + tagName: 'link', + selfClosingTag: selfClosingTag, + attributes: { + rel: 'shortcut icon', + href: assets.favicon + } + }); + } + // Add styles to the head + head = head.concat(styles); + // Add scripts to body or head + if (this.options.inject === 'head') { + head = head.concat(scripts); + } 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)) { + // Append assets to body element + html = html.replace(bodyRegExp, function (match) { + return body.join('') + match; + }); + } else { + // Append scripts to the end of the file if no <body> element exists: + html += body.join(''); + } + } + + if (head.length) { + // Create a head tag if none exists + if (!headRegExp.test(html)) { + if (!htmlRegExp.test(html)) { + html = '<head></head>' + html; + } else { + html = html.replace(htmlRegExp, function (match) { + return match + '<head></head>'; + }); + } + } + + // Append assets to head element + html = html.replace(headRegExp, function (match) { + return head.join('') + match; + }); + } + + // Inject manifest into the opening html tag + if (assets.manifest) { + html = html.replace(/(<html[^>]*)(>)/i, function (match, start, end) { + // Append the manifest only if no manifest was specified + if (/\smanifest\s*=/.test(match)) { + return match; + } + return start + ' manifest="' + assets.manifest + '"' + end; + }); + } + return html; +}; + +/** + * Appends a cache busting hash + */ +HtmlWebpackPlugin.prototype.appendHash = function (url, hash) { + if (!url) { + return url; + } + 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 || {}) + .filter(function (attributeName) { + return tagDefinition.attributes[attributeName] !== false; + }) + .map(function (attributeName) { + if (tagDefinition.attributes[attributeName] === true) { + return attributeName; + } + return attributeName + '="' + tagDefinition.attributes[attributeName] + '"'; + }); + // Backport of 3.x void tag definition + var voidTag = tagDefinition.voidTag !== undefined ? tagDefinition.voidTag : !tagDefinition.closeTag; + var selfClosingTag = tagDefinition.voidTag !== undefined ? tagDefinition.voidTag && this.options.xhtml : tagDefinition.selfClosingTag; + return '<' + [tagDefinition.tagName].concat(attributes).join(' ') + (selfClosingTag ? '/' : '') + '>' + + (tagDefinition.innerHTML || '') + + (voidTag ? '' : '</' + tagDefinition.tagName + '>'); +}; + +/** + * Helper to return the absolute template path with a fallback loader + */ +HtmlWebpackPlugin.prototype.getFullTemplatePath = function (template, context) { + // If the template doesn't use a loader use the lodash template loader + if (template.indexOf('!') === -1) { + template = require.resolve('./lib/loader.js') + '!' + path.resolve(context, template); + } + // Resolve template path + return template.replace( + /([!])([^/\\][^!?]+|[^/\\!?])($|\?[^!?\n]+$)/, + function (match, prefix, filepath, postfix) { + return prefix + path.resolve(filepath) + postfix; + }); +}; + +/** + * Helper to return a sorted unique array of all asset files out of the + * asset object + */ +HtmlWebpackPlugin.prototype.getAssetFiles = function (assets) { + var files = _.uniq(Object.keys(assets).filter(function (assetType) { + return assetType !== 'chunks' && assets[assetType]; + }).reduce(function (files, assetType) { + return files.concat(assets[assetType]); + }, [])); + files.sort(); + return files; +}; + +/** + * Helper to promisify compilation.applyPluginsAsyncWaterfall that returns + * a function that helps to merge given plugin arguments with processed ones + */ +HtmlWebpackPlugin.prototype.applyPluginsAsyncWaterfall = function (compilation) { + var promisedApplyPluginsAsyncWaterfall = Promise.promisify(compilation.applyPluginsAsyncWaterfall, {context: compilation}); + return function (eventName, requiresResult, pluginArgs) { + return promisedApplyPluginsAsyncWaterfall(eventName, pluginArgs) + .then(function (result) { + if (requiresResult && !result) { + compilation.warnings.push(new Error('Using ' + eventName + ' without returning a result is deprecated.')); + } + return _.extend(pluginArgs, result); + }); + }; +}; + +module.exports = HtmlWebpackPlugin; diff --git a/node_modules/html-webpack-plugin/lib/chunksorter.js b/node_modules/html-webpack-plugin/lib/chunksorter.js new file mode 100644 index 000000000..584e01ccb --- /dev/null +++ b/node_modules/html-webpack-plugin/lib/chunksorter.js @@ -0,0 +1,93 @@ +'use strict'; + +var toposort = require('toposort'); +var _ = require('lodash'); + +/* + Sorts dependencies between chunks by their "parents" attribute. + + This function sorts chunks based on their dependencies with each other. + The parent relation between chunks as generated by Webpack for each chunk + is used to define a directed (and hopefully acyclic) graph, which is then + topologically sorted in order to retrieve the correct order in which + chunks need to be embedded into HTML. A directed edge in this graph is + describing a "is parent of" relationship from a chunk to another (distinct) + chunk. Thus topological sorting orders chunks from bottom-layer chunks to + highest level chunks that use the lower-level chunks. + + @param {Array} chunks an array of chunks as generated by the html-webpack-plugin. + It is assumed that each entry contains at least the properties "id" + (containing the chunk id) and "parents" (array containing the ids of the + parent chunks). + + @return {Array} A topologically sorted version of the input chunks +*/ +module.exports.dependency = function (chunks) { + if (!chunks) { + return chunks; + } + + // We build a map (chunk-id -> chunk) for faster access during graph building. + var nodeMap = {}; + + chunks.forEach(function (chunk) { + nodeMap[chunk.id] = chunk; + }); + + // Next, we add an edge for each parent relationship into the graph + var edges = []; + + chunks.forEach(function (chunk) { + if (chunk.parents) { + // Add an edge for each parent (parent -> child) + chunk.parents.forEach(function (parentId) { + // webpack2 chunk.parents are chunks instead of string id(s) + var parentChunk = _.isObject(parentId) ? parentId : nodeMap[parentId]; + // If the parent chunk does not exist (e.g. because of an excluded chunk) + // we ignore that parent + if (parentChunk) { + edges.push([parentChunk, chunk]); + } + }); + } + }); + // We now perform a topological sorting on the input chunks and built edges + return toposort.array(chunks, edges); +}; + +/** + * Sorts the chunks based on the chunk id. + * + * @param {Array} chunks the list of chunks to sort + * @return {Array} The sorted list of chunks + */ +module.exports.id = function (chunks) { + return chunks.sort(function orderEntryLast (a, b) { + if (a.entry !== b.entry) { + return b.entry ? 1 : -1; + } else { + return b.id - a.id; + } + }); +}; + +/** + * Performs identity mapping (no-sort). + * @param {Array} chunks the chunks to sort + * @return {Array} The sorted chunks + */ +module.exports.none = function (chunks) { + return chunks; +}; + +/** + * Defines the default sorter. + */ +module.exports.auto = module.exports.id; + +// In webpack 2 the ids have been flipped. +// Therefore the id sort doesn't work the same way as it did for webpack 1 +// Luckily the dependency sort is working as expected +if (require('webpack/package.json').version.split('.')[0] === '2') { + module.exports.auto = module.exports.dependency; +} diff --git a/node_modules/html-webpack-plugin/lib/compiler.js b/node_modules/html-webpack-plugin/lib/compiler.js new file mode 100644 index 000000000..9c8a22434 --- /dev/null +++ b/node_modules/html-webpack-plugin/lib/compiler.js @@ -0,0 +1,112 @@ +/* + * This file uses webpack to compile a template with a child compiler. + * + * [TEMPLATE] -> [JAVASCRIPT] + * + */ +'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'); +var LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin'); +var LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin'); +var SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin'); + +/** + * Compiles the template into a nodejs factory, adds its to the compilation.assets + * and returns a promise of the result asset object. + * + * @param template relative path to the template file + * @param context path context + * @param outputFilename the file name + * @param compilation The webpack compilation object + * + * Returns an object: + * { + * hash: {String} - Base64 hash of the file + * content: {String} - Javascript executable code of the template + * } + * + */ +module.exports.compileTemplate = function compileTemplate (template, context, outputFilename, compilation) { + // The entry file is just an empty helper as the dynamic template + // require is added in "loader.js" + var outputOptions = { + filename: outputFilename, + publicPath: compilation.outputOptions.publicPath + }; + // 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 + var compilerName = getCompilerName(context, outputFilename); + var childCompiler = compilation.createChildCompiler(compilerName, outputOptions); + childCompiler.context = context; + childCompiler.apply( + new NodeTemplatePlugin(outputOptions), + new NodeTargetPlugin(), + new LibraryTemplatePlugin('HTML_WEBPACK_PLUGIN_RESULT', 'var'), + new SingleEntryPlugin(this.context, template), + new LoaderTargetPlugin('node') + ); + + // Fix for "Uncaught TypeError: __webpack_require__(...) is not a function" + // Hot module replacement requires that every child compiler has its own + // cache. @see https://github.com/ampedandwired/html-webpack-plugin/pull/179 + childCompiler.plugin('compilation', function (compilation) { + if (compilation.cache) { + if (!compilation.cache[compilerName]) { + compilation.cache[compilerName] = {}; + } + compilation.cache = compilation.cache[compilerName]; + } + }); + + // Compile and return a promise + return new Promise(function (resolve, reject) { + childCompiler.runAsChild(function (err, entries, childCompilation) { + // Resolve / reject the promise + if (childCompilation && childCompilation.errors && childCompilation.errors.length) { + var errorDetails = childCompilation.errors.map(function (error) { + return error.message + (error.error ? ':\n' + error.error : ''); + }).join('\n'); + reject(new Error('Child compilation failed:\n' + errorDetails)); + } else if (err) { + reject(err); + } else { + // 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({ + // Hash of the template entry point + hash: entries[0].hash, + // Output name + outputName: outputName, + // Compiled code + content: childCompilation.assets[outputName].source() + }); + } + }); + }); +}; + +/** + * Returns the child compiler name e.g. 'html-webpack-plugin for "index.html"' + */ +function getCompilerName (context, filename) { + var absolutePath = path.resolve(context, filename); + var relativePath = path.relative(context, absolutePath); + return 'html-webpack-plugin for "' + (absolutePath.length < relativePath.length ? absolutePath : relativePath) + '"'; +} diff --git a/node_modules/html-webpack-plugin/lib/errors.js b/node_modules/html-webpack-plugin/lib/errors.js new file mode 100644 index 000000000..ddf3562b1 --- /dev/null +++ b/node_modules/html-webpack-plugin/lib/errors.js @@ -0,0 +1,23 @@ +'use strict'; +var PrettyError = require('pretty-error'); +var prettyError = new PrettyError(); +prettyError.withoutColors(); +prettyError.skipPackage(['html-plugin-evaluation']); +prettyError.skipNodeFiles(); +prettyError.skip(function (traceLine) { + return traceLine.path === 'html-plugin-evaluation'; +}); + +module.exports = function (err, context) { + return { + toHtml: function () { + return 'Html Webpack Plugin:\n<pre>\n' + this.toString() + '</pre>'; + }, + toJsonHtml: function () { + return JSON.stringify(this.toHtml()); + }, + toString: function () { + return prettyError.render(err).replace(/webpack:\/\/\/\./g, context); + } + }; +}; diff --git a/node_modules/html-webpack-plugin/lib/loader.js b/node_modules/html-webpack-plugin/lib/loader.js new file mode 100644 index 000000000..e1af5e513 --- /dev/null +++ b/node_modules/html-webpack-plugin/lib/loader.js @@ -0,0 +1,51 @@ +/* This loader renders the template with underscore if no other loader was found */ +'use strict'; + +var _ = require('lodash'); +var loaderUtils = require('loader-utils'); + +module.exports = function (source) { + if (this.cacheable) { + this.cacheable(); + } + var allLoadersButThisOne = this.loaders.filter(function (loader) { + // Loader API changed from `loader.module` to `loader.normal` in Webpack 2. + return (loader.module || loader.normal) !== module.exports; + }); + // This loader shouldn't kick in if there is any other loader + if (allLoadersButThisOne.length > 0) { + return source; + } + // Skip .js files + if (/\.js$/.test(this.request)) { + return source; + } + + // The following part renders the tempalte with lodash as aminimalistic loader + // + // Get templating options + var options = loaderUtils.parseQuery(this.query); + // Webpack 2 does not allow with() statements, which lodash templates use to unwrap + // the parameters passed to the compiled template inside the scope. We therefore + // need to unwrap them ourselves here. This is essentially what lodash does internally + // To tell lodash it should not use with we set a variable + var template = _.template(source, _.defaults(options, { variable: 'data' })); + // All templateVariables which should be available + // @see HtmlWebpackPlugin.prototype.executeTemplate + var templateVariables = [ + 'compilation', + 'webpack', + 'webpackConfig', + 'htmlWebpackPlugin' + ]; + return 'var _ = require(' + loaderUtils.stringifyRequest(this, require.resolve('lodash')) + ');' + + 'module.exports = function (templateParams) {' + + // Declare the template variables in the outer scope of the + // lodash template to unwrap them + templateVariables.map(function (variableName) { + return 'var ' + variableName + ' = templateParams.' + variableName; + }).join(';') + ';' + + // Execute the lodash template + 'return (' + template.source + ')();' + + '}'; +}; diff --git a/node_modules/html-webpack-plugin/node_modules/.bin/html-minifier b/node_modules/html-webpack-plugin/node_modules/.bin/html-minifier new file mode 120000 index 000000000..82bf699e6 --- /dev/null +++ b/node_modules/html-webpack-plugin/node_modules/.bin/html-minifier @@ -0,0 +1 @@ +../../../html-minifier/cli.js
\ No newline at end of file diff --git a/node_modules/html-webpack-plugin/node_modules/.bin/webpack b/node_modules/html-webpack-plugin/node_modules/.bin/webpack new file mode 120000 index 000000000..8a1900f6d --- /dev/null +++ b/node_modules/html-webpack-plugin/node_modules/.bin/webpack @@ -0,0 +1 @@ +../../../webpack/bin/webpack.js
\ No newline at end of file diff --git a/node_modules/html-webpack-plugin/package.json b/node_modules/html-webpack-plugin/package.json new file mode 100644 index 000000000..f6c5b41a5 --- /dev/null +++ b/node_modules/html-webpack-plugin/package.json @@ -0,0 +1,68 @@ +{ + "name": "html-webpack-plugin", + "version": "2.28.0", + "description": "Simplifies creation of HTML files to serve your webpack bundles", + "main": "index.js", + "files": [ + "index.js", + "default_index.ejs", + "lib/" + ], + "scripts": { + "prepublish": "npm run test", + "pretest": "semistandard", + "build-examples": "node examples/build-examples.js", + "test": "jasmine" + }, + "repository": { + "type": "git", + "url": "https://github.com/ampedandwired/html-webpack-plugin.git" + }, + "keywords": [ + "webpack", + "plugin", + "html", + "html-webpack-plugin" + ], + "author": "Charles Blaxland <charles.blaxland@gmail.com> (https://github.com/ampedandwired)", + "license": "MIT", + "bugs": { + "url": "https://github.com/ampedandwired/html-webpack-plugin/issues" + }, + "homepage": "https://github.com/ampedandwired/html-webpack-plugin", + "semistandard": { + "ignore": [ + "examples/*/dist/**/*.*" + ] + }, + "devDependencies": { + "appcache-webpack-plugin": "^1.3.0", + "css-loader": "^0.26.1", + "dir-compare": "1.3.0", + "es6-promise": "^4.0.5", + "extract-text-webpack-plugin": "^1.0.1", + "file-loader": "^0.9.0", + "html-loader": "^0.4.4", + "jade": "^1.11.0", + "jade-loader": "^0.8.0", + "jasmine": "^2.5.2", + "rimraf": "^2.5.4", + "semistandard": "8.0.0", + "style-loader": "^0.13.1", + "underscore-template-loader": "^0.7.3", + "url-loader": "^0.5.7", + "webpack": "^1.14.0", + "webpack-recompilation-simulator": "^1.3.0" + }, + "dependencies": { + "bluebird": "^3.4.7", + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "toposort": "^1.0.0" + }, + "peerDependencies": { + "webpack": "1 || ^2 || ^2.1.0-beta || ^2.2.0-rc" + } +} |