@rushstack/webpack4-module-minifier-plugin 0.9.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.
Files changed (49) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +61 -0
  3. package/dist/tsdoc-metadata.json +11 -0
  4. package/dist/webpack4-module-minifier-plugin.d.ts +346 -0
  5. package/lib/AsyncImportCompressionPlugin.d.ts +14 -0
  6. package/lib/AsyncImportCompressionPlugin.d.ts.map +1 -0
  7. package/lib/AsyncImportCompressionPlugin.js +200 -0
  8. package/lib/AsyncImportCompressionPlugin.js.map +1 -0
  9. package/lib/Constants.d.ts +28 -0
  10. package/lib/Constants.d.ts.map +1 -0
  11. package/lib/Constants.js +33 -0
  12. package/lib/Constants.js.map +1 -0
  13. package/lib/GenerateLicenseFileForAsset.d.ts +13 -0
  14. package/lib/GenerateLicenseFileForAsset.d.ts.map +1 -0
  15. package/lib/GenerateLicenseFileForAsset.js +79 -0
  16. package/lib/GenerateLicenseFileForAsset.js.map +1 -0
  17. package/lib/ModuleMinifierPlugin.d.ts +18 -0
  18. package/lib/ModuleMinifierPlugin.d.ts.map +1 -0
  19. package/lib/ModuleMinifierPlugin.js +439 -0
  20. package/lib/ModuleMinifierPlugin.js.map +1 -0
  21. package/lib/ModuleMinifierPlugin.types.d.ts +217 -0
  22. package/lib/ModuleMinifierPlugin.types.d.ts.map +1 -0
  23. package/lib/ModuleMinifierPlugin.types.js +5 -0
  24. package/lib/ModuleMinifierPlugin.types.js.map +1 -0
  25. package/lib/OverrideWebpackIdentifierAllocation.d.ts +2 -0
  26. package/lib/OverrideWebpackIdentifierAllocation.d.ts.map +1 -0
  27. package/lib/OverrideWebpackIdentifierAllocation.js +9 -0
  28. package/lib/OverrideWebpackIdentifierAllocation.js.map +1 -0
  29. package/lib/ParallelCompiler.d.ts +11 -0
  30. package/lib/ParallelCompiler.d.ts.map +1 -0
  31. package/lib/ParallelCompiler.js +90 -0
  32. package/lib/ParallelCompiler.js.map +1 -0
  33. package/lib/PortableMinifierIdsPlugin.d.ts +13 -0
  34. package/lib/PortableMinifierIdsPlugin.d.ts.map +1 -0
  35. package/lib/PortableMinifierIdsPlugin.js +129 -0
  36. package/lib/PortableMinifierIdsPlugin.js.map +1 -0
  37. package/lib/RehydrateAsset.d.ts +11 -0
  38. package/lib/RehydrateAsset.d.ts.map +1 -0
  39. package/lib/RehydrateAsset.js +143 -0
  40. package/lib/RehydrateAsset.js.map +1 -0
  41. package/lib/index.d.ts +9 -0
  42. package/lib/index.d.ts.map +1 -0
  43. package/lib/index.js +32 -0
  44. package/lib/index.js.map +1 -0
  45. package/lib/workerPool/WebpackWorker.d.ts +2 -0
  46. package/lib/workerPool/WebpackWorker.d.ts.map +1 -0
  47. package/lib/workerPool/WebpackWorker.js +101 -0
  48. package/lib/workerPool/WebpackWorker.js.map +1 -0
  49. package/package.json +56 -0
package/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ @rushstack/webpack4-module-minifier-plugin
2
+
3
+ Copyright (c) Microsoft Corporation. All rights reserved.
4
+
5
+ MIT License
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining
8
+ a copy of this software and associated documentation files (the
9
+ "Software"), to deal in the Software without restriction, including
10
+ without limitation the rights to use, copy, modify, merge, publish,
11
+ distribute, sublicense, and/or sell copies of the Software, and to
12
+ permit persons to whom the Software is furnished to do so, subject to
13
+ the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be
16
+ included in all copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # @rushstack/webpack4-module-minifier-plugin
2
+
3
+ ## Installation
4
+
5
+ `npm install @rushstack/webpack4-module-minifier-plugin --save-dev`
6
+
7
+ ## Overview
8
+
9
+ This Webpack plugin performs minification of production assets on a per-module basis, rather than minifying an entire chunk at a time.
10
+ It issues async calls to the minifier for each unique module and each unique set of chunk boilerplate (i.e. the webpack runtime and the structure of the module list).
11
+ This improves minification time by:
12
+ - Avoiding duplicate work for each module that is included in multiple distinct assets/chunks (this is common with async chunks)
13
+ - Handing smaller code chunks to the minifier at a time (AST analysis is superlinear in size of the AST)
14
+ - Even single asset builds will likely still contain multiple modules in the final output, which can be split across available CPU cores
15
+
16
+ ## Use with `[hash]` and `[contenthash]` tokens
17
+ The plugin will do its best to update webpack hashes if changing the direct inputs (`useSourceMap`, `compressAsyncImports` or `usePortableModules`) to the plugin, but if altering the `minifier` property itself, you may need to use the `output.hashSalt` property to force a change to the hashes, especially if leverging the `MessagePortMinifier` or similar, since it has no direct access to the configuration of the minifier.
18
+
19
+ ## Parallel execution
20
+ If running on node 10, you will need to ensure that the `--experimental-workers` flag is enabled.
21
+
22
+ ```js
23
+ const { ModuleMinifierPlugin, WorkerPoolMinifier } = require('@rushstack/webpack4-module-minifier-plugin');
24
+
25
+ // In your webpack options:
26
+ optimization: {
27
+ minimizer: [
28
+ new ModuleMinifierPlugin({
29
+ minifier: new WorkerPoolMinifier(),
30
+ // If not provided, the plugin will attempt to guess from `mode` and `devtool`.
31
+ // Providing it expressly gives better results
32
+ useSourceMap: true
33
+ })
34
+ ]
35
+ }
36
+ ```
37
+
38
+ ## Single-threaded execution
39
+ You can also run the ModuleMinifierPlugin in a single-threaded configuration.
40
+
41
+ ```js
42
+ // webpack.config.js
43
+ const { ModuleMinifierPlugin, LocalMinifier } = require('@rushstack/webpack4-module-minifier-plugin');
44
+
45
+ // In your webpack options:
46
+ optimization: {
47
+ minimizer: [
48
+ new ModuleMinifierPlugin({
49
+ minifier: new LocalMinifier()
50
+ })
51
+ ]
52
+ }
53
+ ```
54
+
55
+ ## Links
56
+
57
+ - [CHANGELOG.md](
58
+ https://github.com/microsoft/rushstack/blob/main/webpack/module-minifier-plugin/CHANGELOG.md) - Find
59
+ out what's new in the latest version
60
+
61
+ `@rushstack/webpack4-module-minifier-plugin` is part of the [Rush Stack](https://rushstack.io/) family of projects.
@@ -0,0 +1,11 @@
1
+ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.
2
+ // It should be published with your NPM package. It should not be tracked by Git.
3
+ {
4
+ "tsdocVersion": "0.12",
5
+ "toolPackages": [
6
+ {
7
+ "packageName": "@microsoft/api-extractor",
8
+ "packageVersion": "7.25.2"
9
+ }
10
+ ]
11
+ }
@@ -0,0 +1,346 @@
1
+ import type { AsyncSeriesWaterfallHook } from 'tapable';
2
+ import { Compiler } from 'webpack';
3
+ import { getIdentifier } from '@rushstack/module-minifier';
4
+ import { ILocalMinifierOptions } from '@rushstack/module-minifier';
5
+ import { IMinifierConnection } from '@rushstack/module-minifier';
6
+ import { IModuleMinificationCallback } from '@rushstack/module-minifier';
7
+ import { IModuleMinificationErrorResult } from '@rushstack/module-minifier';
8
+ import { IModuleMinificationRequest } from '@rushstack/module-minifier';
9
+ import { IModuleMinificationResult } from '@rushstack/module-minifier';
10
+ import { IModuleMinificationSuccessResult } from '@rushstack/module-minifier';
11
+ import { IModuleMinifier } from '@rushstack/module-minifier';
12
+ import { IModuleMinifierFunction } from '@rushstack/module-minifier';
13
+ import { IWorkerPoolMinifierOptions } from '@rushstack/module-minifier';
14
+ import { LocalMinifier } from '@rushstack/module-minifier';
15
+ import { MessagePortMinifier } from '@rushstack/module-minifier';
16
+ import { NoopMinifier } from '@rushstack/module-minifier';
17
+ import { Plugin } from 'webpack';
18
+ import type { ReplaceSource } from 'webpack-sources';
19
+ import { Source } from 'webpack-sources';
20
+ import type { SyncWaterfallHook } from 'tapable';
21
+ import * as webpack from 'webpack';
22
+ import { WorkerPoolMinifier } from '@rushstack/module-minifier';
23
+
24
+ /**
25
+ * Token to replace the object or array of module definitions so that the minifier can operate on the Webpack runtime or chunk boilerplate in isolation
26
+ * @public
27
+ */
28
+ export declare const CHUNK_MODULES_TOKEN: '__WEBPACK_CHUNK_MODULES__';
29
+
30
+ /**
31
+ * Generates a companion asset containing all extracted comments. If it is non-empty, returns a banner comment directing users to said companion asset.
32
+ *
33
+ * @param compilation - The webpack compilation
34
+ * @param asset - The asset to process
35
+ * @param minifiedModules - The minified modules to pull comments from
36
+ * @param assetName - The name of the asset
37
+ * @public
38
+ */
39
+ export declare function generateLicenseFileForAsset(compilation: webpack.compilation.Compilation, asset: IAssetInfo, minifiedModules: IModuleMap): string;
40
+
41
+ export { getIdentifier }
42
+
43
+ /**
44
+ * The comment objects from the Acorn parser inside of webpack
45
+ * @internal
46
+ */
47
+ export declare interface _IAcornComment {
48
+ type: 'Line' | 'Block';
49
+ value: string;
50
+ start: number;
51
+ end: number;
52
+ }
53
+
54
+ /**
55
+ * Information about a dehydrated webpack ECMAScript asset
56
+ * @public
57
+ */
58
+ export declare interface IAssetInfo {
59
+ /**
60
+ * The (minified) boilerplate code for the asset. Will contain a token to be replaced by the minified modules.
61
+ */
62
+ source: Source;
63
+ /**
64
+ * The name of the asset, used to index into compilation.assets
65
+ */
66
+ fileName: string;
67
+ /**
68
+ * The ids of the modules that are part of the chunk corresponding to this asset
69
+ */
70
+ modules: (string | number)[];
71
+ /**
72
+ * The raw chunk object from Webpack, in case information from it is necessary for reconstruction
73
+ */
74
+ chunk: webpack.compilation.Chunk;
75
+ /**
76
+ * The set of external names to postprocess
77
+ */
78
+ externalNames: Map<string, string>;
79
+ }
80
+
81
+ /**
82
+ * A map from file names to dehydrated assets
83
+ * @public
84
+ */
85
+ export declare type IAssetMap = Map<string, IAssetInfo>;
86
+
87
+ /**
88
+ * The set of data remaining to rehydrate in the current compilation
89
+ * @public
90
+ */
91
+ export declare interface IDehydratedAssets {
92
+ /**
93
+ * The set of remaining assets to rehydrate. Each tap may remove some or all assets from this collection
94
+ */
95
+ assets: IAssetMap;
96
+ /**
97
+ * The set of modules to use for rehydrating assets.
98
+ */
99
+ modules: IModuleMap;
100
+ }
101
+
102
+ /**
103
+ * Extension of the webpack Module typings with members that are used by this Plugin
104
+ * @public
105
+ */
106
+ export declare interface IExtendedModule extends webpack.compilation.Module {
107
+ /**
108
+ * Is this module external?
109
+ */
110
+ external?: boolean;
111
+ /**
112
+ * Concatenated modules
113
+ */
114
+ modules?: IExtendedModule[];
115
+ /**
116
+ * Recursively scan the dependencies of a module
117
+ */
118
+ hasDependencies(callback: (dep: webpack.compilation.Dependency) => boolean | void): boolean;
119
+ /**
120
+ * Id for the module
121
+ */
122
+ id: string | number | null;
123
+ /**
124
+ * Gets a descriptive identifier for the module.
125
+ */
126
+ identifier(): string;
127
+ /**
128
+ * Gets a friendly identifier for the module.
129
+ */
130
+ readableIdentifier(requestShortener: unknown): string;
131
+ /**
132
+ * Path to the physical file this module represents
133
+ */
134
+ resource?: string;
135
+ }
136
+
137
+ export { ILocalMinifierOptions }
138
+
139
+ export { IMinifierConnection }
140
+
141
+ /**
142
+ * Information about a minified module
143
+ * @public
144
+ */
145
+ export declare interface IModuleInfo {
146
+ /**
147
+ * The (minified) code of this module. Will be a function expression.
148
+ */
149
+ source: Source;
150
+ /**
151
+ * The raw module object from Webpack, in case information from it is necessary for reconstruction
152
+ */
153
+ module: IExtendedModule;
154
+ }
155
+
156
+ /**
157
+ * A map from module ids to minified modules
158
+ * @public
159
+ */
160
+ export declare type IModuleMap = Map<string | number, IModuleInfo>;
161
+
162
+ export { IModuleMinificationCallback }
163
+
164
+ export { IModuleMinificationErrorResult }
165
+
166
+ export { IModuleMinificationRequest }
167
+
168
+ export { IModuleMinificationResult }
169
+
170
+ export { IModuleMinificationSuccessResult }
171
+
172
+ export { IModuleMinifier }
173
+
174
+ export { IModuleMinifierFunction }
175
+
176
+ /**
177
+ * Hooks provided by the ModuleMinifierPlugin
178
+ * @public
179
+ */
180
+ export declare interface IModuleMinifierPluginHooks {
181
+ /**
182
+ * Hook invoked at the start of optimizeChunkAssets to rehydrate the minified boilerplate and runtime into chunk assets.
183
+ */
184
+ rehydrateAssets: AsyncSeriesWaterfallHook<IDehydratedAssets, webpack.compilation.Compilation>;
185
+ /**
186
+ * Hook invoked on a module id to get the final rendered id.
187
+ */
188
+ finalModuleId: SyncWaterfallHook<string | number | undefined, webpack.compilation.Compilation>;
189
+ /**
190
+ * Hook invoked on code after it has been returned from the minifier.
191
+ */
192
+ postProcessCodeFragment: SyncWaterfallHook<ReplaceSource, IPostProcessFragmentContext>;
193
+ }
194
+
195
+ /**
196
+ * Options to the ModuleMinifierPlugin constructor
197
+ * @public
198
+ */
199
+ export declare interface IModuleMinifierPluginOptions {
200
+ /**
201
+ * Minifier implementation to use. Required.
202
+ */
203
+ minifier: IModuleMinifier;
204
+ /**
205
+ * Whether to enable source map processing. If not provided, will attempt to guess based on `mode` and `devtool` in the webpack config.
206
+ * Set to `false` for faster builds at the expense of debuggability.
207
+ */
208
+ sourceMap?: boolean;
209
+ /**
210
+ * Instructs the plugin to alter the code of modules to maximize portability across compilations.
211
+ */
212
+ usePortableModules?: boolean;
213
+ /**
214
+ * Instructs the plugin to alter the code of async import statements to compress better and be portable across compilations.
215
+ */
216
+ compressAsyncImports?: boolean;
217
+ }
218
+
219
+ /**
220
+ * This is the second parameter to the NormalModuleFactory `module` hook
221
+ * @internal
222
+ */
223
+ export declare interface _INormalModuleFactoryModuleData {
224
+ resourceResolveData?: {
225
+ /**
226
+ * Contents of the description file (package.json) for the module
227
+ */
228
+ descriptionFileData?: {
229
+ /**
230
+ * The name of the package
231
+ */
232
+ name: string;
233
+ };
234
+ /**
235
+ * Absolute path of the description file (package.json) for the module
236
+ */
237
+ descriptionFilePath?: string;
238
+ /**
239
+ * Absolute path of the directory containing the description file (package.json) for the module
240
+ */
241
+ descriptionFileRoot?: string;
242
+ /**
243
+ * Relative path from the description file (package.json) to the module
244
+ */
245
+ relativePath?: string;
246
+ };
247
+ }
248
+
249
+ /**
250
+ * Argument to the postProcessCodeFragment hook for the current execution context
251
+ * @public
252
+ */
253
+ export declare interface IPostProcessFragmentContext {
254
+ /**
255
+ * The current webpack compilation, for error reporting
256
+ */
257
+ compilation: webpack.compilation.Compilation;
258
+ /**
259
+ * A name to use for logging
260
+ */
261
+ loggingName: string;
262
+ /**
263
+ * The current module being processed, or `undefined` if not in a module (e.g. the bootstrapper)
264
+ */
265
+ module: webpack.compilation.Module | undefined;
266
+ }
267
+
268
+ /**
269
+ * This is the second parameter to the thisCompilation and compilation webpack.Compiler hooks.
270
+ * @internal
271
+ */
272
+ export declare interface _IWebpackCompilationData {
273
+ normalModuleFactory: webpack.compilation.NormalModuleFactory;
274
+ }
275
+
276
+ export { IWorkerPoolMinifierOptions }
277
+
278
+ export { LocalMinifier }
279
+
280
+ export { MessagePortMinifier }
281
+
282
+ /**
283
+ * Prefix to wrap `function (module, __webpack_exports__, __webpack_require__) { ... }` so that the minifier doesn't delete it.
284
+ * Public because alternate Minifier implementations may wish to know about it.
285
+ * @public
286
+ */
287
+ export declare const MODULE_WRAPPER_PREFIX: '__MINIFY_MODULE__(';
288
+
289
+ /**
290
+ * Suffix to wrap `function (module, __webpack_exports__, __webpack_require__) { ... }` so that the minifier doesn't delete it.
291
+ * Public because alternate Minifier implementations may wish to know about it.
292
+ * @public
293
+ */
294
+ export declare const MODULE_WRAPPER_SUFFIX: ');';
295
+
296
+ /**
297
+ * Webpack plugin that minifies code on a per-module basis rather than per-asset. The actual minification is handled by the input `minifier` object.
298
+ * @public
299
+ */
300
+ export declare class ModuleMinifierPlugin implements webpack.Plugin {
301
+ readonly hooks: IModuleMinifierPluginHooks;
302
+ minifier: IModuleMinifier;
303
+ private readonly _enhancers;
304
+ private readonly _sourceMap;
305
+ private readonly _optionsForHash;
306
+ constructor(options: IModuleMinifierPluginOptions);
307
+ apply(compiler: webpack.Compiler): void;
308
+ }
309
+
310
+ export { NoopMinifier }
311
+
312
+ /**
313
+ * Plugin responsible for converting the Webpack module ids (of whatever variety) to stable ids before code is handed to the minifier, then back again.
314
+ * Uses the node module identity of the target module. Will emit an error if it encounters multiple versions of the same package in the same compilation.
315
+ * @public
316
+ */
317
+ export declare class PortableMinifierModuleIdsPlugin implements Plugin {
318
+ private readonly _minifierHooks;
319
+ constructor(minifierHooks: IModuleMinifierPluginHooks);
320
+ apply(compiler: Compiler): void;
321
+ }
322
+
323
+ /**
324
+ * Rehydrates an asset with minified modules.
325
+ * @param asset - The asset
326
+ * @param moduleMap - The minified modules
327
+ * @param banner - A banner to inject for license information
328
+ * @public
329
+ */
330
+ export declare function rehydrateAsset(asset: IAssetInfo, moduleMap: IModuleMap, banner: string): Source;
331
+
332
+ /**
333
+ * Stage # to use when this should be the last tap in the hook
334
+ * @public
335
+ */
336
+ export declare const STAGE_AFTER: 100;
337
+
338
+ /**
339
+ * Stage # to use when this should be the first tap in the hook
340
+ * @public
341
+ */
342
+ export declare const STAGE_BEFORE: -100;
343
+
344
+ export { WorkerPoolMinifier }
345
+
346
+ export { }
@@ -0,0 +1,14 @@
1
+ import { Compiler, Plugin } from 'webpack';
2
+ import { IModuleMinifierPluginHooks } from './ModuleMinifierPlugin.types';
3
+ /**
4
+ * Plugin that replaces `Promise.all([__webpack_require__.e(1), __webpack_require__.e(12)]).then(__webpack_require__.t.bind(123,7))`
5
+ * with more concise expressions like `__webpack_require__.ee([1,12],123,7)`, etc.
6
+ *
7
+ * Also ensures that the code seen by the minifier does not contain chunk ids, and is therefore portable across chunks/compilations.
8
+ */
9
+ export declare class AsyncImportCompressionPlugin implements Plugin {
10
+ private readonly _minifierHooks;
11
+ constructor(minifierHooks: IModuleMinifierPluginHooks);
12
+ apply(compiler: Compiler): void;
13
+ }
14
+ //# sourceMappingURL=AsyncImportCompressionPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AsyncImportCompressionPlugin.d.ts","sourceRoot":"","sources":["../src/AsyncImportCompressionPlugin.ts"],"names":[],"mappings":"AAGA,OAAgB,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAOpD,OAAO,EAEL,0BAA0B,EAE3B,MAAM,8BAA8B,CAAC;AA2EtC;;;;;GAKG;AACH,qBAAa,4BAA6B,YAAW,MAAM;IACzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;gBAEzC,aAAa,EAAE,0BAA0B;IAIrD,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;CAoLvC"}
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3
+ // See LICENSE in the project root for license information.
4
+ var __importDefault = (this && this.__importDefault) || function (mod) {
5
+ return (mod && mod.__esModule) ? mod : { "default": mod };
6
+ };
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.AsyncImportCompressionPlugin = void 0;
9
+ const webpack_1 = __importDefault(require("webpack"));
10
+ const { Template } = webpack_1.default;
11
+ const Constants_1 = require("./Constants");
12
+ const PLUGIN_NAME = 'AsyncImportCompressionPlugin';
13
+ const TAP_AFTER = {
14
+ name: PLUGIN_NAME,
15
+ stage: Constants_1.STAGE_AFTER
16
+ };
17
+ const ASYNC_IMPORT_PREFIX = '__IMPORT_ASYNC';
18
+ const ASYNC_IMPORT_REGEX = /__IMPORT_ASYNC[^\)]+/g;
19
+ function getImportDependency(compilation) {
20
+ for (const key of compilation.dependencyTemplates.keys()) {
21
+ if (key.name === 'ImportDependency') {
22
+ return key;
23
+ }
24
+ }
25
+ throw new Error(`Could not find ImportDependency!`);
26
+ }
27
+ function getImportTypeExpression(module, originModule) {
28
+ var _a, _b;
29
+ const exportsType = (_a = module.buildMeta) === null || _a === void 0 ? void 0 : _a.exportsType;
30
+ const strict = (_b = originModule.buildMeta) === null || _b === void 0 ? void 0 : _b.strictHarmonyModule;
31
+ // Logic translated from:
32
+ // https://github.com/webpack/webpack/blob/3956274f1eada621e105208dcab4608883cdfdb2/lib/RuntimeTemplate.js#L110-L122
33
+ if (exportsType === 'namespace') {
34
+ // Use the raw module directly
35
+ return '';
36
+ }
37
+ else if (exportsType === 'named') {
38
+ // Create a new namespace object and forward all exports
39
+ return ',3';
40
+ }
41
+ else if (strict) {
42
+ // Synthetic default export
43
+ return ',1';
44
+ }
45
+ else {
46
+ // If modules is marked __esModule, return raw module, otherwise create a new namespace object and forward all exports
47
+ return ',7';
48
+ }
49
+ }
50
+ function needChunkOnDemandLoadingCode(chunk) {
51
+ for (const chunkGroup of chunk.groupsIterable) {
52
+ if (chunkGroup.getNumberOfChildren() > 0) {
53
+ return true;
54
+ }
55
+ }
56
+ return false;
57
+ }
58
+ /**
59
+ * Plugin that replaces `Promise.all([__webpack_require__.e(1), __webpack_require__.e(12)]).then(__webpack_require__.t.bind(123,7))`
60
+ * with more concise expressions like `__webpack_require__.ee([1,12],123,7)`, etc.
61
+ *
62
+ * Also ensures that the code seen by the minifier does not contain chunk ids, and is therefore portable across chunks/compilations.
63
+ */
64
+ class AsyncImportCompressionPlugin {
65
+ constructor(minifierHooks) {
66
+ this._minifierHooks = minifierHooks;
67
+ }
68
+ apply(compiler) {
69
+ const asyncImportMap = new Map();
70
+ const asyncImportGroups = new Map();
71
+ let rankedImportGroups;
72
+ this._minifierHooks.postProcessCodeFragment.tap({
73
+ name: PLUGIN_NAME,
74
+ stage: -1
75
+ }, (source, context) => {
76
+ const code = source.original().source();
77
+ let localImports;
78
+ ASYNC_IMPORT_REGEX.lastIndex = -1;
79
+ // RegExp.exec uses null or an array as the return type, explicitly
80
+ let match = null;
81
+ while ((match = ASYNC_IMPORT_REGEX.exec(code))) {
82
+ const token = match[0];
83
+ if (!localImports) {
84
+ if (!context.module) {
85
+ context.compilation.errors.push(new Error(`Unexpected async import ${token} in non-module context ${context.loggingName}`));
86
+ return source;
87
+ }
88
+ localImports = asyncImportMap.get(context.module);
89
+ if (!localImports) {
90
+ context.compilation.errors.push(new Error(`Unexpected async import ${token} in module ${context.loggingName}`));
91
+ return source;
92
+ }
93
+ }
94
+ const localImport = localImports.get(token);
95
+ if (!localImport) {
96
+ context.compilation.errors.push(new Error(`Missing metadata for ${token} in module ${context.loggingName}`));
97
+ return source;
98
+ }
99
+ const { meta, module } = localImport;
100
+ const chunkExpression = meta.index < 0 ? JSON.stringify(meta.chunkIds) : `${meta.index}`;
101
+ const mapped = this._minifierHooks.finalModuleId.call(module.id, context.compilation);
102
+ const idExpr = mapped === undefined ? module.id : mapped;
103
+ // Replace with a reference or array of ideas, the target module id, and the type of import
104
+ source.replace(match.index, ASYNC_IMPORT_REGEX.lastIndex - 1, `${chunkExpression},${JSON.stringify(idExpr)}${getImportTypeExpression(module, context.module)}`);
105
+ }
106
+ return source;
107
+ });
108
+ compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
109
+ asyncImportMap.clear();
110
+ asyncImportGroups.clear();
111
+ compilation.hooks.beforeChunkAssets.tap(TAP_AFTER, () => {
112
+ const ImportDependency = getImportDependency(compilation);
113
+ for (const module of compilation.modules) {
114
+ const toProcess = module.modules || [module];
115
+ for (const child of toProcess) {
116
+ child.hasDependencies((dep) => {
117
+ if (dep instanceof ImportDependency) {
118
+ const { module: targetModule } = dep;
119
+ let localAsyncImports = asyncImportMap.get(module);
120
+ if (!localAsyncImports) {
121
+ asyncImportMap.set(module, (localAsyncImports = new Map()));
122
+ }
123
+ const chunkGroup = dep.block.chunkGroup;
124
+ const chunkIds = chunkGroup
125
+ ? chunkGroup.chunks.map((chunk) => chunk.id).sort()
126
+ : [];
127
+ const idString = chunkIds.join(';');
128
+ let meta = asyncImportGroups.get(idString);
129
+ if (!meta) {
130
+ asyncImportGroups.set(idString, (meta = {
131
+ chunkCount: chunkIds.length,
132
+ chunkIds: chunkIds,
133
+ count: 0,
134
+ index: -1
135
+ }));
136
+ }
137
+ meta.count++;
138
+ const stringKey = `${targetModule.id}`.replace(/[^A-Za-z0-9_$]/g, '_');
139
+ const key = `${ASYNC_IMPORT_PREFIX}${stringKey}`;
140
+ localAsyncImports.set(key, {
141
+ meta,
142
+ module: targetModule
143
+ });
144
+ }
145
+ });
146
+ }
147
+ }
148
+ const rankedImports = [...asyncImportGroups]
149
+ .filter((x) => x[1].count > 1)
150
+ .sort((x, y) => {
151
+ let diff = y[1].count - x[1].count;
152
+ if (!diff) {
153
+ diff = y[1].chunkCount - x[1].chunkCount;
154
+ }
155
+ if (!diff) {
156
+ diff = x[0] > y[0] ? 1 : x[0] < y[0] ? -1 : 0;
157
+ }
158
+ return diff;
159
+ });
160
+ for (let i = 0, len = rankedImports.length; i < len; i++) {
161
+ rankedImports[i][1].index = i;
162
+ // console.log(rankedImports[i]);
163
+ }
164
+ rankedImportGroups = rankedImports.map((x) => x[1]);
165
+ // Have to do this after the official plugin in order to override
166
+ compilation.dependencyTemplates.set(ImportDependency, {
167
+ apply(dep, source) {
168
+ const stringKey = `${dep.module.id}`.replace(/[^A-Za-z0-9_$]/g, '_');
169
+ const key = `${ASYNC_IMPORT_PREFIX}${stringKey}`;
170
+ const content = `__webpack_require__.ee(${key})`;
171
+ source.replace(dep.block.range[0], dep.block.range[1] - 1, content);
172
+ }
173
+ // Typings in webpack are incorrect. This is a DependencyTemplate object
174
+ });
175
+ });
176
+ compilation.mainTemplate.hooks.requireExtensions.tap(PLUGIN_NAME, (source, chunk) => {
177
+ if (!needChunkOnDemandLoadingCode(chunk)) {
178
+ return source;
179
+ }
180
+ const { requireFn } = compilation.mainTemplate;
181
+ return Template.asString([
182
+ `var asyncImportChunkGroups = [`,
183
+ rankedImportGroups
184
+ ? rankedImportGroups.map((x) => Template.indent(JSON.stringify(x.chunkIds))).join(',\n')
185
+ : '',
186
+ `];`,
187
+ `${requireFn}.ee = function (groupOrId, moduleId, importType) {`,
188
+ Template.indent([
189
+ `return Promise.all((Array.isArray(groupOrId) ? groupOrId : asyncImportChunkGroups[groupOrId]).map(function (x) { return ${requireFn}.e(x); }))`,
190
+ `.then(importType ? ${requireFn}.t.bind(0,moduleId,importType) : ${requireFn}.bind(0,moduleId));`
191
+ ]),
192
+ `};`,
193
+ source
194
+ ]);
195
+ });
196
+ });
197
+ }
198
+ }
199
+ exports.AsyncImportCompressionPlugin = AsyncImportCompressionPlugin;
200
+ //# sourceMappingURL=AsyncImportCompressionPlugin.js.map