html-webpack-plugin
Advanced tools
Comparing version 5.0.0-alpha.7 to 5.0.0-alpha.8
30
index.js
@@ -18,3 +18,2 @@ // @ts-check | ||
const loaderUtils = require('loader-utils'); | ||
const webpack = require('webpack'); | ||
const { CachedChildCompilation } = require('./lib/cached-child-compiler'); | ||
@@ -83,12 +82,19 @@ | ||
// Get all filenNames to support [name] | ||
const multipleOptions = options.filename.includes('[name]') | ||
? Object.keys(compiler.options.entry).map((entryName) => ({ | ||
...options, | ||
filename: options.filename.replace(/\[name\]/g, entryName) | ||
})) | ||
: [options]; | ||
// entryName to fileName conversion | ||
const filenameFunction = typeof options.filename === 'function' | ||
? options.filename | ||
// Replace '[name]' with entry name | ||
: (entryName) => options.filename.replace(/\[name\]/g, entryName); | ||
/** output filenames for the given entry names */ | ||
const outputFileNames = new Set(Object.keys(compiler.options.entry).map(filenameFunction)); | ||
/** Option for every entry point */ | ||
const entryOptions = Array.from(outputFileNames).map((filename) => ({ | ||
...options, | ||
filename | ||
})); | ||
// Hook all options into the webpack compiler | ||
multipleOptions.forEach((instanceOptions) => { | ||
entryOptions.forEach((instanceOptions) => { | ||
hookIntoCompiler(compiler, instanceOptions, this); | ||
@@ -138,3 +144,3 @@ }); | ||
* apply is called by the webpack main compiler during the start phase | ||
* @param {WebpackCompiler} compiler | ||
* @param {import('webpack').Compiler} compiler | ||
* @param {ProcessedHtmlWebpackOptions} options | ||
@@ -144,2 +150,3 @@ * @param {HtmlWebpackPlugin} plugin | ||
function hookIntoCompiler (compiler, options, plugin) { | ||
const webpack = compiler.webpack; | ||
// Instance variables to keep caching information | ||
@@ -161,3 +168,4 @@ // for multiple builds | ||
if (path.resolve(filename) === path.normalize(filename)) { | ||
options.filename = path.relative(compiler.options.output.path, filename); | ||
const outputPath = /** @type {string} - Once initialized the path is always a string */(compiler.options.output.path); | ||
options.filename = path.relative(outputPath, filename); | ||
} | ||
@@ -164,0 +172,0 @@ |
@@ -17,5 +17,3 @@ // @ts-check | ||
const LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin'); | ||
const LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin'); | ||
const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin'); | ||
const Compilation = require('webpack').Compilation; | ||
@@ -78,6 +76,9 @@ let instanceId = 0; | ||
* | ||
* @param {WebpackCompilation} mainCompilation | ||
* @param {import('Webpack').Compilation} mainCompilation | ||
* @returns {Promise<{[templatePath: string]: { content: string, hash: string, entry: WebpackChunk }}>} | ||
*/ | ||
compileTemplates (mainCompilation) { | ||
const webpack = mainCompilation.compiler.webpack; | ||
const Compilation = webpack.Compilation; | ||
// To prevent multiple compilations for the same template | ||
@@ -90,7 +91,12 @@ // the compilation is cached in a promise. | ||
// The entry file is just an empty helper as the dynamic template | ||
// require is added in "loader.js" | ||
const outputOptions = { | ||
filename: '__child-[name]', | ||
publicPath: mainCompilation.outputOptions.publicPath | ||
publicPath: mainCompilation.outputOptions.publicPath, | ||
library: { | ||
type: 'var', | ||
name: 'HTML_WEBPACK_PLUGIN_RESULT' | ||
}, | ||
/** @type {'text/javascript'} */ | ||
scriptType: (/** @type {'text/javascript'} */'text/javascript'), | ||
iife: false | ||
}; | ||
@@ -101,10 +107,10 @@ const compilerName = 'HtmlWebpackCompiler'; | ||
// This allows us to use loaders during the compilation | ||
const childCompiler = mainCompilation.createChildCompiler(compilerName, outputOptions); | ||
const childCompiler = mainCompilation.createChildCompiler(compilerName, outputOptions, [ | ||
// Compile the template to nodejs javascript | ||
new NodeTemplatePlugin(outputOptions), | ||
new NodeTargetPlugin(), | ||
new LoaderTargetPlugin('node') | ||
]); | ||
// The file path context which webpack uses to resolve all relative files to | ||
childCompiler.context = mainCompilation.compiler.context; | ||
// Compile the template to nodejs javascript | ||
new NodeTemplatePlugin(outputOptions).apply(childCompiler); | ||
new NodeTargetPlugin().apply(childCompiler); | ||
new LibraryTemplatePlugin('HTML_WEBPACK_PLUGIN_RESULT', 'var').apply(childCompiler); | ||
new LoaderTargetPlugin('node').apply(childCompiler); | ||
@@ -145,3 +151,3 @@ // Generate output file names | ||
// Extract file dependencies | ||
if (entries) { | ||
if (entries && childCompilation) { | ||
this.fileDependencies = { fileDependencies: Array.from(childCompilation.fileDependencies), contextDependencies: Array.from(childCompilation.contextDependencies), missingDependencies: Array.from(childCompilation.missingDependencies) }; | ||
@@ -153,3 +159,3 @@ } | ||
let message = error.message; | ||
if (error.error) { | ||
if ('error' in error) { | ||
message += ':\n' + error.error; | ||
@@ -170,2 +176,6 @@ } | ||
} | ||
if (!childCompilation || !entries) { | ||
reject(new Error('Empty child compilation')); | ||
return; | ||
} | ||
/** | ||
@@ -172,0 +182,0 @@ * @type {{[templatePath: string]: { content: string, hash: string, entry: WebpackChunk }}} |
{ | ||
"name": "html-webpack-plugin", | ||
"version": "5.0.0-alpha.7", | ||
"version": "5.0.0-alpha.8", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "description": "Simplifies creation of HTML files to serve your webpack bundles", |
@@ -136,3 +136,3 @@ [![npm][npm]][npm-url] | ||
|**`title`**|`{String}`|`Webpack App`|The title to use for the generated HTML document| | ||
|**`filename`**|`{String}`|`'index.html'`|The file to write the HTML to. Defaults to `index.html`. You can specify a subdirectory here too (eg: `assets/admin.html`)| | ||
|**`filename`**|`{String\|Function}`|`'index.html'`|The file to write the HTML to. Defaults to `index.html`. You can specify a subdirectory here too (eg: `assets/admin.html`). The `[name]` placeholder will be replaced with the entry name. Can also be a function e.g. `(entryName) => entryName + '.html'`. | | ||
|**`template`**|`{String}`|``|`webpack` relative or absolute path to the template. By default it will use `src/index.ejs` if it exists. Please see the [docs](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md) for details| | ||
@@ -139,0 +139,0 @@ |**`templateContent`**|`{string\|Function\|false}`|false| Can be used instead of `template` to provide an inline template - please read the [Writing Your Own Templates](https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates) section | |
@@ -28,5 +28,14 @@ import { AsyncSeriesWaterfallHook } from "tapable"; | ||
type MinifyOptions = HtmlMinifierOptions; | ||
/** | ||
* The file to write the HTML to. | ||
* Supports subdirectories eg: `assets/admin.html` | ||
* [name] will be replaced by the entry name | ||
* Supports a function to generate the name | ||
* | ||
* @default 'index.html' | ||
*/ | ||
interface Options extends Partial<ProcessedOptions> { | ||
filename: string | ((entryName: string) => string); | ||
} | ||
interface Options extends Partial<ProcessedOptions> {} | ||
/** | ||
@@ -64,5 +73,8 @@ * The plugin options after adding default values | ||
* Supports subdirectories eg: `assets/admin.html` | ||
* [name] will be replaced by the entry name | ||
* Supports a function to generate the name | ||
* | ||
* @default 'index.html' | ||
*/ | ||
filename: string; | ||
filename: string | ||
/** | ||
@@ -69,0 +81,0 @@ * By default the public path is set to `auto` - that way the html-webpack-plugin will try |
141391
2135