Skip to content

Commit f77d06a

Browse files
committed
fix: use webpack sources of the current webpack compiler instance
1 parent c5beb4b commit f77d06a

File tree

3 files changed

+40
-20
lines changed

3 files changed

+40
-20
lines changed

index.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ const fs = require('fs');
1515
const _ = require('lodash');
1616
const path = require('path');
1717
const loaderUtils = require('loader-utils');
18-
const webpack = require('webpack');
1918
const { CachedChildCompilation } = require('./lib/cached-child-compiler');
2019

2120
const { createHtmlTagObject, htmlTagObjectToString, HtmlTagArray } = require('./lib/html-tags');
@@ -145,11 +144,12 @@ class HtmlWebpackPlugin {
145144

146145
/**
147146
* apply is called by the webpack main compiler during the start phase
148-
* @param {WebpackCompiler} compiler
147+
* @param {import('webpack').Compiler} compiler
149148
* @param {ProcessedHtmlWebpackOptions} options
150149
* @param {HtmlWebpackPlugin} plugin
151150
*/
152151
function hookIntoCompiler (compiler, options, plugin) {
152+
const webpack = compiler.webpack;
153153
// Instance variables to keep caching information
154154
// for multiple builds
155155
let assetJson;
@@ -166,7 +166,8 @@ function hookIntoCompiler (compiler, options, plugin) {
166166
// generate it at correct location
167167
const filename = options.filename;
168168
if (path.resolve(filename) === path.normalize(filename)) {
169-
options.filename = path.relative(compiler.options.output.path, filename);
169+
const outputPath = /** @type {string} - Once initialized the path is always a string */(compiler.options.output.path);
170+
options.filename = path.relative(outputPath, filename);
170171
}
171172

172173
// `contenthash` is introduced in webpack v4.3

lib/child-compiler.js

+24-14
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
const NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
1515
const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
1616
const LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin');
17-
const LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin');
1817
const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
19-
const Compilation = require('webpack').Compilation;
2018

2119
let instanceId = 0;
2220
/**
@@ -74,35 +72,43 @@ class HtmlWebpackChildCompiler {
7472
* This function will start the template compilation
7573
* once it is started no more templates can be added
7674
*
77-
* @param {WebpackCompilation} mainCompilation
75+
* @param {import('Webpack').Compilation} mainCompilation
7876
* @returns {Promise<{[templatePath: string]: { content: string, hash: string, entry: WebpackChunk }}>}
7977
*/
8078
compileTemplates (mainCompilation) {
79+
const webpack = mainCompilation.compiler.webpack;
80+
const Compilation = webpack.Compilation;
81+
8182
// To prevent multiple compilations for the same template
8283
// the compilation is cached in a promise.
8384
// If it already exists return
8485
if (this.compilationPromise) {
8586
return this.compilationPromise;
8687
}
8788

88-
// The entry file is just an empty helper as the dynamic template
89-
// require is added in "loader.js"
9089
const outputOptions = {
9190
filename: '__child-[name]',
92-
publicPath: mainCompilation.outputOptions.publicPath
91+
publicPath: mainCompilation.outputOptions.publicPath,
92+
library: {
93+
type: 'var',
94+
name: 'HTML_WEBPACK_PLUGIN_RESULT'
95+
},
96+
/** @type {'text/javascript'} */
97+
scriptType: (/** @type {'text/javascript'} */'text/javascript'),
98+
iife: false
9399
};
94100
const compilerName = 'HtmlWebpackCompiler';
95101
// Create an additional child compiler which takes the template
96102
// and turns it into an Node.JS html factory.
97103
// This allows us to use loaders during the compilation
98-
const childCompiler = mainCompilation.createChildCompiler(compilerName, outputOptions);
104+
const childCompiler = mainCompilation.createChildCompiler(compilerName, outputOptions, [
105+
// Compile the template to nodejs javascript
106+
new NodeTemplatePlugin(outputOptions),
107+
new NodeTargetPlugin(),
108+
new LoaderTargetPlugin('node')
109+
]);
99110
// The file path context which webpack uses to resolve all relative files to
100111
childCompiler.context = mainCompilation.compiler.context;
101-
// Compile the template to nodejs javascript
102-
new NodeTemplatePlugin(outputOptions).apply(childCompiler);
103-
new NodeTargetPlugin().apply(childCompiler);
104-
new LibraryTemplatePlugin('HTML_WEBPACK_PLUGIN_RESULT', 'var').apply(childCompiler);
105-
new LoaderTargetPlugin('node').apply(childCompiler);
106112

107113
// Generate output file names
108114
const temporaryTemplateNames = this.templates.map((template, index) => `__child-HtmlWebpackPlugin_${index}-${this.id}`);
@@ -138,14 +144,14 @@ class HtmlWebpackChildCompiler {
138144
? extractedAssets.map((asset) => asset.source())
139145
: [];
140146
// Extract file dependencies
141-
if (entries) {
147+
if (entries && childCompilation) {
142148
this.fileDependencies = { fileDependencies: Array.from(childCompilation.fileDependencies), contextDependencies: Array.from(childCompilation.contextDependencies), missingDependencies: Array.from(childCompilation.missingDependencies) };
143149
}
144150
// Reject the promise if the childCompilation contains error
145151
if (childCompilation && childCompilation.errors && childCompilation.errors.length) {
146152
const errorDetails = childCompilation.errors.map(error => {
147153
let message = error.message;
148-
if (error.error) {
154+
if ('error' in error) {
149155
message += ':\n' + error.error;
150156
}
151157
if (error.stack) {
@@ -161,6 +167,10 @@ class HtmlWebpackChildCompiler {
161167
reject(err);
162168
return;
163169
}
170+
if (!childCompilation || !entries) {
171+
reject(new Error('Empty child compilation'));
172+
return;
173+
}
164174
/**
165175
* @type {{[templatePath: string]: { content: string, hash: string, entry: WebpackChunk }}}
166176
*/

typings.d.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,17 @@ declare class HtmlWebpackPlugin {
2525

2626
declare namespace HtmlWebpackPlugin {
2727
type MinifyOptions = HtmlMinifierOptions;
28-
29-
interface Options extends Partial<ProcessedOptions> {}
28+
/**
29+
* The file to write the HTML to.
30+
* Supports subdirectories eg: `assets/admin.html`
31+
* [name] will be replaced by the entry name
32+
* Supports a function to generate the name
33+
*
34+
* @default 'index.html'
35+
*/
36+
interface Options extends Partial<ProcessedOptions> {
37+
filename: string | ((entryName: string) => string);
38+
}
3039

3140
/**
3241
* The plugin options after adding default values
@@ -65,7 +74,7 @@ declare namespace HtmlWebpackPlugin {
6574
*
6675
* @default 'index.html'
6776
*/
68-
filename: string | ((entryName: string) => string);
77+
filename: string
6978
/**
7079
* By default the public path is set to `auto` - that way the html-webpack-plugin will try
7180
* to set the publicPath according to the current filename and the webpack publicPath setting

0 commit comments

Comments
 (0)