html-webpack-plugin 4.0.2 → 4.2.0

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.
@@ -0,0 +1,71 @@
1
+ /** @typedef {import("webpack/lib/Compilation.js")} WebpackCompilation */
2
+ /** @typedef {import("webpack/lib/FileSystemInfo").Snapshot} Snapshot */
3
+ 'use strict';
4
+
5
+ /**
6
+ *
7
+ * @param {{fileDependencies: string[], contextDependencies: string[], missingDependencies: string[]}} fileDependencies
8
+ * @param {WebpackCompilation} mainCompilation
9
+ * @param {number} startTime
10
+ */
11
+ function createSnapshot (fileDependencies, mainCompilation, startTime) {
12
+ return new Promise((resolve, reject) => {
13
+ mainCompilation.fileSystemInfo.createSnapshot(
14
+ startTime,
15
+ fileDependencies.fileDependencies,
16
+ fileDependencies.contextDependencies,
17
+ fileDependencies.missingDependencies,
18
+ null,
19
+ (err, snapshot) => {
20
+ if (err) {
21
+ return reject(err);
22
+ }
23
+ resolve(snapshot);
24
+ }
25
+ );
26
+ });
27
+ }
28
+
29
+ /**
30
+ * Returns true if the files inside this snapshot
31
+ * have not been changed
32
+ *
33
+ * @param {Snapshot} snapshot
34
+ * @param {WebpackCompilation} compilation
35
+ * @returns {Promise<boolean>}
36
+ */
37
+ function isSnapShotValid (snapshot, mainCompilation) {
38
+ return new Promise((resolve, reject) => {
39
+ mainCompilation.fileSystemInfo.checkSnapshotValid(
40
+ snapshot,
41
+ (err, isValid) => {
42
+ if (err) {
43
+ reject(err);
44
+ }
45
+ resolve(isValid);
46
+ }
47
+ );
48
+ });
49
+ }
50
+
51
+ /**
52
+ * Ensure that the files keep watched for changes
53
+ * and will trigger a recompile
54
+ *
55
+ * @param {WebpackCompilation} mainCompilation
56
+ * @param {{fileDependencies: string[], contextDependencies: string[], missingDependencies: string[]}} fileDependencies
57
+ */
58
+ function watchFiles (mainCompilation, fileDependencies) {
59
+ Object.keys(fileDependencies).forEach((depencyTypes) => {
60
+ fileDependencies[depencyTypes].forEach(fileDependency => {
61
+ mainCompilation.fileDependencies.add(fileDependency);
62
+ mainCompilation[depencyTypes].add(fileDependency);
63
+ });
64
+ });
65
+ }
66
+
67
+ module.exports = {
68
+ createSnapshot,
69
+ isSnapShotValid,
70
+ watchFiles
71
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "html-webpack-plugin",
3
- "version": "4.0.2",
3
+ "version": "4.2.0",
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)",
@@ -28,10 +28,8 @@
28
28
  ]
29
29
  },
30
30
  "devDependencies": {
31
- "@types/html-minifier-terser": "5.0.0",
32
31
  "@types/loader-utils": "1.1.3",
33
32
  "@types/node": "11.13.9",
34
- "@types/tapable": "1.0.4",
35
33
  "appcache-webpack-plugin": "1.4.0",
36
34
  "commitizen": "4.0.3",
37
35
  "css-loader": "2.1.1",
@@ -44,14 +42,17 @@
44
42
  "pug": "2.0.3",
45
43
  "pug-loader": "2.4.0",
46
44
  "rimraf": "2.6.3",
47
- "semistandard": "13.0.1",
45
+ "semistandard": "^13.0.1",
48
46
  "standard-version": "5.0.2",
49
47
  "style-loader": "0.23.1",
50
- "typescript": "3.5.2",
48
+ "typescript": "3.8.3",
51
49
  "webpack": "4.35.2",
52
- "webpack-recompilation-simulator": "3.0.0"
50
+ "webpack-recompilation-simulator": "3.2.0"
53
51
  },
54
52
  "dependencies": {
53
+ "@types/html-minifier-terser": "^5.0.0",
54
+ "@types/tapable": "^1.0.5",
55
+ "@types/webpack": "^4.41.8",
55
56
  "html-minifier-terser": "^5.0.1",
56
57
  "loader-utils": "^1.2.3",
57
58
  "lodash": "^4.17.15",
@@ -60,7 +61,7 @@
60
61
  "util.promisify": "1.0.0"
61
62
  },
62
63
  "peerDependencies": {
63
- "webpack": "^4.0.0"
64
+ "webpack": ">=4.0.0 < 6.0.0"
64
65
  },
65
66
  "keywords": [
66
67
  "webpack",
package/typings.d.ts CHANGED
@@ -109,6 +109,7 @@ declare namespace HtmlWebpackPlugin {
109
109
  templateContent:
110
110
  | false // Use the template option instead to load a file
111
111
  | string
112
+ | ((templateParameters: { [option: string]: any }) => (string | Promise<string>))
112
113
  | Promise<string>;
113
114
  /**
114
115
  * Allows to overwrite the parameters used in the template
package/lib/compiler.js DELETED
@@ -1,356 +0,0 @@
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
- 'use strict';
6
- /**
7
- * @file
8
- * This file uses webpack to compile a template with a child compiler.
9
- *
10
- * [TEMPLATE] -> [JAVASCRIPT]
11
- *
12
- */
13
- 'use strict';
14
- const NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
15
- const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
16
- const LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin');
17
- const LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin');
18
- const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin');
19
-
20
- /**
21
- * The HtmlWebpackChildCompiler is a helper to allow resusing one childCompiler
22
- * for multile HtmlWebpackPlugin instances to improve the compilation performance.
23
- */
24
- class HtmlWebpackChildCompiler {
25
- constructor () {
26
- /**
27
- * @type {string[]} templateIds
28
- * The template array will allow us to keep track which input generated which output
29
- */
30
- this.templates = [];
31
- /**
32
- * @type {Promise<{[templatePath: string]: { content: string, hash: string, entry: WebpackChunk }}>}
33
- */
34
- this.compilationPromise; // eslint-disable-line
35
- /**
36
- * @type {number}
37
- */
38
- this.compilationStartedTimestamp; // eslint-disable-line
39
- /**
40
- * @type {number}
41
- */
42
- this.compilationEndedTimestamp; // eslint-disable-line
43
- /**
44
- * All file dependencies of the child compiler
45
- * @type {string[]}
46
- */
47
- this.fileDependencies = [];
48
- }
49
-
50
- /**
51
- * Add a templatePath to the child compiler
52
- * The given template will be compiled by `compileTemplates`
53
- * @param {string} template - The webpack path to the template e.g. `'!!html-loader!index.html'`
54
- * @returns {boolean} true if the template is new
55
- */
56
- addTemplate (template) {
57
- const templateId = this.templates.indexOf(template);
58
- // Don't add the template to the compiler if a similar template was already added
59
- if (templateId !== -1) {
60
- return false;
61
- }
62
- // A child compiler can compile only once
63
- // throw an error if a new template is added after the compilation started
64
- if (this.isCompiling()) {
65
- throw new Error('New templates can only be added before `compileTemplates` was called.');
66
- }
67
- // Add the template to the childCompiler
68
- this.templates.push(template);
69
- // Mark the cache invalid
70
- return true;
71
- }
72
-
73
- /**
74
- * Returns true if the childCompiler is currently compiling
75
- * @retuns {boolean}
76
- */
77
- isCompiling () {
78
- return !this.didCompile() && this.compilationStartedTimestamp !== undefined;
79
- }
80
-
81
- /**
82
- * Returns true if the childCOmpiler is done compiling
83
- */
84
- didCompile () {
85
- return this.compilationEndedTimestamp !== undefined;
86
- }
87
-
88
- /**
89
- * This function will start the template compilation
90
- * once it is started no more templates can be added
91
- *
92
- * @param {WebpackCompilation} mainCompilation
93
- * @returns {Promise<{[templatePath: string]: { content: string, hash: string, entry: WebpackChunk }}>}
94
- */
95
- compileTemplates (mainCompilation) {
96
- // To prevent multiple compilations for the same template
97
- // the compilation is cached in a promise.
98
- // If it already exists return
99
- if (this.compilationPromise) {
100
- return this.compilationPromise;
101
- }
102
-
103
- // The entry file is just an empty helper as the dynamic template
104
- // require is added in "loader.js"
105
- const outputOptions = {
106
- filename: '__child-[name]',
107
- publicPath: mainCompilation.outputOptions.publicPath
108
- };
109
- const compilerName = 'HtmlWebpackCompiler';
110
- // Create an additional child compiler which takes the template
111
- // and turns it into an Node.JS html factory.
112
- // This allows us to use loaders during the compilation
113
- const childCompiler = mainCompilation.createChildCompiler(compilerName, outputOptions);
114
- // The file path context which webpack uses to resolve all relative files to
115
- childCompiler.context = mainCompilation.compiler.context;
116
- // Compile the template to nodejs javascript
117
- new NodeTemplatePlugin(outputOptions).apply(childCompiler);
118
- new NodeTargetPlugin().apply(childCompiler);
119
- new LibraryTemplatePlugin('HTML_WEBPACK_PLUGIN_RESULT', 'var').apply(childCompiler);
120
- new LoaderTargetPlugin('node').apply(childCompiler);
121
-
122
- // Add all templates
123
- this.templates.forEach((template, index) => {
124
- new SingleEntryPlugin(childCompiler.context, template, `HtmlWebpackPlugin_${index}`).apply(childCompiler);
125
- });
126
-
127
- this.compilationStartedTimestamp = new Date().getTime();
128
- this.compilationPromise = new Promise((resolve, reject) => {
129
- childCompiler.runAsChild((err, entries, childCompilation) => {
130
- // Extract templates
131
- const compiledTemplates = entries
132
- ? extractHelperFilesFromCompilation(mainCompilation, childCompilation, outputOptions.filename, entries)
133
- : [];
134
- // Extract file dependencies
135
- if (entries) {
136
- this.fileDependencies = Array.from(childCompilation.fileDependencies);
137
- }
138
- // Reject the promise if the childCompilation contains error
139
- if (childCompilation && childCompilation.errors && childCompilation.errors.length) {
140
- const errorDetails = childCompilation.errors.map(error => error.message + (error.error ? ':\n' + error.error : '')).join('\n');
141
- reject(new Error('Child compilation failed:\n' + errorDetails));
142
- return;
143
- }
144
- // Reject if the error object contains errors
145
- if (err) {
146
- reject(err);
147
- return;
148
- }
149
- /**
150
- * @type {{[templatePath: string]: { content: string, hash: string, entry: WebpackChunk }}}
151
- */
152
- const result = {};
153
- compiledTemplates.forEach((templateSource, entryIndex) => {
154
- // The compiledTemplates are generated from the entries added in
155
- // the addTemplate function.
156
- // Therefore the array index of this.templates should be the as entryIndex.
157
- result[this.templates[entryIndex]] = {
158
- content: templateSource,
159
- hash: childCompilation.hash,
160
- entry: entries[entryIndex]
161
- };
162
- });
163
- this.compilationEndedTimestamp = new Date().getTime();
164
- resolve(result);
165
- });
166
- });
167
-
168
- return this.compilationPromise;
169
- }
170
- }
171
-
172
- /**
173
- * The webpack child compilation will create files as a side effect.
174
- * This function will extract them and clean them up so they won't be written to disk.
175
- *
176
- * Returns the source code of the compiled templates as string
177
- *
178
- * @returns Array<string>
179
- */
180
- function extractHelperFilesFromCompilation (mainCompilation, childCompilation, filename, childEntryChunks) {
181
- const helperAssetNames = childEntryChunks.map((entryChunk, index) => {
182
- return mainCompilation.mainTemplate.getAssetPath(filename, {
183
- hash: childCompilation.hash,
184
- chunk: entryChunk,
185
- name: `HtmlWebpackPlugin_${index}`
186
- });
187
- });
188
-
189
- helperAssetNames.forEach((helperFileName) => {
190
- delete mainCompilation.assets[helperFileName];
191
- });
192
-
193
- const helperContents = helperAssetNames.map((helperFileName) => {
194
- return childCompilation.assets[helperFileName].source();
195
- });
196
-
197
- return helperContents;
198
- }
199
-
200
- /**
201
- * @type {WeakMap<WebpackCompiler, HtmlWebpackChildCompiler>}}
202
- */
203
- const childCompilerCache = new WeakMap();
204
-
205
- /**
206
- * Get child compiler from cache or a new child compiler for the given mainCompilation
207
- *
208
- * @param {WebpackCompiler} mainCompiler
209
- */
210
- function getChildCompiler (mainCompiler) {
211
- const cachedChildCompiler = childCompilerCache.get(mainCompiler);
212
- if (cachedChildCompiler) {
213
- return cachedChildCompiler;
214
- }
215
- const newCompiler = new HtmlWebpackChildCompiler();
216
- childCompilerCache.set(mainCompiler, newCompiler);
217
- return newCompiler;
218
- }
219
-
220
- /**
221
- * Remove the childCompiler from the cache
222
- *
223
- * @param {WebpackCompiler} mainCompiler
224
- */
225
- function clearCache (mainCompiler) {
226
- const childCompiler = getChildCompiler(mainCompiler);
227
- // If this childCompiler was already used
228
- // remove the entire childCompiler from the cache
229
- if (childCompiler.isCompiling() || childCompiler.didCompile()) {
230
- childCompilerCache.delete(mainCompiler);
231
- }
232
- }
233
-
234
- /**
235
- * Register a template for the current main compiler
236
- * @param {WebpackCompiler} mainCompiler
237
- * @param {string} templatePath
238
- */
239
- function addTemplateToCompiler (mainCompiler, templatePath) {
240
- const childCompiler = getChildCompiler(mainCompiler);
241
- const isNew = childCompiler.addTemplate(templatePath);
242
- if (isNew) {
243
- clearCache(mainCompiler);
244
- }
245
- }
246
-
247
- /**
248
- * Starts the compilation for all templates.
249
- * This has to be called once all templates where added.
250
- *
251
- * If this function is called multiple times it will use a cache inside
252
- * the childCompiler
253
- *
254
- * @param {string} templatePath
255
- * @param {string} outputFilename
256
- * @param {WebpackCompilation} mainCompilation
257
- */
258
- function compileTemplate (templatePath, outputFilename, mainCompilation) {
259
- const childCompiler = getChildCompiler(mainCompilation.compiler);
260
- return childCompiler.compileTemplates(mainCompilation).then((compiledTemplates) => {
261
- if (!compiledTemplates[templatePath]) console.log(Object.keys(compiledTemplates), templatePath);
262
- const compiledTemplate = compiledTemplates[templatePath];
263
- // Replace [hash] placeholders in filename
264
- const outputName = mainCompilation.mainTemplate.getAssetPath(outputFilename, {
265
- hash: compiledTemplate.hash,
266
- chunk: compiledTemplate.entry
267
- });
268
- return {
269
- // Hash of the template entry point
270
- hash: compiledTemplate.hash,
271
- // Output name
272
- outputName: outputName,
273
- // Compiled code
274
- content: compiledTemplate.content
275
- };
276
- });
277
- }
278
-
279
- /**
280
- * Return all file dependencies of the last child compilation
281
- *
282
- * @param {WebpackCompiler} compiler
283
- * @returns {Array<string>}
284
- */
285
- function getFileDependencies (compiler) {
286
- const childCompiler = getChildCompiler(compiler);
287
- return childCompiler.fileDependencies;
288
- }
289
-
290
- /**
291
- * @type {WeakMap<WebpackCompilation, WeakMap<HtmlWebpackChildCompiler, boolean>>}}
292
- */
293
- const hasOutdatedCompilationDependenciesMap = new WeakMap();
294
- /**
295
- * Returns `true` if the file dependencies of the current childCompiler
296
- * for the given mainCompilation are outdated.
297
- *
298
- * Uses the `hasOutdatedCompilationDependenciesMap` cache if possible.
299
- *
300
- * @param {WebpackCompilation} mainCompilation
301
- * @returns {boolean}
302
- */
303
- function hasOutDatedTemplateCache (mainCompilation) {
304
- const childCompiler = getChildCompiler(mainCompilation.compiler);
305
- /**
306
- * @type {WeakMap<HtmlWebpackChildCompiler, boolean>|undefined}
307
- */
308
- let hasOutdatedChildCompilerDependenciesMap = hasOutdatedCompilationDependenciesMap.get(mainCompilation);
309
- // Create map for childCompiler if none exist
310
- if (!hasOutdatedChildCompilerDependenciesMap) {
311
- hasOutdatedChildCompilerDependenciesMap = new WeakMap();
312
- hasOutdatedCompilationDependenciesMap.set(mainCompilation, hasOutdatedChildCompilerDependenciesMap);
313
- }
314
- // Try to get the `checkChildCompilerCache` result from cache
315
- let isOutdated = hasOutdatedChildCompilerDependenciesMap.get(childCompiler);
316
- if (isOutdated !== undefined) {
317
- return isOutdated;
318
- }
319
- // If `checkChildCompilerCache` has never been called for the given
320
- // `mainCompilation` and `childCompiler` combination call it:
321
- isOutdated = isChildCompilerCacheOutdated(mainCompilation, childCompiler);
322
- hasOutdatedChildCompilerDependenciesMap.set(childCompiler, isOutdated);
323
- return isOutdated;
324
- }
325
-
326
- /**
327
- * Returns `true` if the file dependencies of the given childCompiler are outdated.
328
- *
329
- * @param {WebpackCompilation} mainCompilation
330
- * @param {HtmlWebpackChildCompiler} childCompiler
331
- * @returns {boolean}
332
- */
333
- function isChildCompilerCacheOutdated (mainCompilation, childCompiler) {
334
- // If the compilation was never run there is no invalid cache
335
- if (!childCompiler.compilationStartedTimestamp) {
336
- return false;
337
- }
338
- // Check if any dependent file was changed after the last compilation
339
- const fileTimestamps = mainCompilation.fileTimestamps;
340
- const isCacheOutOfDate = childCompiler.fileDependencies.some((fileDependency) => {
341
- const timestamp = fileTimestamps.get(fileDependency);
342
- // If the timestamp is not known the file is new
343
- // If the timestamp is larger then the file has changed
344
- // Otherwise the file is still the same
345
- return !timestamp || timestamp > childCompiler.compilationStartedTimestamp;
346
- });
347
- return isCacheOutOfDate;
348
- }
349
-
350
- module.exports = {
351
- addTemplateToCompiler,
352
- compileTemplate,
353
- hasOutDatedTemplateCache,
354
- clearCache,
355
- getFileDependencies
356
- };