@rushstack/webpack4-module-minifier-plugin 0.14.13 → 0.15.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.
Files changed (70) hide show
  1. package/CHANGELOG.json +41 -0
  2. package/CHANGELOG.md +13 -1
  3. package/dist/tsdoc-metadata.json +1 -1
  4. package/lib-esm/AsyncImportCompressionPlugin.js +206 -0
  5. package/lib-esm/AsyncImportCompressionPlugin.js.map +1 -0
  6. package/lib-esm/Constants.js +30 -0
  7. package/lib-esm/Constants.js.map +1 -0
  8. package/lib-esm/GenerateLicenseFileForAsset.js +52 -0
  9. package/lib-esm/GenerateLicenseFileForAsset.js.map +1 -0
  10. package/lib-esm/ModuleMinifierPlugin.js +432 -0
  11. package/lib-esm/ModuleMinifierPlugin.js.map +1 -0
  12. package/lib-esm/ModuleMinifierPlugin.types.js +4 -0
  13. package/lib-esm/ModuleMinifierPlugin.types.js.map +1 -0
  14. package/lib-esm/OverrideWebpackIdentifierAllocation.js +7 -0
  15. package/lib-esm/OverrideWebpackIdentifierAllocation.js.map +1 -0
  16. package/lib-esm/ParallelCompiler.js +90 -0
  17. package/lib-esm/ParallelCompiler.js.map +1 -0
  18. package/lib-esm/PortableMinifierIdsPlugin.js +123 -0
  19. package/lib-esm/PortableMinifierIdsPlugin.js.map +1 -0
  20. package/lib-esm/RehydrateAsset.js +169 -0
  21. package/lib-esm/RehydrateAsset.js.map +1 -0
  22. package/lib-esm/index.js +9 -0
  23. package/lib-esm/index.js.map +1 -0
  24. package/lib-esm/workerPool/WebpackWorker.js +78 -0
  25. package/lib-esm/workerPool/WebpackWorker.js.map +1 -0
  26. package/package.json +29 -7
  27. /package/{lib → lib-commonjs}/AsyncImportCompressionPlugin.js +0 -0
  28. /package/{lib → lib-commonjs}/AsyncImportCompressionPlugin.js.map +0 -0
  29. /package/{lib → lib-commonjs}/Constants.js +0 -0
  30. /package/{lib → lib-commonjs}/Constants.js.map +0 -0
  31. /package/{lib → lib-commonjs}/GenerateLicenseFileForAsset.js +0 -0
  32. /package/{lib → lib-commonjs}/GenerateLicenseFileForAsset.js.map +0 -0
  33. /package/{lib → lib-commonjs}/ModuleMinifierPlugin.js +0 -0
  34. /package/{lib → lib-commonjs}/ModuleMinifierPlugin.js.map +0 -0
  35. /package/{lib → lib-commonjs}/ModuleMinifierPlugin.types.js +0 -0
  36. /package/{lib → lib-commonjs}/ModuleMinifierPlugin.types.js.map +0 -0
  37. /package/{lib → lib-commonjs}/OverrideWebpackIdentifierAllocation.js +0 -0
  38. /package/{lib → lib-commonjs}/OverrideWebpackIdentifierAllocation.js.map +0 -0
  39. /package/{lib → lib-commonjs}/ParallelCompiler.js +0 -0
  40. /package/{lib → lib-commonjs}/ParallelCompiler.js.map +0 -0
  41. /package/{lib → lib-commonjs}/PortableMinifierIdsPlugin.js +0 -0
  42. /package/{lib → lib-commonjs}/PortableMinifierIdsPlugin.js.map +0 -0
  43. /package/{lib → lib-commonjs}/RehydrateAsset.js +0 -0
  44. /package/{lib → lib-commonjs}/RehydrateAsset.js.map +0 -0
  45. /package/{lib → lib-commonjs}/index.js +0 -0
  46. /package/{lib → lib-commonjs}/index.js.map +0 -0
  47. /package/{lib → lib-commonjs}/workerPool/WebpackWorker.js +0 -0
  48. /package/{lib → lib-commonjs}/workerPool/WebpackWorker.js.map +0 -0
  49. /package/{lib → lib-dts}/AsyncImportCompressionPlugin.d.ts +0 -0
  50. /package/{lib → lib-dts}/AsyncImportCompressionPlugin.d.ts.map +0 -0
  51. /package/{lib → lib-dts}/Constants.d.ts +0 -0
  52. /package/{lib → lib-dts}/Constants.d.ts.map +0 -0
  53. /package/{lib → lib-dts}/GenerateLicenseFileForAsset.d.ts +0 -0
  54. /package/{lib → lib-dts}/GenerateLicenseFileForAsset.d.ts.map +0 -0
  55. /package/{lib → lib-dts}/ModuleMinifierPlugin.d.ts +0 -0
  56. /package/{lib → lib-dts}/ModuleMinifierPlugin.d.ts.map +0 -0
  57. /package/{lib → lib-dts}/ModuleMinifierPlugin.types.d.ts +0 -0
  58. /package/{lib → lib-dts}/ModuleMinifierPlugin.types.d.ts.map +0 -0
  59. /package/{lib → lib-dts}/OverrideWebpackIdentifierAllocation.d.ts +0 -0
  60. /package/{lib → lib-dts}/OverrideWebpackIdentifierAllocation.d.ts.map +0 -0
  61. /package/{lib → lib-dts}/ParallelCompiler.d.ts +0 -0
  62. /package/{lib → lib-dts}/ParallelCompiler.d.ts.map +0 -0
  63. /package/{lib → lib-dts}/PortableMinifierIdsPlugin.d.ts +0 -0
  64. /package/{lib → lib-dts}/PortableMinifierIdsPlugin.d.ts.map +0 -0
  65. /package/{lib → lib-dts}/RehydrateAsset.d.ts +0 -0
  66. /package/{lib → lib-dts}/RehydrateAsset.d.ts.map +0 -0
  67. /package/{lib → lib-dts}/index.d.ts +0 -0
  68. /package/{lib → lib-dts}/index.d.ts.map +0 -0
  69. /package/{lib → lib-dts}/workerPool/WebpackWorker.d.ts +0 -0
  70. /package/{lib → lib-dts}/workerPool/WebpackWorker.d.ts.map +0 -0
@@ -0,0 +1,90 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+ import os from 'node:os';
4
+ import { resolve } from 'node:path';
5
+ import { WorkerPoolMinifier } from '@rushstack/module-minifier';
6
+ import { WorkerPool } from '@rushstack/worker-pool';
7
+ const ZERO = BigInt(0);
8
+ const THOUSAND = BigInt(1e3);
9
+ /**
10
+ * Formats a delta of `process.hrtime.bigint()` values as a string
11
+ * @param timeNs
12
+ */
13
+ function formatTime(timeNs) {
14
+ let unit = 'ns';
15
+ let fraction = ZERO;
16
+ if (timeNs > THOUSAND) {
17
+ unit = 'us';
18
+ fraction = timeNs % THOUSAND;
19
+ timeNs /= THOUSAND;
20
+ }
21
+ if (timeNs > THOUSAND) {
22
+ unit = 'ms';
23
+ fraction = timeNs % THOUSAND;
24
+ timeNs /= THOUSAND;
25
+ }
26
+ if (timeNs > THOUSAND) {
27
+ unit = 's';
28
+ fraction = timeNs % THOUSAND;
29
+ timeNs /= THOUSAND;
30
+ }
31
+ return `${timeNs}.${('000' + fraction).slice(-3, -1)} ${unit}`;
32
+ }
33
+ export async function runParallel(options) {
34
+ var _a, _b;
35
+ const resolvedPath = resolve(options.configFilePath);
36
+ const rawConfig = require(resolvedPath);
37
+ const configArray = Array.isArray(rawConfig) ? rawConfig : [rawConfig];
38
+ const configCount = configArray.length;
39
+ const totalCpus = (_b = (_a = os.availableParallelism) === null || _a === void 0 ? void 0 : _a.call(os)) !== null && _b !== void 0 ? _b : os.cpus().length;
40
+ // TODO: Use all cores if not minifying
41
+ const { maxCompilationThreads: maxConfiguredCompilationThreads = Math.max(totalCpus > 8 ? (totalCpus * 3) >> 2 : totalCpus >> 1, 1), sourceMap, usePortableModules } = options;
42
+ const maxCompilationThreads = Math.min(configCount, maxConfiguredCompilationThreads);
43
+ const maxCompressionThreads = Math.max(1, totalCpus - maxCompilationThreads);
44
+ const minifier = new WorkerPoolMinifier({
45
+ terserOptions: options.terserOptions,
46
+ maxThreads: maxCompressionThreads
47
+ });
48
+ const minifierConnection = await minifier.connectAsync();
49
+ const webpackPool = new WorkerPool({
50
+ id: 'Webpack',
51
+ maxWorkers: maxCompilationThreads,
52
+ onWorkerDestroyed: () => {
53
+ // Allocate the webpack worker to terser
54
+ minifier.maxThreads++;
55
+ },
56
+ workerScriptPath: require.resolve('./workerPool/WebpackWorker'),
57
+ workerData: {
58
+ configFilePath: resolvedPath,
59
+ sourceMap,
60
+ usePortableModules
61
+ }
62
+ });
63
+ let processed = 0;
64
+ const startTime = process.hrtime.bigint();
65
+ for (let i = 0; i < configCount; i++) {
66
+ const webpackWorker = await webpackPool.checkoutWorkerAsync(true);
67
+ const sendMinifierResult = (result) => {
68
+ webpackWorker.postMessage(result);
69
+ };
70
+ const workerOnMessage = (message) => {
71
+ if (message === 'getConfigHash') {
72
+ webpackWorker.postMessage(minifierConnection.configHash);
73
+ return;
74
+ }
75
+ if (typeof message === 'object') {
76
+ return minifier.minify(message, sendMinifierResult);
77
+ }
78
+ ++processed;
79
+ // eslint-disable-next-line no-console
80
+ console.log(`${processed}/${configCount} complete (${formatTime(process.hrtime.bigint() - startTime)})`);
81
+ webpackWorker.off('message', workerOnMessage);
82
+ webpackPool.checkinWorker(webpackWorker);
83
+ };
84
+ webpackWorker.on('message', workerOnMessage);
85
+ webpackWorker.postMessage(i);
86
+ }
87
+ await webpackPool.finishAsync();
88
+ await minifierConnection.disconnectAsync();
89
+ }
90
+ //# sourceMappingURL=ParallelCompiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParallelCompiler.js","sourceRoot":"","sources":["../src/ParallelCompiler.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAWpD,MAAM,IAAI,GAAW,MAAM,CAAC,CAAC,CAAC,CAAC;AAC/B,MAAM,QAAQ,GAAW,MAAM,CAAC,GAAG,CAAC,CAAC;AAErC;;;GAGG;AACH,SAAS,UAAU,CAAC,MAAc;IAChC,IAAI,IAAI,GAAW,IAAI,CAAC;IACxB,IAAI,QAAQ,GAAW,IAAI,CAAC;IAC5B,IAAI,MAAM,GAAG,QAAQ,EAAE,CAAC;QACtB,IAAI,GAAG,IAAI,CAAC;QACZ,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;QAC7B,MAAM,IAAI,QAAQ,CAAC;IACrB,CAAC;IACD,IAAI,MAAM,GAAG,QAAQ,EAAE,CAAC;QACtB,IAAI,GAAG,IAAI,CAAC;QACZ,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;QAC7B,MAAM,IAAI,QAAQ,CAAC;IACrB,CAAC;IACD,IAAI,MAAM,GAAG,QAAQ,EAAE,CAAC;QACtB,IAAI,GAAG,GAAG,CAAC;QACX,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;QAC7B,MAAM,IAAI,QAAQ,CAAC;IACrB,CAAC;IAED,OAAO,GAAG,MAAM,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAgC;;IAChE,MAAM,YAAY,GAAW,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAoC,OAAO,CAAC,YAAY,CAAC,CAAC;IACzE,MAAM,WAAW,GAAoB,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACxF,MAAM,WAAW,GAAW,WAAW,CAAC,MAAM,CAAC;IAE/C,MAAM,SAAS,GAAW,MAAA,MAAA,EAAE,CAAC,oBAAoB,kDAAI,mCAAI,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC;IAE1E,uCAAuC;IACvC,MAAM,EACJ,qBAAqB,EAAE,+BAA+B,GAAG,IAAI,CAAC,GAAG,CAC/D,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,EACrD,CAAC,CACF,EACD,SAAS,EACT,kBAAkB,EACnB,GAAG,OAAO,CAAC;IAEZ,MAAM,qBAAqB,GAAW,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,+BAA+B,CAAC,CAAC;IAE7F,MAAM,qBAAqB,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,qBAAqB,CAAC,CAAC;IAErF,MAAM,QAAQ,GAAuB,IAAI,kBAAkB,CAAC;QAC1D,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,UAAU,EAAE,qBAAqB;KAClC,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAAwB,MAAM,QAAQ,CAAC,YAAY,EAAE,CAAC;IAE9E,MAAM,WAAW,GAAe,IAAI,UAAU,CAAC;QAC7C,EAAE,EAAE,SAAS;QACb,UAAU,EAAE,qBAAqB;QACjC,iBAAiB,EAAE,GAAS,EAAE;YAC5B,wCAAwC;YACxC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACxB,CAAC;QACD,gBAAgB,EAAE,OAAO,CAAC,OAAO,CAAC,4BAA4B,CAAC;QAC/D,UAAU,EAAE;YACV,cAAc,EAAE,YAAY;YAC5B,SAAS;YACT,kBAAkB;SACnB;KACF,CAAC,CAAC;IAEH,IAAI,SAAS,GAAW,CAAC,CAAC;IAC1B,MAAM,SAAS,GAAW,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IAElD,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,MAAM,aAAa,GAAW,MAAM,WAAW,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAE1E,MAAM,kBAAkB,GAAgD,CACtE,MAAiC,EAC3B,EAAE;YACR,aAAa,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC,CAAC;QAEF,MAAM,eAAe,GAA2D,CAC9E,OAAqD,EAC/C,EAAE;YACR,IAAI,OAAO,KAAK,eAAe,EAAE,CAAC;gBAChC,aAAa,CAAC,WAAW,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;gBACzD,OAAO;YACT,CAAC;YAED,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAChC,OAAO,QAAQ,CAAC,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;YACtD,CAAC;YAED,EAAE,SAAS,CAAC;YACZ,sCAAsC;YACtC,OAAO,CAAC,GAAG,CACT,GAAG,SAAS,IAAI,WAAW,cAAc,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,CAC5F,CAAC;YAEF,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;YAC9C,WAAW,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;QAC3C,CAAC,CAAC;QAEF,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QAC7C,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,WAAW,CAAC,WAAW,EAAE,CAAC;IAEhC,MAAM,kBAAkB,CAAC,eAAe,EAAE,CAAC;AAC7C,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport os from 'node:os';\nimport { resolve } from 'node:path';\nimport type { Worker } from 'node:worker_threads';\n\nimport type { Configuration } from 'webpack';\n\nimport type {\n IMinifierConnection,\n IModuleMinificationRequest,\n IModuleMinificationResult,\n MinifyOptions\n} from '@rushstack/module-minifier';\nimport { WorkerPoolMinifier } from '@rushstack/module-minifier';\nimport { WorkerPool } from '@rushstack/worker-pool';\n\nexport interface IParallelWebpackOptions {\n cacheDirectory?: string;\n configFilePath: string;\n maxCompilationThreads?: number;\n sourceMap?: boolean | undefined;\n terserOptions?: MinifyOptions;\n usePortableModules?: boolean;\n}\n\nconst ZERO: bigint = BigInt(0);\nconst THOUSAND: bigint = BigInt(1e3);\n\n/**\n * Formats a delta of `process.hrtime.bigint()` values as a string\n * @param timeNs\n */\nfunction formatTime(timeNs: bigint): string {\n let unit: string = 'ns';\n let fraction: bigint = ZERO;\n if (timeNs > THOUSAND) {\n unit = 'us';\n fraction = timeNs % THOUSAND;\n timeNs /= THOUSAND;\n }\n if (timeNs > THOUSAND) {\n unit = 'ms';\n fraction = timeNs % THOUSAND;\n timeNs /= THOUSAND;\n }\n if (timeNs > THOUSAND) {\n unit = 's';\n fraction = timeNs % THOUSAND;\n timeNs /= THOUSAND;\n }\n\n return `${timeNs}.${('000' + fraction).slice(-3, -1)} ${unit}`;\n}\n\nexport async function runParallel(options: IParallelWebpackOptions): Promise<void> {\n const resolvedPath: string = resolve(options.configFilePath);\n const rawConfig: Configuration | Configuration[] = require(resolvedPath);\n const configArray: Configuration[] = Array.isArray(rawConfig) ? rawConfig : [rawConfig];\n const configCount: number = configArray.length;\n\n const totalCpus: number = os.availableParallelism?.() ?? os.cpus().length;\n\n // TODO: Use all cores if not minifying\n const {\n maxCompilationThreads: maxConfiguredCompilationThreads = Math.max(\n totalCpus > 8 ? (totalCpus * 3) >> 2 : totalCpus >> 1,\n 1\n ),\n sourceMap,\n usePortableModules\n } = options;\n\n const maxCompilationThreads: number = Math.min(configCount, maxConfiguredCompilationThreads);\n\n const maxCompressionThreads: number = Math.max(1, totalCpus - maxCompilationThreads);\n\n const minifier: WorkerPoolMinifier = new WorkerPoolMinifier({\n terserOptions: options.terserOptions,\n maxThreads: maxCompressionThreads\n });\n\n const minifierConnection: IMinifierConnection = await minifier.connectAsync();\n\n const webpackPool: WorkerPool = new WorkerPool({\n id: 'Webpack',\n maxWorkers: maxCompilationThreads,\n onWorkerDestroyed: (): void => {\n // Allocate the webpack worker to terser\n minifier.maxThreads++;\n },\n workerScriptPath: require.resolve('./workerPool/WebpackWorker'),\n workerData: {\n configFilePath: resolvedPath,\n sourceMap,\n usePortableModules\n }\n });\n\n let processed: number = 0;\n const startTime: bigint = process.hrtime.bigint();\n\n for (let i: number = 0; i < configCount; i++) {\n const webpackWorker: Worker = await webpackPool.checkoutWorkerAsync(true);\n\n const sendMinifierResult: (result: IModuleMinificationResult) => void = (\n result: IModuleMinificationResult\n ): void => {\n webpackWorker.postMessage(result);\n };\n\n const workerOnMessage: (message: IModuleMinificationRequest | number) => void = (\n message: IModuleMinificationRequest | string | number\n ): void => {\n if (message === 'getConfigHash') {\n webpackWorker.postMessage(minifierConnection.configHash);\n return;\n }\n\n if (typeof message === 'object') {\n return minifier.minify(message, sendMinifierResult);\n }\n\n ++processed;\n // eslint-disable-next-line no-console\n console.log(\n `${processed}/${configCount} complete (${formatTime(process.hrtime.bigint() - startTime)})`\n );\n\n webpackWorker.off('message', workerOnMessage);\n webpackPool.checkinWorker(webpackWorker);\n };\n\n webpackWorker.on('message', workerOnMessage);\n webpackWorker.postMessage(i);\n }\n\n await webpackPool.finishAsync();\n\n await minifierConnection.disconnectAsync();\n}\n"]}
@@ -0,0 +1,123 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+ import { createHash } from 'node:crypto';
4
+ import RequestShortener from 'webpack/lib/RequestShortener';
5
+ import { STAGE_AFTER, STAGE_BEFORE } from './Constants';
6
+ const PLUGIN_NAME = 'PortableMinifierModuleIdsPlugin';
7
+ const TAP_BEFORE = {
8
+ name: PLUGIN_NAME,
9
+ stage: STAGE_BEFORE
10
+ };
11
+ const TAP_AFTER = {
12
+ name: PLUGIN_NAME,
13
+ stage: STAGE_AFTER
14
+ };
15
+ const STABLE_MODULE_ID_PREFIX = '__MODULEID_SHA_';
16
+ // The negative lookback here is to ensure that this regex does not match an async import placeholder
17
+ const STABLE_MODULE_ID_REGEX = /(?<!C)['"]?(__MODULEID_SHA_[0-9a-f]+)['"]?/g;
18
+ /**
19
+ * Plugin responsible for converting the Webpack module ids (of whatever variety) to stable ids before code is handed to the minifier, then back again.
20
+ * 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.
21
+ * @public
22
+ */
23
+ export class PortableMinifierModuleIdsPlugin {
24
+ constructor(minifierHooks) {
25
+ this._minifierHooks = minifierHooks;
26
+ }
27
+ apply(compiler) {
28
+ // Ensure that "EXTERNAL MODULE: " comments are portable and module version invariant
29
+ const baseShorten = RequestShortener.prototype.shorten;
30
+ RequestShortener.prototype.shorten = function (request) {
31
+ const baseResult = baseShorten.call(this, request);
32
+ const nodeModules = '/node_modules/';
33
+ if (!baseResult) {
34
+ return baseResult;
35
+ }
36
+ const nodeModulesIndex = baseResult.lastIndexOf(nodeModules);
37
+ if (nodeModulesIndex < 0) {
38
+ return baseResult;
39
+ }
40
+ const nodeModulePath = baseResult.slice(nodeModulesIndex + nodeModules.length);
41
+ this.cache.set(request, nodeModulePath);
42
+ return nodeModulePath;
43
+ };
44
+ const stableIdToFinalId = new Map();
45
+ this._minifierHooks.finalModuleId.tap(PLUGIN_NAME, (id) => {
46
+ return id === undefined ? id : stableIdToFinalId.get(id);
47
+ });
48
+ this._minifierHooks.postProcessCodeFragment.tap(PLUGIN_NAME, (source, context) => {
49
+ const code = source.original().source();
50
+ STABLE_MODULE_ID_REGEX.lastIndex = -1;
51
+ // RegExp.exec uses null or an array as the return type, explicitly
52
+ let match = null;
53
+ while ((match = STABLE_MODULE_ID_REGEX.exec(code))) {
54
+ const id = match[1];
55
+ const mapped = this._minifierHooks.finalModuleId.call(id, context.compilation);
56
+ if (mapped === undefined) {
57
+ context.compilation.errors.push(new Error(`Missing module id for ${id} in ${context.loggingName}!`));
58
+ }
59
+ source.replace(match.index, STABLE_MODULE_ID_REGEX.lastIndex - 1, JSON.stringify(mapped));
60
+ }
61
+ return source;
62
+ });
63
+ compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation, compilationData) => {
64
+ const { normalModuleFactory } = compilationData;
65
+ normalModuleFactory.hooks.module.tap(PLUGIN_NAME, (mod, data) => {
66
+ const { resourceResolveData: resolveData } = data;
67
+ if (resolveData) {
68
+ mod.factoryMeta.resolveData = resolveData;
69
+ return;
70
+ }
71
+ // eslint-disable-next-line no-console
72
+ console.error(`Missing resolution data for ${mod.resource}`);
73
+ });
74
+ compilation.hooks.succeedModule.tap(PLUGIN_NAME, (mod) => {
75
+ const { resolveData } = mod.factoryMeta;
76
+ if (!resolveData) {
77
+ return;
78
+ }
79
+ const { descriptionFileData: packageJson, relativePath } = resolveData;
80
+ if (packageJson && relativePath) {
81
+ const nodeId = `${packageJson.name}${relativePath.slice(1).replace(/\.js(on)?$/, '')}`;
82
+ mod.factoryMeta.nodeResource = nodeId;
83
+ }
84
+ });
85
+ stableIdToFinalId.clear();
86
+ // Make module ids a pure function of the file path immediately before rendering.
87
+ // Unfortunately, other means of altering these ids don't work in Webpack 4 without a lot more code and work.
88
+ // Namely, a number of functions reference "module.id" directly during code generation
89
+ compilation.hooks.beforeChunkAssets.tap(TAP_AFTER, () => {
90
+ // For tracking collisions
91
+ const resourceById = new Map();
92
+ for (const mod of compilation.modules) {
93
+ const originalId = mod.id;
94
+ // Need different cache keys for different sets of loaders, so can't use 'resource'
95
+ const identity = mod.identifier();
96
+ const hashId = createHash('sha256').update(identity).digest('hex');
97
+ // This is designed to be an easily regex-findable string
98
+ const stableId = `${STABLE_MODULE_ID_PREFIX}${hashId}`;
99
+ const existingResource = resourceById.get(stableId);
100
+ if (existingResource) {
101
+ compilation.errors.push(new Error(`Module id collision for ${identity} with ${existingResource}.\n This means you are bundling multiple versions of the same module.`));
102
+ }
103
+ stableIdToFinalId.set(stableId, originalId);
104
+ // Record to detect collisions
105
+ resourceById.set(stableId, identity);
106
+ mod.id = stableId;
107
+ }
108
+ });
109
+ // This is the hook immediately following chunk asset rendering. Fix the module ids.
110
+ compilation.hooks.additionalChunkAssets.tap(TAP_BEFORE, () => {
111
+ // Restore module ids in case any later hooks need them
112
+ for (const mod of compilation.modules) {
113
+ const stableId = mod.id;
114
+ const finalId = stableIdToFinalId.get(stableId);
115
+ if (finalId !== undefined) {
116
+ mod.id = finalId;
117
+ }
118
+ }
119
+ });
120
+ });
121
+ }
122
+ }
123
+ //# sourceMappingURL=PortableMinifierIdsPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PortableMinifierIdsPlugin.js","sourceRoot":"","sources":["../src/PortableMinifierIdsPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { createHash } from 'node:crypto';\n\nimport type { Compiler, Plugin } from 'webpack';\nimport type webpack from 'webpack';\nimport type { ReplaceSource } from 'webpack-sources';\nimport type { TapOptions } from 'tapable';\nimport RequestShortener from 'webpack/lib/RequestShortener';\n\nimport { STAGE_AFTER, STAGE_BEFORE } from './Constants';\nimport type {\n _INormalModuleFactoryModuleData,\n IExtendedModule,\n IModuleMinifierPluginHooks,\n _IWebpackCompilationData,\n IPostProcessFragmentContext\n} from './ModuleMinifierPlugin.types';\n\nconst PLUGIN_NAME: 'PortableMinifierModuleIdsPlugin' = 'PortableMinifierModuleIdsPlugin';\n\nconst TAP_BEFORE: TapOptions<'sync'> = {\n name: PLUGIN_NAME,\n stage: STAGE_BEFORE\n};\n\nconst TAP_AFTER: TapOptions<'sync'> = {\n name: PLUGIN_NAME,\n stage: STAGE_AFTER\n};\n\nconst STABLE_MODULE_ID_PREFIX: '__MODULEID_SHA_' = '__MODULEID_SHA_';\n// The negative lookback here is to ensure that this regex does not match an async import placeholder\nconst STABLE_MODULE_ID_REGEX: RegExp = /(?<!C)['\"]?(__MODULEID_SHA_[0-9a-f]+)['\"]?/g;\n\n/**\n * Plugin responsible for converting the Webpack module ids (of whatever variety) to stable ids before code is handed to the minifier, then back again.\n * 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.\n * @public\n */\nexport class PortableMinifierModuleIdsPlugin implements Plugin {\n private readonly _minifierHooks: IModuleMinifierPluginHooks;\n\n public constructor(minifierHooks: IModuleMinifierPluginHooks) {\n this._minifierHooks = minifierHooks;\n }\n\n public apply(compiler: Compiler): void {\n // Ensure that \"EXTERNAL MODULE: \" comments are portable and module version invariant\n const baseShorten: (request: string) => string = RequestShortener.prototype.shorten;\n RequestShortener.prototype.shorten = function (this: RequestShortener, request: string): string {\n const baseResult: string = baseShorten.call(this, request);\n const nodeModules: '/node_modules/' = '/node_modules/';\n\n if (!baseResult) {\n return baseResult;\n }\n\n const nodeModulesIndex: number = baseResult.lastIndexOf(nodeModules);\n if (nodeModulesIndex < 0) {\n return baseResult;\n }\n\n const nodeModulePath: string = baseResult.slice(nodeModulesIndex + nodeModules.length);\n this.cache.set(request, nodeModulePath);\n return nodeModulePath;\n };\n\n const stableIdToFinalId: Map<string | number, string | number> = new Map();\n\n this._minifierHooks.finalModuleId.tap(PLUGIN_NAME, (id: string | number | undefined) => {\n return id === undefined ? id : stableIdToFinalId.get(id);\n });\n\n this._minifierHooks.postProcessCodeFragment.tap(\n PLUGIN_NAME,\n (source: ReplaceSource, context: IPostProcessFragmentContext) => {\n const code: string = source.original().source() as string;\n\n STABLE_MODULE_ID_REGEX.lastIndex = -1;\n // RegExp.exec uses null or an array as the return type, explicitly\n let match: RegExpExecArray | null = null;\n while ((match = STABLE_MODULE_ID_REGEX.exec(code))) {\n const id: string = match[1];\n const mapped: string | number | undefined = this._minifierHooks.finalModuleId.call(\n id,\n context.compilation\n );\n\n if (mapped === undefined) {\n context.compilation.errors.push(\n new Error(`Missing module id for ${id} in ${context.loggingName}!`)\n );\n }\n\n source.replace(match.index, STABLE_MODULE_ID_REGEX.lastIndex - 1, JSON.stringify(mapped));\n }\n\n return source;\n }\n );\n\n compiler.hooks.thisCompilation.tap(\n PLUGIN_NAME,\n (compilation: webpack.compilation.Compilation, compilationData: _IWebpackCompilationData) => {\n const { normalModuleFactory } = compilationData;\n\n normalModuleFactory.hooks.module.tap(\n PLUGIN_NAME,\n (mod: IExtendedModule, data: _INormalModuleFactoryModuleData) => {\n const { resourceResolveData: resolveData } = data;\n\n if (resolveData) {\n mod.factoryMeta.resolveData = resolveData;\n return;\n }\n\n // eslint-disable-next-line no-console\n console.error(`Missing resolution data for ${mod.resource}`);\n }\n );\n\n compilation.hooks.succeedModule.tap(PLUGIN_NAME, (mod: webpack.compilation.Module) => {\n const { resolveData } = mod.factoryMeta;\n\n if (!resolveData) {\n return;\n }\n\n const { descriptionFileData: packageJson, relativePath } = resolveData;\n\n if (packageJson && relativePath) {\n const nodeId: string = `${packageJson.name}${relativePath.slice(1).replace(/\\.js(on)?$/, '')}`;\n mod.factoryMeta.nodeResource = nodeId;\n }\n });\n\n stableIdToFinalId.clear();\n\n // Make module ids a pure function of the file path immediately before rendering.\n // Unfortunately, other means of altering these ids don't work in Webpack 4 without a lot more code and work.\n // Namely, a number of functions reference \"module.id\" directly during code generation\n\n compilation.hooks.beforeChunkAssets.tap(TAP_AFTER, () => {\n // For tracking collisions\n const resourceById: Map<string | number, string> = new Map();\n\n for (const mod of compilation.modules) {\n const originalId: string | number = mod.id;\n\n // Need different cache keys for different sets of loaders, so can't use 'resource'\n const identity: string = mod.identifier();\n const hashId: string = createHash('sha256').update(identity).digest('hex');\n\n // This is designed to be an easily regex-findable string\n const stableId: string = `${STABLE_MODULE_ID_PREFIX}${hashId}`;\n const existingResource: string | undefined = resourceById.get(stableId);\n\n if (existingResource) {\n compilation.errors.push(\n new Error(\n `Module id collision for ${identity} with ${existingResource}.\\n This means you are bundling multiple versions of the same module.`\n )\n );\n }\n\n stableIdToFinalId.set(stableId, originalId);\n\n // Record to detect collisions\n resourceById.set(stableId, identity);\n mod.id = stableId;\n }\n });\n\n // This is the hook immediately following chunk asset rendering. Fix the module ids.\n compilation.hooks.additionalChunkAssets.tap(TAP_BEFORE, () => {\n // Restore module ids in case any later hooks need them\n for (const mod of compilation.modules) {\n const stableId: string | number = mod.id;\n const finalId: string | number | undefined = stableIdToFinalId.get(stableId);\n if (finalId !== undefined) {\n mod.id = finalId;\n }\n }\n });\n }\n );\n }\n}\n"]}
@@ -0,0 +1,169 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+ import { CachedSource, ConcatSource, ReplaceSource } from 'webpack-sources';
4
+ import { CHUNK_MODULES_TOKEN } from './Constants';
5
+ /**
6
+ * Rehydrates an asset with minified modules.
7
+ * @param asset - The asset
8
+ * @param moduleMap - The minified modules
9
+ * @param banner - A banner to inject for license information
10
+ * @param emitRenderInfo - If set, provide information about module offsets
11
+ * @public
12
+ */
13
+ export function rehydrateAsset(asset, moduleMap, banner, emitRenderInfo) {
14
+ const { source: assetSource, modules } = asset;
15
+ const assetCode = assetSource.source();
16
+ const tokenIndex = assetCode.indexOf(CHUNK_MODULES_TOKEN);
17
+ if (tokenIndex < 0) {
18
+ // This is not a JS asset.
19
+ return handleExternals(assetSource, asset);
20
+ }
21
+ const suffixStart = tokenIndex + CHUNK_MODULES_TOKEN.length;
22
+ const suffix = assetCode.slice(suffixStart);
23
+ const prefix = new ReplaceSource(assetSource);
24
+ // Preserve source map via fiddly logic
25
+ prefix.replace(tokenIndex, assetCode.length, '');
26
+ if (!modules.length) {
27
+ // Empty chunk, degenerate case
28
+ return new ConcatSource(banner, prefix, '[]', suffix);
29
+ }
30
+ const emptyFunction = 'function(){}'; // eslint-disable-line @typescript-eslint/typedef
31
+ // This must not have the global flag set
32
+ const validIdRegex = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
33
+ const source = new ConcatSource(banner, prefix);
34
+ // Source.size() is in bytes, we want characters
35
+ let charOffset = source.source().length;
36
+ const firstModuleId = modules[0];
37
+ const lastModuleId = modules[modules.length - 1];
38
+ // Extended logic from webpack.Template.getModulesArrayBounds
39
+ const minId = typeof firstModuleId === 'number' ? firstModuleId : 0;
40
+ const maxId = typeof lastModuleId === 'number' ? lastModuleId : Infinity;
41
+ const simpleArrayOverhead = 2 + maxId;
42
+ let concatArrayOverhead = simpleArrayOverhead + 9;
43
+ let useObject = typeof firstModuleId !== 'number' || typeof lastModuleId !== 'number';
44
+ let objectOverhead = 1;
45
+ let lastId = 0;
46
+ if (!useObject) {
47
+ for (const id of modules) {
48
+ if (typeof id !== 'number') {
49
+ // This must be an object
50
+ useObject = true;
51
+ break;
52
+ }
53
+ // This is the extension from webpack.Template.getModulesArrayBounds
54
+ // We can make smaller emit by injecting additional filler arrays
55
+ const delta = id - lastId - 1;
56
+ // Compare the length of `],Array(${delta}),[` to ','.repeat(delta + 1)
57
+ const threshold = (lastId === 0 ? 7 : 11) + ('' + delta).length;
58
+ const fillerArraySavings = delta + 1 - threshold;
59
+ if (fillerArraySavings > 0) {
60
+ concatArrayOverhead -= fillerArraySavings;
61
+ }
62
+ objectOverhead += 2 + ('' + id).length;
63
+ lastId = id;
64
+ }
65
+ }
66
+ const useConcat = concatArrayOverhead < simpleArrayOverhead;
67
+ const arrayOverhead = useConcat ? concatArrayOverhead : simpleArrayOverhead;
68
+ useObject = useObject || objectOverhead < arrayOverhead;
69
+ if (useObject) {
70
+ // Write an object literal
71
+ let separator = '{';
72
+ for (const id of modules) {
73
+ // If the id is legal to use as a key in a JavaScript object literal, use as-is
74
+ const javascriptId = typeof id !== 'string' || validIdRegex.test(id) ? id : JSON.stringify(id);
75
+ const currentSeparator = `${separator}${javascriptId}:`;
76
+ source.add(currentSeparator);
77
+ charOffset += currentSeparator.length;
78
+ separator = ',';
79
+ const item = moduleMap.get(id);
80
+ const moduleCode = item ? item.source : emptyFunction;
81
+ // Source.size() is in bytes, we want characters
82
+ const charLength = typeof moduleCode === 'string' ? moduleCode.length : moduleCode.source().toString().length;
83
+ if (emitRenderInfo) {
84
+ asset.renderInfo.set(id, {
85
+ charOffset,
86
+ charLength
87
+ });
88
+ }
89
+ source.add(moduleCode);
90
+ charOffset += charLength;
91
+ }
92
+ source.add('}');
93
+ }
94
+ else {
95
+ // Write one or more array literals, joined by Array(gap) expressions
96
+ // There will never be more than 16 + ("" + minId).length consecutive commas, so 40 is more than will ever be used
97
+ // This is because the above criteria triggers an Array(len) expression instead
98
+ const enoughCommas = ',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,';
99
+ const useConcatAtStart = useConcat && minId > 8;
100
+ lastId = useConcatAtStart ? minId : 0;
101
+ // TODO: Just because we want to use concat elsewhere doesn't mean its optimal to use at the start
102
+ let separator = useConcatAtStart ? `Array(${minId}).concat([` : '[';
103
+ let concatInserted = useConcatAtStart;
104
+ for (const id of modules) {
105
+ const delta = id - lastId - 1;
106
+ const deltaStr = '' + delta;
107
+ const fillerArrayThreshold = 11 + deltaStr.length;
108
+ const item = moduleMap.get(id);
109
+ const moduleCode = item ? item.source : emptyFunction;
110
+ // Source.size() is in bytes, we want characters
111
+ const charLength = typeof moduleCode === 'string' ? moduleCode.length : moduleCode.source().toString().length;
112
+ if (useConcat && delta + 1 > fillerArrayThreshold) {
113
+ if (concatInserted) {
114
+ const currentSeparator = `],Array(${deltaStr}),[`;
115
+ source.add(currentSeparator);
116
+ charOffset += currentSeparator.length;
117
+ }
118
+ else {
119
+ const currentSeparator = `].concat(Array(${deltaStr}),[`;
120
+ concatInserted = true;
121
+ source.add(currentSeparator);
122
+ charOffset += currentSeparator.length;
123
+ }
124
+ }
125
+ else {
126
+ const currentSeparator = separator + enoughCommas.slice(0, delta + 1);
127
+ source.add(currentSeparator);
128
+ charOffset += currentSeparator.length;
129
+ }
130
+ lastId = id;
131
+ if (emitRenderInfo) {
132
+ asset.renderInfo.set(id, {
133
+ charOffset,
134
+ charLength
135
+ });
136
+ }
137
+ source.add(moduleCode);
138
+ charOffset += charLength;
139
+ separator = '';
140
+ }
141
+ source.add(useConcat ? '])' : ']');
142
+ }
143
+ source.add(suffix);
144
+ return handleExternals(new CachedSource(source), asset);
145
+ }
146
+ function handleExternals(source, asset) {
147
+ const { externalNames } = asset;
148
+ if (externalNames.size) {
149
+ const replaceSource = new ReplaceSource(source);
150
+ const code = source.source();
151
+ const externalIdRegex = /__WEBPACK_EXTERNAL_MODULE_[A-Za-z0-9_$]+/g;
152
+ // RegExp.exec uses null or an array as the return type, explicitly
153
+ let match = null;
154
+ while ((match = externalIdRegex.exec(code))) {
155
+ const id = match[0];
156
+ const mapped = externalNames.get(id);
157
+ if (mapped === undefined) {
158
+ // eslint-disable-next-line no-console
159
+ console.error(`Missing minified external for ${id} in ${asset.fileName}!`);
160
+ }
161
+ else {
162
+ replaceSource.replace(match.index, externalIdRegex.lastIndex - 1, mapped);
163
+ }
164
+ }
165
+ return new CachedSource(replaceSource);
166
+ }
167
+ return source;
168
+ }
169
+ //# sourceMappingURL=RehydrateAsset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RehydrateAsset.js","sourceRoot":"","sources":["../src/RehydrateAsset.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { CachedSource, ConcatSource, ReplaceSource, type Source } from 'webpack-sources';\n\nimport { CHUNK_MODULES_TOKEN } from './Constants';\nimport type { IAssetInfo, IModuleMap, IModuleInfo } from './ModuleMinifierPlugin.types';\n\n/**\n * Rehydrates an asset with minified modules.\n * @param asset - The asset\n * @param moduleMap - The minified modules\n * @param banner - A banner to inject for license information\n * @param emitRenderInfo - If set, provide information about module offsets\n * @public\n */\nexport function rehydrateAsset(\n asset: IAssetInfo,\n moduleMap: IModuleMap,\n banner: string,\n emitRenderInfo?: boolean\n): Source {\n const { source: assetSource, modules } = asset;\n\n const assetCode: string = assetSource.source() as string;\n\n const tokenIndex: number = assetCode.indexOf(CHUNK_MODULES_TOKEN);\n if (tokenIndex < 0) {\n // This is not a JS asset.\n return handleExternals(assetSource, asset);\n }\n const suffixStart: number = tokenIndex + CHUNK_MODULES_TOKEN.length;\n const suffix: string = assetCode.slice(suffixStart);\n\n const prefix: ReplaceSource = new ReplaceSource(assetSource);\n // Preserve source map via fiddly logic\n prefix.replace(tokenIndex, assetCode.length, '');\n\n if (!modules.length) {\n // Empty chunk, degenerate case\n return new ConcatSource(banner, prefix, '[]', suffix);\n }\n\n const emptyFunction = 'function(){}'; // eslint-disable-line @typescript-eslint/typedef\n // This must not have the global flag set\n const validIdRegex: RegExp = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n const source: ConcatSource = new ConcatSource(banner, prefix);\n // Source.size() is in bytes, we want characters\n let charOffset: number = source.source().length;\n\n const firstModuleId: string | number = modules[0];\n const lastModuleId: string | number = modules[modules.length - 1];\n\n // Extended logic from webpack.Template.getModulesArrayBounds\n const minId: number = typeof firstModuleId === 'number' ? firstModuleId : 0;\n const maxId: number = typeof lastModuleId === 'number' ? lastModuleId : Infinity;\n\n const simpleArrayOverhead: number = 2 + maxId;\n let concatArrayOverhead: number = simpleArrayOverhead + 9;\n\n let useObject: boolean = typeof firstModuleId !== 'number' || typeof lastModuleId !== 'number';\n let objectOverhead: number = 1;\n let lastId: number = 0;\n\n if (!useObject) {\n for (const id of modules) {\n if (typeof id !== 'number') {\n // This must be an object\n useObject = true;\n break;\n }\n\n // This is the extension from webpack.Template.getModulesArrayBounds\n // We can make smaller emit by injecting additional filler arrays\n const delta: number = id - lastId - 1;\n\n // Compare the length of `],Array(${delta}),[` to ','.repeat(delta + 1)\n const threshold: number = (lastId === 0 ? 7 : 11) + ('' + delta).length;\n const fillerArraySavings: number = delta + 1 - threshold;\n if (fillerArraySavings > 0) {\n concatArrayOverhead -= fillerArraySavings;\n }\n\n objectOverhead += 2 + ('' + id).length;\n lastId = id;\n }\n }\n\n const useConcat: boolean = concatArrayOverhead < simpleArrayOverhead;\n\n const arrayOverhead: number = useConcat ? concatArrayOverhead : simpleArrayOverhead;\n\n useObject = useObject || objectOverhead < arrayOverhead;\n\n if (useObject) {\n // Write an object literal\n let separator: '{' | ',' = '{';\n for (const id of modules) {\n // If the id is legal to use as a key in a JavaScript object literal, use as-is\n const javascriptId: string | number =\n typeof id !== 'string' || validIdRegex.test(id) ? id : JSON.stringify(id);\n const currentSeparator: string = `${separator}${javascriptId}:`;\n\n source.add(currentSeparator);\n charOffset += currentSeparator.length;\n\n separator = ',';\n\n const item: IModuleInfo | undefined = moduleMap.get(id);\n const moduleCode: Source | string = item ? item.source : emptyFunction;\n // Source.size() is in bytes, we want characters\n const charLength: number =\n typeof moduleCode === 'string' ? moduleCode.length : moduleCode.source().toString().length;\n\n if (emitRenderInfo) {\n asset.renderInfo.set(id, {\n charOffset,\n charLength\n });\n }\n\n source.add(moduleCode);\n charOffset += charLength;\n }\n\n source.add('}');\n } else {\n // Write one or more array literals, joined by Array(gap) expressions\n\n // There will never be more than 16 + (\"\" + minId).length consecutive commas, so 40 is more than will ever be used\n // This is because the above criteria triggers an Array(len) expression instead\n const enoughCommas: string = ',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,';\n\n const useConcatAtStart: boolean = useConcat && minId > 8;\n lastId = useConcatAtStart ? minId : 0;\n // TODO: Just because we want to use concat elsewhere doesn't mean its optimal to use at the start\n let separator: string = useConcatAtStart ? `Array(${minId}).concat([` : '[';\n let concatInserted: boolean = useConcatAtStart;\n for (const id of modules) {\n const delta: number = (id as number) - lastId - 1;\n const deltaStr: string = '' + delta;\n const fillerArrayThreshold: number = 11 + deltaStr.length;\n\n const item: IModuleInfo | undefined = moduleMap.get(id);\n const moduleCode: Source | string = item ? item.source : emptyFunction;\n // Source.size() is in bytes, we want characters\n const charLength: number =\n typeof moduleCode === 'string' ? moduleCode.length : moduleCode.source().toString().length;\n\n if (useConcat && delta + 1 > fillerArrayThreshold) {\n if (concatInserted) {\n const currentSeparator: string = `],Array(${deltaStr}),[`;\n\n source.add(currentSeparator);\n charOffset += currentSeparator.length;\n } else {\n const currentSeparator: string = `].concat(Array(${deltaStr}),[`;\n concatInserted = true;\n\n source.add(currentSeparator);\n charOffset += currentSeparator.length;\n }\n } else {\n const currentSeparator: string = separator + enoughCommas.slice(0, delta + 1);\n\n source.add(currentSeparator);\n charOffset += currentSeparator.length;\n }\n lastId = id as number;\n\n if (emitRenderInfo) {\n asset.renderInfo.set(id, {\n charOffset,\n charLength\n });\n }\n\n source.add(moduleCode);\n charOffset += charLength;\n\n separator = '';\n }\n\n source.add(useConcat ? '])' : ']');\n }\n\n source.add(suffix);\n\n return handleExternals(new CachedSource(source), asset);\n}\n\nfunction handleExternals(source: Source, asset: IAssetInfo): Source {\n const { externalNames } = asset;\n\n if (externalNames.size) {\n const replaceSource: ReplaceSource = new ReplaceSource(source);\n const code: string = source.source() as string;\n\n const externalIdRegex: RegExp = /__WEBPACK_EXTERNAL_MODULE_[A-Za-z0-9_$]+/g;\n\n // RegExp.exec uses null or an array as the return type, explicitly\n let match: RegExpExecArray | null = null;\n while ((match = externalIdRegex.exec(code))) {\n const id: string = match[0];\n const mapped: string | undefined = externalNames.get(id);\n\n if (mapped === undefined) {\n // eslint-disable-next-line no-console\n console.error(`Missing minified external for ${id} in ${asset.fileName}!`);\n } else {\n replaceSource.replace(match.index, externalIdRegex.lastIndex - 1, mapped);\n }\n }\n\n return new CachedSource(replaceSource);\n }\n\n return source;\n}\n"]}
@@ -0,0 +1,9 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+ export { MODULE_WRAPPER_PREFIX, MODULE_WRAPPER_SUFFIX, CHUNK_MODULES_TOKEN, STAGE_BEFORE, STAGE_AFTER } from './Constants';
4
+ export { generateLicenseFileForAsset } from './GenerateLicenseFileForAsset';
5
+ export { ModuleMinifierPlugin } from './ModuleMinifierPlugin';
6
+ export { PortableMinifierModuleIdsPlugin } from './PortableMinifierIdsPlugin';
7
+ export { rehydrateAsset } from './RehydrateAsset';
8
+ export { getIdentifier, LocalMinifier, MessagePortMinifier, NoopMinifier, WorkerPoolMinifier } from '@rushstack/module-minifier';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,2DAA2D;AAE3D,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAkB5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,+BAA+B,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAalD,OAAO,EACL,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EACnB,MAAM,4BAA4B,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nexport {\n MODULE_WRAPPER_PREFIX,\n MODULE_WRAPPER_SUFFIX,\n CHUNK_MODULES_TOKEN,\n STAGE_BEFORE,\n STAGE_AFTER\n} from './Constants';\nexport { generateLicenseFileForAsset } from './GenerateLicenseFileForAsset';\nexport type {\n IRenderedModulePosition,\n IAssetInfo,\n IModuleMinifierPluginStats,\n IAssetStats,\n IModuleInfo,\n IExtendedModule,\n _IWebpackCompilationData,\n _INormalModuleFactoryModuleData,\n IAssetMap,\n IModuleMap,\n IModuleMinifierPluginOptions,\n IDehydratedAssets,\n IPostProcessFragmentContext,\n IModuleMinifierPluginHooks,\n _IAcornComment\n} from './ModuleMinifierPlugin.types';\nexport { ModuleMinifierPlugin } from './ModuleMinifierPlugin';\nexport { PortableMinifierModuleIdsPlugin } from './PortableMinifierIdsPlugin';\nexport { rehydrateAsset } from './RehydrateAsset';\nexport type {\n ILocalMinifierOptions,\n IMinifierConnection,\n IModuleMinificationCallback,\n IModuleMinificationErrorResult,\n IModuleMinificationRequest,\n IModuleMinificationResult,\n IModuleMinificationSuccessResult,\n IModuleMinifier,\n IModuleMinifierFunction,\n IWorkerPoolMinifierOptions\n} from '@rushstack/module-minifier';\nexport {\n getIdentifier,\n LocalMinifier,\n MessagePortMinifier,\n NoopMinifier,\n WorkerPoolMinifier\n} from '@rushstack/module-minifier';\n"]}
@@ -0,0 +1,78 @@
1
+ // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2
+ // See LICENSE in the project root for license information.
3
+ import * as workerThreads from 'node:worker_threads';
4
+ import { MessagePortMinifier } from '@rushstack/module-minifier';
5
+ import { ModuleMinifierPlugin } from '../ModuleMinifierPlugin';
6
+ import '../OverrideWebpackIdentifierAllocation';
7
+ // Hack to support mkdirp on node 10
8
+ process.umask = () => 0;
9
+ const { configFilePath, sourceMap, usePortableModules } = workerThreads.workerData;
10
+ const webpackConfigs = require(configFilePath);
11
+ // chalk.enabled = enableColor;
12
+ const minifier = new MessagePortMinifier(workerThreads.parentPort);
13
+ async function processTaskAsync(index) {
14
+ const config = webpackConfigs[index];
15
+ // eslint-disable-next-line no-console
16
+ console.log(`Compiling config: ${config.name || (config.output && config.output.filename)}`);
17
+ const optimization = config.optimization || (config.optimization = {});
18
+ const { minimizer } = optimization;
19
+ if (minimizer) {
20
+ for (const plugin of minimizer) {
21
+ if (plugin instanceof ModuleMinifierPlugin) {
22
+ plugin.minifier = minifier;
23
+ }
24
+ }
25
+ }
26
+ else {
27
+ const { devtool, mode } = config;
28
+ const finalSourceMap = typeof sourceMap === 'boolean'
29
+ ? sourceMap
30
+ : typeof devtool === 'string'
31
+ ? devtool.endsWith('source-map') && !devtool.includes('eval')
32
+ : devtool !== false && mode === 'production';
33
+ optimization.minimizer = [
34
+ new ModuleMinifierPlugin({
35
+ minifier,
36
+ usePortableModules,
37
+ sourceMap: finalSourceMap
38
+ })
39
+ ];
40
+ }
41
+ await new Promise((resolve, reject) => {
42
+ const compiler = webpack(config);
43
+ compiler.run(async (err, stats) => {
44
+ if (err) {
45
+ return reject(err);
46
+ }
47
+ if (stats && stats.hasErrors()) {
48
+ const errorStats = stats.toJson('errors-only');
49
+ errorStats.errors.forEach((error) => {
50
+ // eslint-disable-next-line no-console
51
+ console.error(error);
52
+ });
53
+ return reject(new Error(`Webpack failed with ${errorStats.errors.length} error(s).`));
54
+ }
55
+ resolve();
56
+ });
57
+ });
58
+ }
59
+ process.exitCode = 3;
60
+ workerThreads.parentPort.on('message', (message) => {
61
+ // Termination request
62
+ if (message === false) {
63
+ process.exit(0);
64
+ }
65
+ // Input for the MessagePortMinifier
66
+ if (typeof message === 'object') {
67
+ return;
68
+ }
69
+ const index = message;
70
+ processTaskAsync(index).then(() => {
71
+ workerThreads.parentPort.postMessage(index);
72
+ }, (err) => {
73
+ // eslint-disable-next-line no-console
74
+ console.error(err);
75
+ process.exit(1);
76
+ });
77
+ });
78
+ //# sourceMappingURL=WebpackWorker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebpackWorker.js","sourceRoot":"","sources":["../../src/workerPool/WebpackWorker.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as workerThreads from 'node:worker_threads';\n\nimport webpack = require('webpack');\n\nimport { MessagePortMinifier } from '@rushstack/module-minifier';\n\nimport { ModuleMinifierPlugin } from '../ModuleMinifierPlugin';\nimport '../OverrideWebpackIdentifierAllocation';\n\n// Hack to support mkdirp on node 10\nprocess.umask = () => 0;\n\nconst { configFilePath, sourceMap, usePortableModules } = workerThreads.workerData;\n\nconst webpackConfigs: webpack.Configuration[] = require(configFilePath);\n\n// chalk.enabled = enableColor;\n\nconst minifier: MessagePortMinifier = new MessagePortMinifier(workerThreads.parentPort!);\n\nasync function processTaskAsync(index: number): Promise<void> {\n const config: webpack.Configuration = webpackConfigs[index];\n // eslint-disable-next-line no-console\n console.log(`Compiling config: ${config.name || (config.output && config.output.filename)}`);\n\n const optimization: webpack.Options.Optimization = config.optimization || (config.optimization = {});\n const { minimizer } = optimization;\n\n if (minimizer) {\n for (const plugin of minimizer) {\n if (plugin instanceof ModuleMinifierPlugin) {\n plugin.minifier = minifier;\n }\n }\n } else {\n const { devtool, mode } = config;\n\n const finalSourceMap: boolean =\n typeof sourceMap === 'boolean'\n ? sourceMap\n : typeof devtool === 'string'\n ? devtool.endsWith('source-map') && !devtool.includes('eval')\n : devtool !== false && mode === 'production';\n\n optimization.minimizer = [\n new ModuleMinifierPlugin({\n minifier,\n usePortableModules,\n sourceMap: finalSourceMap\n })\n ];\n }\n\n await new Promise<void>((resolve: () => void, reject: (err: Error) => void) => {\n const compiler: webpack.Compiler = webpack(config);\n compiler.run(async (err: Error | undefined, stats: webpack.Stats) => {\n if (err) {\n return reject(err);\n }\n\n if (stats && stats.hasErrors()) {\n const errorStats: webpack.Stats.ToJsonOutput = stats.toJson('errors-only');\n\n errorStats.errors.forEach((error) => {\n // eslint-disable-next-line no-console\n console.error(error);\n });\n\n return reject(new Error(`Webpack failed with ${errorStats.errors.length} error(s).`));\n }\n\n resolve();\n });\n });\n}\n\nprocess.exitCode = 3;\n\nworkerThreads.parentPort!.on('message', (message: number | false | object) => {\n // Termination request\n if (message === false) {\n process.exit(0);\n }\n\n // Input for the MessagePortMinifier\n if (typeof message === 'object') {\n return;\n }\n\n const index: number = message as number;\n\n processTaskAsync(index).then(\n () => {\n workerThreads.parentPort!.postMessage(index);\n },\n (err: Error) => {\n // eslint-disable-next-line no-console\n console.error(err);\n process.exit(1);\n }\n );\n});\n"]}
package/package.json CHANGED
@@ -1,9 +1,30 @@
1
1
  {
2
2
  "name": "@rushstack/webpack4-module-minifier-plugin",
3
- "version": "0.14.13",
3
+ "version": "0.15.0",
4
4
  "description": "This plugin splits minification of webpack compilations into smaller units.",
5
- "main": "lib/index.js",
6
- "typings": "dist/webpack4-module-minifier-plugin.d.ts",
5
+ "main": "./lib-commonjs/index.js",
6
+ "module": "./lib-esm/index.js",
7
+ "types": "./dist/webpack4-module-minifier-plugin.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/webpack4-module-minifier-plugin.d.ts",
11
+ "import": "./lib-esm/index.js",
12
+ "require": "./lib-commonjs/index.js"
13
+ },
14
+ "./lib/*": {
15
+ "types": "./lib-dts/*.d.ts",
16
+ "import": "./lib-esm/*.js",
17
+ "require": "./lib-commonjs/*.js"
18
+ },
19
+ "./package.json": "./package.json"
20
+ },
21
+ "typesVersions": {
22
+ "*": {
23
+ "lib/*": [
24
+ "lib-dts/*"
25
+ ]
26
+ }
27
+ },
7
28
  "license": "MIT",
8
29
  "repository": {
9
30
  "type": "git",
@@ -34,8 +55,8 @@
34
55
  "dependencies": {
35
56
  "@types/tapable": "1.0.6",
36
57
  "tapable": "1.1.3",
37
- "@rushstack/module-minifier": "0.8.13",
38
- "@rushstack/worker-pool": "0.6.13"
58
+ "@rushstack/module-minifier": "0.9.0",
59
+ "@rushstack/worker-pool": "0.7.0"
39
60
  },
40
61
  "devDependencies": {
41
62
  "@types/node": "20.17.19",
@@ -44,11 +65,12 @@
44
65
  "eslint": "~9.37.0",
45
66
  "webpack-sources": "~1.4.3",
46
67
  "webpack": "~4.47.0",
47
- "@rushstack/heft": "1.1.13",
68
+ "@rushstack/heft": "1.2.0",
48
69
  "local-node-rig": "1.0.0"
49
70
  },
50
71
  "sideEffects": [
51
- "./lib/OverrideWebpackIdentifierAllocation"
72
+ "lib-esm/OverrideWebpackIdentifierAllocation.js",
73
+ "lib-commonjs/OverrideWebpackIdentifierAllocation.js"
52
74
  ],
53
75
  "scripts": {
54
76
  "build": "heft build --clean",
File without changes
File without changes