html-webpack-plugin 5.5.3 → 5.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,41 +21,40 @@
21
21
  });
22
22
  * ```
23
23
  */
24
+ 'use strict';
24
25
 
25
26
  // Import types
26
- /** @typedef {import("webpack/lib/Compiler.js")} WebpackCompiler */
27
- /** @typedef {import("webpack/lib/Compilation.js")} WebpackCompilation */
28
- /** @typedef {{hash: string, entry: any, content: string }} ChildCompilationResultEntry */
29
- /** @typedef {import("./file-watcher-api").Snapshot} Snapshot */
27
+ /** @typedef {import("webpack").Compiler} Compiler */
28
+ /** @typedef {import("webpack").Compilation} Compilation */
29
+ /** @typedef {import("webpack/lib/FileSystemInfo").Snapshot} Snapshot */
30
+ /** @typedef {import("./child-compiler").ChildCompilationTemplateResult} ChildCompilationTemplateResult */
30
31
  /** @typedef {{fileDependencies: string[], contextDependencies: string[], missingDependencies: string[]}} FileDependencies */
31
32
  /** @typedef {{
32
33
  dependencies: FileDependencies,
33
- compiledEntries: {[entryName: string]: ChildCompilationResultEntry}
34
+ compiledEntries: {[entryName: string]: ChildCompilationTemplateResult}
34
35
  } | {
35
36
  dependencies: FileDependencies,
36
37
  error: Error
37
38
  }} ChildCompilationResult */
38
- 'use strict';
39
39
 
40
40
  const { HtmlWebpackChildCompiler } = require('./child-compiler');
41
- const fileWatcherApi = require('./file-watcher-api');
42
41
 
43
42
  /**
44
43
  * This plugin is a singleton for performance reasons.
45
44
  * To keep track if a plugin does already exist for the compiler they are cached
46
45
  * in this map
47
- * @type {WeakMap<WebpackCompiler, PersistentChildCompilerSingletonPlugin>}}
46
+ * @type {WeakMap<Compiler, PersistentChildCompilerSingletonPlugin>}}
48
47
  */
49
48
  const compilerMap = new WeakMap();
50
49
 
51
50
  class CachedChildCompilation {
52
51
  /**
53
- * @param {WebpackCompiler} compiler
52
+ * @param {Compiler} compiler
54
53
  */
55
54
  constructor (compiler) {
56
55
  /**
57
56
  * @private
58
- * @type {WebpackCompiler}
57
+ * @type {Compiler}
59
58
  */
60
59
  this.compiler = compiler;
61
60
  // Create a singleton instance for the compiler
@@ -97,7 +96,7 @@ class CachedChildCompilation {
97
96
  * @param {string} entry
98
97
  * @returns {
99
98
  | { mainCompilationHash: string, error: Error }
100
- | { mainCompilationHash: string, compiledEntry: ChildCompilationResultEntry }
99
+ | { mainCompilationHash: string, compiledEntry: ChildCompilationTemplateResult }
101
100
  }
102
101
  */
103
102
  getCompilationEntryResult (entry) {
@@ -114,6 +113,61 @@ class CachedChildCompilation {
114
113
  }
115
114
 
116
115
  class PersistentChildCompilerSingletonPlugin {
116
+ /**
117
+ *
118
+ * @param {{fileDependencies: string[], contextDependencies: string[], missingDependencies: string[]}} fileDependencies
119
+ * @param {Compilation} mainCompilation
120
+ * @param {number} startTime
121
+ */
122
+ static createSnapshot (fileDependencies, mainCompilation, startTime) {
123
+ return new Promise((resolve, reject) => {
124
+ mainCompilation.fileSystemInfo.createSnapshot(
125
+ startTime,
126
+ fileDependencies.fileDependencies,
127
+ fileDependencies.contextDependencies,
128
+ fileDependencies.missingDependencies,
129
+ // @ts-ignore
130
+ null,
131
+ (err, snapshot) => {
132
+ if (err) {
133
+ return reject(err);
134
+ }
135
+ resolve(snapshot);
136
+ }
137
+ );
138
+ });
139
+ }
140
+
141
+ /**
142
+ * Returns true if the files inside this snapshot
143
+ * have not been changed
144
+ *
145
+ * @param {Snapshot} snapshot
146
+ * @param {Compilation} mainCompilation
147
+ * @returns {Promise<boolean | undefined>}
148
+ */
149
+ static isSnapshotValid (snapshot, mainCompilation) {
150
+ return new Promise((resolve, reject) => {
151
+ mainCompilation.fileSystemInfo.checkSnapshotValid(
152
+ snapshot,
153
+ (err, isValid) => {
154
+ if (err) {
155
+ reject(err);
156
+ }
157
+ resolve(isValid);
158
+ }
159
+ );
160
+ });
161
+ }
162
+
163
+ static watchFiles (mainCompilation, fileDependencies) {
164
+ Object.keys(fileDependencies).forEach((depencyTypes) => {
165
+ fileDependencies[depencyTypes].forEach(fileDependency => {
166
+ mainCompilation[depencyTypes].add(fileDependency);
167
+ });
168
+ });
169
+ }
170
+
117
171
  constructor () {
118
172
  /**
119
173
  * @private
@@ -158,7 +212,7 @@ class PersistentChildCompilerSingletonPlugin {
158
212
 
159
213
  /**
160
214
  * apply is called by the webpack main compiler during the start phase
161
- * @param {WebpackCompiler} compiler
215
+ * @param {Compiler} compiler
162
216
  */
163
217
  apply (compiler) {
164
218
  /** @type Promise<ChildCompilationResult> */
@@ -174,8 +228,9 @@ class PersistentChildCompilerSingletonPlugin {
174
228
  * The main compilation hash which will only be updated
175
229
  * if the childCompiler changes
176
230
  */
231
+ /** @type {string} */
177
232
  let mainCompilationHashOfLastChildRecompile = '';
178
- /** @typedef{Snapshot|undefined} */
233
+ /** @type {Snapshot | undefined} */
179
234
  let previousFileSystemSnapshot;
180
235
  let compilationStartTime = new Date().getTime();
181
236
 
@@ -216,7 +271,7 @@ class PersistentChildCompilerSingletonPlugin {
216
271
  // this might possibly cause bugs if files were changed inbetween
217
272
  // compilation start and snapshot creation
218
273
  compiledEntriesPromise.then((childCompilationResult) => {
219
- return fileWatcherApi.createSnapshot(childCompilationResult.dependencies, mainCompilation, compilationStartTime);
274
+ return PersistentChildCompilerSingletonPlugin.createSnapshot(childCompilationResult.dependencies, mainCompilation, compilationStartTime);
220
275
  }).then((snapshot) => {
221
276
  previousFileSystemSnapshot = snapshot;
222
277
  });
@@ -234,6 +289,7 @@ class PersistentChildCompilerSingletonPlugin {
234
289
  childCompilationResult.dependencies
235
290
  );
236
291
  });
292
+ // @ts-ignore
237
293
  handleCompilationDonePromise.then(() => callback(null, chunks, modules), callback);
238
294
  }
239
295
  );
@@ -253,7 +309,7 @@ class PersistentChildCompilerSingletonPlugin {
253
309
  ([childCompilationResult, didRecompile]) => {
254
310
  // Update hash and snapshot if childCompilation changed
255
311
  if (didRecompile) {
256
- mainCompilationHashOfLastChildRecompile = mainCompilation.hash;
312
+ mainCompilationHashOfLastChildRecompile = /** @type {string} */ (mainCompilation.hash);
257
313
  }
258
314
  this.compilationState = {
259
315
  isCompiling: false,
@@ -309,8 +365,8 @@ class PersistentChildCompilerSingletonPlugin {
309
365
  * Verify that the cache is still valid
310
366
  * @private
311
367
  * @param {Snapshot | undefined} snapshot
312
- * @param {WebpackCompilation} mainCompilation
313
- * @returns {Promise<boolean>}
368
+ * @param {Compilation} mainCompilation
369
+ * @returns {Promise<boolean | undefined>}
314
370
  */
315
371
  isCacheValid (snapshot, mainCompilation) {
316
372
  if (!this.compilationState.isVerifyingCache) {
@@ -328,14 +384,15 @@ class PersistentChildCompilerSingletonPlugin {
328
384
  if (!snapshot) {
329
385
  return Promise.resolve(false);
330
386
  }
331
- return fileWatcherApi.isSnapShotValid(snapshot, mainCompilation);
387
+
388
+ return PersistentChildCompilerSingletonPlugin.isSnapshotValid(snapshot, mainCompilation);
332
389
  }
333
390
 
334
391
  /**
335
392
  * Start to compile all templates
336
393
  *
337
394
  * @private
338
- * @param {WebpackCompilation} mainCompilation
395
+ * @param {Compilation} mainCompilation
339
396
  * @param {string[]} entries
340
397
  * @returns {Promise<ChildCompilationResult>}
341
398
  */
@@ -366,11 +423,11 @@ class PersistentChildCompilerSingletonPlugin {
366
423
 
367
424
  /**
368
425
  * @private
369
- * @param {WebpackCompilation} mainCompilation
426
+ * @param {Compilation} mainCompilation
370
427
  * @param {FileDependencies} files
371
428
  */
372
429
  watchFiles (mainCompilation, files) {
373
- fileWatcherApi.watchFiles(mainCompilation, files);
430
+ PersistentChildCompilerSingletonPlugin.watchFiles(mainCompilation, files);
374
431
  }
375
432
  }
376
433
 
@@ -1,7 +1,4 @@
1
1
  // @ts-check
2
- /** @typedef {import("webpack/lib/Compilation.js")} WebpackCompilation */
3
- /** @typedef {import("webpack/lib/Compiler.js")} WebpackCompiler */
4
- /** @typedef {import("webpack/lib/Chunk.js")} WebpackChunk */
5
2
  'use strict';
6
3
 
7
4
  /**
@@ -12,6 +9,10 @@
12
9
  *
13
10
  */
14
11
 
12
+ /** @typedef {import("webpack").Chunk} Chunk */
13
+ /** @typedef {import("webpack").sources.Source} Source */
14
+ /** @typedef {{hash: string, entry: Chunk, content: string, assets: {[name: string]: { source: Source, info: import("webpack").AssetInfo }}}} ChildCompilationTemplateResult */
15
+
15
16
  let instanceId = 0;
16
17
  /**
17
18
  * The HtmlWebpackChildCompiler is a helper to allow reusing one childCompiler
@@ -30,17 +31,11 @@ class HtmlWebpackChildCompiler {
30
31
  * The template array will allow us to keep track which input generated which output
31
32
  */
32
33
  this.templates = templates;
33
- /**
34
- * @type {Promise<{[templatePath: string]: { content: string, hash: string, entry: WebpackChunk }}>}
35
- */
34
+ /** @type {Promise<{[templatePath: string]: ChildCompilationTemplateResult}>} */
36
35
  this.compilationPromise; // eslint-disable-line
37
- /**
38
- * @type {number}
39
- */
36
+ /** @type {number | undefined} */
40
37
  this.compilationStartedTimestamp; // eslint-disable-line
41
- /**
42
- * @type {number}
43
- */
38
+ /** @type {number | undefined} */
44
39
  this.compilationEndedTimestamp; // eslint-disable-line
45
40
  /**
46
41
  * All file dependencies of the child compiler
@@ -51,6 +46,7 @@ class HtmlWebpackChildCompiler {
51
46
 
52
47
  /**
53
48
  * Returns true if the childCompiler is currently compiling
49
+ *
54
50
  * @returns {boolean}
55
51
  */
56
52
  isCompiling () {
@@ -59,6 +55,8 @@ class HtmlWebpackChildCompiler {
59
55
 
60
56
  /**
61
57
  * Returns true if the childCompiler is done compiling
58
+ *
59
+ * @returns {boolean}
62
60
  */
63
61
  didCompile () {
64
62
  return this.compilationEndedTimestamp !== undefined;
@@ -69,7 +67,7 @@ class HtmlWebpackChildCompiler {
69
67
  * once it is started no more templates can be added
70
68
  *
71
69
  * @param {import('webpack').Compilation} mainCompilation
72
- * @returns {Promise<{[templatePath: string]: { content: string, hash: string, entry: WebpackChunk }}>}
70
+ * @returns {Promise<{[templatePath: string]: ChildCompilationTemplateResult}>}
73
71
  */
74
72
  compileTemplates (mainCompilation) {
75
73
  const webpack = mainCompilation.compiler.webpack;
@@ -125,12 +123,17 @@ class HtmlWebpackChildCompiler {
125
123
  // The following config enables relative URL support for the child compiler
126
124
  childCompiler.options.module = { ...childCompiler.options.module };
127
125
  childCompiler.options.module.parser = { ...childCompiler.options.module.parser };
128
- childCompiler.options.module.parser.javascript = { ...childCompiler.options.module.parser.javascript,
129
- url: 'relative' };
126
+ childCompiler.options.module.parser.javascript = {
127
+ ...childCompiler.options.module.parser.javascript,
128
+ url: 'relative'
129
+ };
130
130
 
131
131
  this.compilationStartedTimestamp = new Date().getTime();
132
+ /** @type {Promise<{[templatePath: string]: ChildCompilationTemplateResult}>} */
132
133
  this.compilationPromise = new Promise((resolve, reject) => {
134
+ /** @type {Source[]} */
133
135
  const extractedAssets = [];
136
+
134
137
  childCompiler.hooks.thisCompilation.tap('HtmlWebpackPlugin', (compilation) => {
135
138
  compilation.hooks.processAssets.tap(
136
139
  {
@@ -141,6 +144,7 @@ class HtmlWebpackChildCompiler {
141
144
  temporaryTemplateNames.forEach((temporaryTemplateName) => {
142
145
  if (assets[temporaryTemplateName]) {
143
146
  extractedAssets.push(assets[temporaryTemplateName]);
147
+
144
148
  compilation.deleteAsset(temporaryTemplateName);
145
149
  }
146
150
  });
@@ -150,13 +154,16 @@ class HtmlWebpackChildCompiler {
150
154
 
151
155
  childCompiler.runAsChild((err, entries, childCompilation) => {
152
156
  // Extract templates
157
+ // TODO fine a better way to store entries and results, to avoid duplicate chunks and assets
153
158
  const compiledTemplates = entries
154
159
  ? extractedAssets.map((asset) => asset.source())
155
160
  : [];
161
+
156
162
  // Extract file dependencies
157
163
  if (entries && childCompilation) {
158
164
  this.fileDependencies = { fileDependencies: Array.from(childCompilation.fileDependencies), contextDependencies: Array.from(childCompilation.contextDependencies), missingDependencies: Array.from(childCompilation.missingDependencies) };
159
165
  }
166
+
160
167
  // Reject the promise if the childCompilation contains error
161
168
  if (childCompilation && childCompilation.errors && childCompilation.errors.length) {
162
169
  const errorDetails = childCompilation.errors.map(error => {
@@ -166,33 +173,50 @@ class HtmlWebpackChildCompiler {
166
173
  }
167
174
  return message;
168
175
  }).join('\n');
176
+
169
177
  reject(new Error('Child compilation failed:\n' + errorDetails));
178
+
170
179
  return;
171
180
  }
181
+
172
182
  // Reject if the error object contains errors
173
183
  if (err) {
174
184
  reject(err);
175
185
  return;
176
186
  }
187
+
177
188
  if (!childCompilation || !entries) {
178
189
  reject(new Error('Empty child compilation'));
179
190
  return;
180
191
  }
192
+
181
193
  /**
182
- * @type {{[templatePath: string]: { content: string, hash: string, entry: WebpackChunk }}}
194
+ * @type {{[templatePath: string]: ChildCompilationTemplateResult}}
183
195
  */
184
196
  const result = {};
197
+
198
+ /** @type {{[name: string]: { source: Source, info: import("webpack").AssetInfo }}} */
199
+ const assets = {};
200
+
201
+ for (const asset of childCompilation.getAssets()) {
202
+ assets[asset.name] = { source: asset.source, info: asset.info };
203
+ }
204
+
185
205
  compiledTemplates.forEach((templateSource, entryIndex) => {
186
206
  // The compiledTemplates are generated from the entries added in
187
207
  // the addTemplate function.
188
- // Therefore the array index of this.templates should be the as entryIndex.
208
+ // Therefore, the array index of this.templates should be the as entryIndex.
189
209
  result[this.templates[entryIndex]] = {
190
- content: templateSource,
210
+ // TODO, can we have Buffer here?
211
+ content: /** @type {string} */ (templateSource),
191
212
  hash: childCompilation.hash || 'XXXX',
192
- entry: entries[entryIndex]
213
+ entry: entries[entryIndex],
214
+ assets
193
215
  };
194
216
  });
217
+
195
218
  this.compilationEndedTimestamp = new Date().getTime();
219
+
196
220
  resolve(result);
197
221
  });
198
222
  });
@@ -1,25 +1,26 @@
1
1
  // @ts-check
2
- /** @typedef {import("webpack/lib/Compilation.js")} WebpackCompilation */
3
2
  'use strict';
4
3
 
4
+ /** @typedef {import("webpack").Compilation} Compilation */
5
+
5
6
  /**
6
- * @type {{[sortmode: string] : (entryPointNames: Array<string>, compilation, htmlWebpackPluginOptions) => Array<string> }}
7
+ * @type {{[sortmode: string] : (entryPointNames: Array<string>, compilation: Compilation, htmlWebpackPluginOptions: any) => Array<string> }}
7
8
  * This file contains different sort methods for the entry chunks names
8
9
  */
9
10
  module.exports = {};
10
11
 
11
12
  /**
12
13
  * Performs identity mapping (no-sort).
13
- * @param {Array} chunks the chunks to sort
14
- * @return {Array} The sorted chunks
14
+ * @param {Array<string>} chunks the chunks to sort
15
+ * @return {Array<string>} The sorted chunks
15
16
  */
16
17
  module.exports.none = chunks => chunks;
17
18
 
18
19
  /**
19
20
  * Sort manually by the chunks
20
- * @param {string[]} entryPointNames the chunks to sort
21
- * @param {WebpackCompilation} compilation the webpack compilation
22
- * @param htmlWebpackPluginOptions the plugin options
21
+ * @param {string[]} entryPointNames the chunks to sort
22
+ * @param {Compilation} compilation the webpack compilation
23
+ * @param {any} htmlWebpackPluginOptions the plugin options
23
24
  * @return {string[]} The sorted chunks
24
25
  */
25
26
  module.exports.manual = (entryPointNames, compilation, htmlWebpackPluginOptions) => {
package/lib/hooks.js CHANGED
@@ -1,12 +1,12 @@
1
1
  // @ts-check
2
- /** @typedef {import("../typings").Hooks} HtmlWebpackPluginHooks */
3
2
  'use strict';
4
3
  /**
5
4
  * This file provides access to all public htmlWebpackPlugin hooks
6
5
  */
7
6
 
8
- /** @typedef {import("webpack/lib/Compilation.js")} WebpackCompilation */
7
+ /** @typedef {import("webpack").Compilation} WebpackCompilation */
9
8
  /** @typedef {import("../index.js")} HtmlWebpackPlugin */
9
+ /** @typedef {import("../typings").Hooks} HtmlWebpackPluginHooks */
10
10
 
11
11
  const AsyncSeriesWaterfallHook = require('tapable').AsyncSeriesWaterfallHook;
12
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "html-webpack-plugin",
3
- "version": "5.5.3",
3
+ "version": "5.5.4",
4
4
  "license": "MIT",
5
5
  "description": "Simplifies creation of HTML files to serve your webpack bundles",
6
6
  "author": "Jan Nicklas <j.nicklas@me.com> (https://github.com/jantimon)",
package/typings.d.ts CHANGED
@@ -143,7 +143,7 @@ declare namespace HtmlWebpackPlugin {
143
143
  templateParameters?:
144
144
  | false // Pass an empty object to the template function
145
145
  | ((
146
- compilation: any,
146
+ compilation: Compilation,
147
147
  assets: {
148
148
  publicPath: string;
149
149
  js: Array<string>;
@@ -186,7 +186,7 @@ declare namespace HtmlWebpackPlugin {
186
186
  * Please keep in mind that the `templateParameter` options allows to change them
187
187
  */
188
188
  interface TemplateParameter {
189
- compilation: any;
189
+ compilation: Compilation;
190
190
  htmlWebpackPlugin: {
191
191
  tags: {
192
192
  headTags: HtmlTagObject[];
@@ -1,71 +0,0 @@
1
- // @ts-check
2
- /** @typedef {import("webpack/lib/Compilation.js")} WebpackCompilation */
3
- /** @typedef {import("webpack/lib/FileSystemInfo").Snapshot} Snapshot */
4
- 'use strict';
5
-
6
- /**
7
- *
8
- * @param {{fileDependencies: string[], contextDependencies: string[], missingDependencies: string[]}} fileDependencies
9
- * @param {WebpackCompilation} mainCompilation
10
- * @param {number} startTime
11
- */
12
- function createSnapshot (fileDependencies, mainCompilation, startTime) {
13
- return new Promise((resolve, reject) => {
14
- mainCompilation.fileSystemInfo.createSnapshot(
15
- startTime,
16
- fileDependencies.fileDependencies,
17
- fileDependencies.contextDependencies,
18
- fileDependencies.missingDependencies,
19
- null,
20
- (err, snapshot) => {
21
- if (err) {
22
- return reject(err);
23
- }
24
- resolve(snapshot);
25
- }
26
- );
27
- });
28
- }
29
-
30
- /**
31
- * Returns true if the files inside this snapshot
32
- * have not been changed
33
- *
34
- * @param {Snapshot} snapshot
35
- * @param {WebpackCompilation} mainCompilation
36
- * @returns {Promise<boolean>}
37
- */
38
- function isSnapShotValid (snapshot, mainCompilation) {
39
- return new Promise((resolve, reject) => {
40
- mainCompilation.fileSystemInfo.checkSnapshotValid(
41
- snapshot,
42
- (err, isValid) => {
43
- if (err) {
44
- reject(err);
45
- }
46
- resolve(isValid);
47
- }
48
- );
49
- });
50
- }
51
-
52
- /**
53
- * Ensure that the files keep watched for changes
54
- * and will trigger a recompile
55
- *
56
- * @param {WebpackCompilation} mainCompilation
57
- * @param {{fileDependencies: string[], contextDependencies: string[], missingDependencies: string[]}} fileDependencies
58
- */
59
- function watchFiles (mainCompilation, fileDependencies) {
60
- Object.keys(fileDependencies).forEach((depencyTypes) => {
61
- fileDependencies[depencyTypes].forEach(fileDependency => {
62
- mainCompilation[depencyTypes].add(fileDependency);
63
- });
64
- });
65
- }
66
-
67
- module.exports = {
68
- createSnapshot,
69
- isSnapShotValid,
70
- watchFiles
71
- };