webpack 5.105.4 → 5.106.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 (123) hide show
  1. package/README.md +3 -6
  2. package/lib/BannerPlugin.js +13 -13
  3. package/lib/Chunk.js +25 -0
  4. package/lib/ChunkGraph.js +8 -4
  5. package/lib/CleanPlugin.js +23 -20
  6. package/lib/CompatibilityPlugin.js +1 -1
  7. package/lib/Compilation.js +34 -11
  8. package/lib/Compiler.js +59 -1
  9. package/lib/CssModule.js +17 -2
  10. package/lib/Dependency.js +1 -1
  11. package/lib/DllPlugin.js +17 -17
  12. package/lib/DllReferencePlugin.js +20 -18
  13. package/lib/DotenvPlugin.js +29 -27
  14. package/lib/ExternalModule.js +39 -6
  15. package/lib/FileSystemInfo.js +3 -1
  16. package/lib/IgnorePlugin.js +12 -11
  17. package/lib/LoaderOptionsPlugin.js +17 -15
  18. package/lib/ManifestPlugin.js +27 -25
  19. package/lib/Module.js +69 -4
  20. package/lib/ModuleGraph.js +3 -0
  21. package/lib/ModuleParseError.js +1 -1
  22. package/lib/ModuleTypeConstants.js +1 -1
  23. package/lib/NormalModule.js +7 -3
  24. package/lib/NormalModuleFactory.js +20 -1
  25. package/lib/ProgressPlugin.js +39 -29
  26. package/lib/RuntimeGlobals.js +6 -0
  27. package/lib/RuntimeTemplate.js +1 -1
  28. package/lib/SourceMapDevToolPlugin.js +13 -11
  29. package/lib/TemplatedPathPlugin.js +4 -3
  30. package/lib/WatchIgnorePlugin.js +15 -13
  31. package/lib/WebpackOptionsApply.js +4 -4
  32. package/lib/asset/AssetModulesPlugin.js +50 -29
  33. package/lib/cli.js +3 -1
  34. package/lib/config/defaults.js +27 -13
  35. package/lib/config/normalization.js +3 -2
  36. package/lib/container/ContainerPlugin.js +46 -42
  37. package/lib/container/ContainerReferencePlugin.js +42 -26
  38. package/lib/container/FallbackModule.js +1 -1
  39. package/lib/container/ModuleFederationPlugin.js +17 -13
  40. package/lib/css/CssGenerator.js +306 -192
  41. package/lib/css/CssInjectStyleRuntimeModule.js +179 -0
  42. package/lib/css/CssLoadingRuntimeModule.js +1 -4
  43. package/lib/css/CssModulesPlugin.js +197 -98
  44. package/lib/css/CssParser.js +231 -134
  45. package/lib/css/walkCssTokens.js +115 -12
  46. package/lib/debug/ProfilingPlugin.js +16 -13
  47. package/lib/dependencies/AMDDefineDependencyParserPlugin.js +20 -15
  48. package/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +4 -3
  49. package/lib/dependencies/CommonJsExportRequireDependency.js +4 -2
  50. package/lib/dependencies/CommonJsExportsDependency.js +1 -1
  51. package/lib/dependencies/CommonJsExportsParserPlugin.js +1 -1
  52. package/lib/dependencies/CommonJsFullRequireDependency.js +1 -1
  53. package/lib/dependencies/CommonJsImportsParserPlugin.js +63 -2
  54. package/lib/dependencies/CommonJsRequireContextDependency.js +21 -0
  55. package/lib/dependencies/CommonJsRequireDependency.js +42 -1
  56. package/lib/dependencies/CommonJsSelfReferenceDependency.js +1 -1
  57. package/lib/dependencies/ContextElementDependency.js +1 -1
  58. package/lib/dependencies/CssIcssExportDependency.js +210 -87
  59. package/lib/dependencies/CssIcssImportDependency.js +13 -70
  60. package/lib/dependencies/CssIcssSymbolDependency.js +19 -30
  61. package/lib/dependencies/HarmonyExportDependencyParserPlugin.js +13 -2
  62. package/lib/dependencies/HarmonyExportExpressionDependency.js +28 -2
  63. package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +13 -3
  64. package/lib/dependencies/HarmonyExportInitFragment.js +1 -1
  65. package/lib/dependencies/HarmonyImportDependency.js +21 -8
  66. package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +4 -1
  67. package/lib/dependencies/HarmonyImportSideEffectDependency.js +2 -2
  68. package/lib/dependencies/HarmonyImportSpecifierDependency.js +13 -2
  69. package/lib/dependencies/ImportContextDependency.js +1 -1
  70. package/lib/dependencies/ImportDependency.js +16 -2
  71. package/lib/dependencies/ImportMetaPlugin.js +39 -29
  72. package/lib/dependencies/ImportParserPlugin.js +4 -5
  73. package/lib/dependencies/ImportPhase.js +65 -22
  74. package/lib/dependencies/RequireEnsureDependenciesBlockParserPlugin.js +1 -1
  75. package/lib/esm/ModuleChunkFormatPlugin.js +1 -4
  76. package/lib/ids/HashedModuleIdsPlugin.js +21 -23
  77. package/lib/ids/OccurrenceChunkIdsPlugin.js +15 -11
  78. package/lib/ids/OccurrenceModuleIdsPlugin.js +15 -11
  79. package/lib/javascript/ArrayPushCallbackChunkFormatPlugin.js +1 -4
  80. package/lib/javascript/CommonJsChunkFormatPlugin.js +1 -4
  81. package/lib/javascript/EnableChunkLoadingPlugin.js +1 -2
  82. package/lib/javascript/JavascriptModulesPlugin.js +38 -12
  83. package/lib/javascript/JavascriptParser.js +5 -3
  84. package/lib/json/JsonModulesPlugin.js +28 -21
  85. package/lib/library/AssignLibraryPlugin.js +1 -1
  86. package/lib/library/ExportPropertyLibraryPlugin.js +1 -1
  87. package/lib/library/ModuleLibraryPlugin.js +35 -13
  88. package/lib/library/SystemLibraryPlugin.js +1 -1
  89. package/lib/node/ReadFileCompileAsyncWasmPlugin.js +22 -0
  90. package/lib/optimize/AggressiveSplittingPlugin.js +18 -31
  91. package/lib/optimize/ConcatenatedModule.js +4 -3
  92. package/lib/optimize/InnerGraphPlugin.js +11 -5
  93. package/lib/optimize/LimitChunkCountPlugin.js +22 -18
  94. package/lib/optimize/MergeDuplicateChunksPlugin.js +15 -12
  95. package/lib/optimize/MinChunkSizePlugin.js +20 -16
  96. package/lib/optimize/RemoveEmptyChunksPlugin.js +0 -1
  97. package/lib/rules/RuleSetCompiler.js +1 -0
  98. package/lib/schemes/HttpUriPlugin.js +20 -11
  99. package/lib/schemes/VirtualUrlPlugin.js +77 -30
  100. package/lib/serialization/FileMiddleware.js +7 -7
  101. package/lib/sharing/ConsumeSharedPlugin.js +32 -25
  102. package/lib/sharing/ProvideSharedPlugin.js +29 -25
  103. package/lib/util/{propertyName.js → property.js} +26 -1
  104. package/lib/wasm-async/AsyncWasmCompileRuntimeModule.js +148 -0
  105. package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +54 -0
  106. package/lib/wasm-async/AsyncWebAssemblyModulesPlugin.js +105 -0
  107. package/lib/wasm-async/AsyncWebAssemblyParser.js +30 -6
  108. package/lib/wasm-async/UniversalCompileAsyncWasmPlugin.js +26 -2
  109. package/lib/web/FetchCompileAsyncWasmPlugin.js +23 -0
  110. package/lib/web/JsonpTemplatePlugin.js +1 -0
  111. package/lib/webpack.js +34 -4
  112. package/package.json +18 -16
  113. package/schemas/WebpackOptions.check.js +1 -1
  114. package/schemas/WebpackOptions.json +82 -22
  115. package/schemas/plugins/css/CssModuleGeneratorOptions.check.js +1 -1
  116. package/schemas/plugins/css/CssModuleParserOptions.check.js +1 -1
  117. package/schemas/plugins/css/CssParserOptions.check.js +1 -1
  118. package/schemas/plugins/optimize/LimitChunkCountPlugin.json +1 -1
  119. package/schemas/plugins/schemes/VirtualUrlPlugin.check.js +1 -1
  120. package/schemas/plugins/schemes/VirtualUrlPlugin.json +8 -0
  121. package/types.d.ts +511 -114
  122. package/lib/util/create-schema-validation.js +0 -41
  123. package/lib/util/propertyAccess.js +0 -30
@@ -14,7 +14,6 @@ const {
14
14
  createInflate
15
15
  } = require("zlib");
16
16
  const NormalModule = require("../NormalModule");
17
- const createSchemaValidation = require("../util/create-schema-validation");
18
17
  const createHash = require("../util/createHash");
19
18
  const { dirname, join, mkdirp } = require("../util/fs");
20
19
  const memoize = require("../util/memoize");
@@ -76,6 +75,13 @@ const proxyFetch = (request, proxy) => (url, options, callback) => {
76
75
  if (res.statusCode === 200) {
77
76
  // connected to proxy server
78
77
  doRequest(socket);
78
+ } else {
79
+ eventEmitter.emit(
80
+ "error",
81
+ new Error(
82
+ `Failed to connect to proxy server "${proxy}": ${res.statusCode} ${res.statusMessage}`
83
+ )
84
+ );
79
85
  }
80
86
  })
81
87
  .on("error", (err) => {
@@ -98,15 +104,6 @@ const proxyFetch = (request, proxy) => (url, options, callback) => {
98
104
  /** @type {InProgressWriteItem[] | undefined} */
99
105
  let inProgressWrite;
100
106
 
101
- const validate = createSchemaValidation(
102
- require("../../schemas/plugins/schemes/HttpUriPlugin.check"),
103
- () => require("../../schemas/plugins/schemes/HttpUriPlugin.json"),
104
- {
105
- name: "Http Uri Plugin",
106
- baseDataPath: "options"
107
- }
108
- );
109
-
110
107
  /**
111
108
  * @param {string} str path
112
109
  * @returns {string} safe path
@@ -446,7 +443,6 @@ class HttpUriPlugin {
446
443
  * @param {HttpUriPluginOptions} options options
447
444
  */
448
445
  constructor(options) {
449
- validate(options);
450
446
  /** @type {HttpUriPluginOptions} */
451
447
  this.options = options;
452
448
  }
@@ -457,6 +453,19 @@ class HttpUriPlugin {
457
453
  * @returns {void}
458
454
  */
459
455
  apply(compiler) {
456
+ compiler.hooks.validate.tap(PLUGIN_NAME, () => {
457
+ compiler.validate(
458
+ () => require("../../schemas/plugins/schemes/HttpUriPlugin.json"),
459
+ this.options,
460
+ {
461
+ name: "Http Uri Plugin",
462
+ baseDataPath: "options"
463
+ },
464
+ (options) =>
465
+ require("../../schemas/plugins/schemes/HttpUriPlugin.check")(options)
466
+ );
467
+ });
468
+
460
469
  const proxy =
461
470
  this.options.proxy || process.env.http_proxy || process.env.HTTP_PROXY;
462
471
  /**
@@ -5,37 +5,33 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const { NormalModule } = require("..");
8
+ const { getContext } = require("loader-runner");
9
+
9
10
  const ModuleNotFoundError = require("../ModuleNotFoundError");
11
+ const NormalModule = require("../NormalModule");
12
+ const { isAbsolute, join } = require("../util/fs");
10
13
  const { parseResourceWithoutFragment } = require("../util/identifier");
11
14
 
12
- /** @typedef {import("../Compiler")} Compiler */
13
- /** @typedef {import("../NormalModule")} NormalModule */
15
+ const DEFAULT_SCHEME = "virtual";
16
+
17
+ const PLUGIN_NAME = "VirtualUrlPlugin";
14
18
 
15
19
  /**
16
- * @template T
17
- * @typedef {import("../../declarations/LoaderContext").LoaderContext<T>} LoaderContext
20
+ * @typedef {import("../Compiler")} Compiler
21
+ * @typedef {import("../../declarations/plugins/schemes/VirtualUrlPlugin").VirtualModule} VirtualModuleConfig
22
+ * @typedef {import("../../declarations/plugins/schemes/VirtualUrlPlugin").VirtualModuleContent} VirtualModuleInput
23
+ * @typedef {import("../../declarations/plugins/schemes/VirtualUrlPlugin").VirtualUrlOptions} VirtualUrlOptions
18
24
  */
19
25
 
20
- const PLUGIN_NAME = "VirtualUrlPlugin";
21
- const DEFAULT_SCHEME = "virtual";
22
-
23
26
  /** @typedef {(loaderContext: LoaderContext<EXPECTED_ANY>) => Promise<string | Buffer> | string | Buffer} SourceFn */
24
27
  /** @typedef {() => string} VersionFn */
28
+ /** @typedef {{ [key: string]: VirtualModuleInput }} VirtualModules */
25
29
 
26
30
  /**
27
- * @typedef {object} VirtualModuleConfig
28
- * @property {string=} type the module type
29
- * @property {SourceFn} source the source function
30
- * @property {VersionFn | true | string=} version optional version function or value
31
- */
32
-
33
- /**
34
- * @typedef {string | SourceFn | VirtualModuleConfig} VirtualModuleInput
31
+ * @template T
32
+ * @typedef {import("../../declarations/LoaderContext").LoaderContext<T>} LoaderContext
35
33
  */
36
34
 
37
- /** @typedef {{ [key: string]: VirtualModuleInput }} VirtualModules */
38
-
39
35
  /**
40
36
  * Normalizes a virtual module definition into a standard format
41
37
  * @param {VirtualModuleInput} virtualConfig The virtual module to normalize
@@ -83,6 +79,16 @@ function toVid(id, scheme) {
83
79
  return `${scheme}:${id}`;
84
80
  }
85
81
 
82
+ /**
83
+ * Converts a virtual module id to a module id
84
+ * @param {string} vid The virtual module id
85
+ * @param {string} scheme The URL scheme
86
+ * @returns {string} The module id
87
+ */
88
+ function fromVid(vid, scheme) {
89
+ return vid.replace(`${scheme}:`, "");
90
+ }
91
+
86
92
  const VALUE_DEP_VERSION = `webpack/${PLUGIN_NAME}/version`;
87
93
 
88
94
  /**
@@ -95,22 +101,26 @@ function toCacheKey(id, scheme) {
95
101
  return `${VALUE_DEP_VERSION}/${toVid(id, scheme)}`;
96
102
  }
97
103
 
98
- /**
99
- * @typedef {object} VirtualUrlPluginOptions
100
- * @property {VirtualModules} modules - The virtual modules
101
- * @property {string=} scheme - The URL scheme to use
102
- */
103
-
104
104
  class VirtualUrlPlugin {
105
105
  /**
106
106
  * @param {VirtualModules} modules The virtual modules
107
- * @param {string=} scheme The URL scheme to use
107
+ * @param {Omit<VirtualUrlOptions, "modules"> | string=} schemeOrOptions The URL scheme to use
108
108
  */
109
- constructor(modules, scheme) {
109
+ constructor(modules, schemeOrOptions) {
110
+ /** @type {VirtualUrlOptions} */
111
+ this.options = {
112
+ modules,
113
+ ...(typeof schemeOrOptions === "string"
114
+ ? { scheme: schemeOrOptions }
115
+ : schemeOrOptions || {})
116
+ };
117
+
110
118
  /** @type {string} */
111
- this.scheme = scheme || DEFAULT_SCHEME;
119
+ this.scheme = this.options.scheme || DEFAULT_SCHEME;
120
+ /** @type {VirtualUrlOptions["context"]} */
121
+ this.context = this.options.context || "auto";
112
122
  /** @type {NormalizedModules} */
113
- this.modules = normalizeModules(modules, this.scheme);
123
+ this.modules = normalizeModules(this.options.modules, this.scheme);
114
124
  }
115
125
 
116
126
  /**
@@ -119,6 +129,21 @@ class VirtualUrlPlugin {
119
129
  * @returns {void}
120
130
  */
121
131
  apply(compiler) {
132
+ compiler.hooks.validate.tap(PLUGIN_NAME, () => {
133
+ compiler.validate(
134
+ () => require("../../schemas/plugins/schemes/VirtualUrlPlugin.json"),
135
+ this.options,
136
+ {
137
+ name: "Virtual Url Plugin",
138
+ baseDataPath: "options"
139
+ },
140
+ (options) =>
141
+ require("../../schemas/plugins/schemes/VirtualUrlPlugin.check")(
142
+ options
143
+ )
144
+ );
145
+ });
146
+
122
147
  const scheme = this.scheme;
123
148
  const cachedParseResourceWithoutFragment =
124
149
  parseResourceWithoutFragment.bindCache(compiler.root);
@@ -157,10 +182,32 @@ class VirtualUrlPlugin {
157
182
  resourceData.resource
158
183
  );
159
184
  const path = url.path;
160
- const type = virtualConfig.type;
185
+ const type = virtualConfig.type || "";
186
+ const context = virtualConfig.context || this.context;
187
+
161
188
  resourceData.path = path + type;
162
189
  resourceData.resource = path;
163
- resourceData.context = compiler.context;
190
+
191
+ if (context === "auto") {
192
+ const context = getContext(path);
193
+ if (context === path) {
194
+ resourceData.context = compiler.context;
195
+ } else {
196
+ const resolvedContext = fromVid(context, scheme);
197
+ resourceData.context = isAbsolute(resolvedContext)
198
+ ? resolvedContext
199
+ : join(
200
+ /** @type {import("..").InputFileSystem} */
201
+ (compiler.inputFileSystem),
202
+ compiler.context,
203
+ resolvedContext
204
+ );
205
+ }
206
+ } else if (context && typeof context === "string") {
207
+ resourceData.context = context;
208
+ } else {
209
+ resourceData.context = compiler.context;
210
+ }
164
211
 
165
212
  if (virtualConfig.version) {
166
213
  const cacheKey = toCacheKey(resourceData.resource, scheme);
@@ -270,15 +270,15 @@ const deserialize = async (middleware, name, readFile) => {
270
270
  nextContent();
271
271
  }
272
272
  while (contentItemLength - contentPosition < n) {
273
- const remaining = contentItem.slice(contentPosition);
273
+ const remaining = contentItem.subarray(contentPosition);
274
274
  let lengthFromNext = n - remaining.length;
275
275
  /** @type {Buffer[]} */
276
276
  const buffers = [remaining];
277
277
  for (let i = contentsIndex + 1; i < contents.length; i++) {
278
278
  const l = contents[i].length;
279
279
  if (l > lengthFromNext) {
280
- buffers.push(contents[i].slice(0, lengthFromNext));
281
- contents[i] = contents[i].slice(lengthFromNext);
280
+ buffers.push(contents[i].subarray(0, lengthFromNext));
281
+ contents[i] = contents[i].subarray(lengthFromNext);
282
282
  lengthFromNext = 0;
283
283
  break;
284
284
  } else {
@@ -326,7 +326,7 @@ const deserialize = async (middleware, name, readFile) => {
326
326
  }
327
327
  return result;
328
328
  }
329
- const result = contentItem.slice(contentPosition, contentPosition + l);
329
+ const result = contentItem.subarray(contentPosition, contentPosition + l);
330
330
  contentPosition += l;
331
331
  // we clone the buffer here to allow the original content to be garbage collected
332
332
  return l * 2 < contentItem.buffer.byteLength ? Buffer.from(result) : result;
@@ -355,7 +355,7 @@ const deserialize = async (middleware, name, readFile) => {
355
355
  if (length < 0) {
356
356
  const slice = readSlice(-length);
357
357
  const size = Number(readUInt64LE(slice, 0));
358
- const nameBuffer = slice.slice(8);
358
+ const nameBuffer = slice.subarray(8);
359
359
  const name = nameBuffer.toString();
360
360
  const lazy =
361
361
  /** @type {LazyFunction} */
@@ -510,7 +510,7 @@ class FileMiddleware extends SerializerMiddleware {
510
510
  chunks.push(b);
511
511
  } else {
512
512
  for (let i = 0; i < b.length; i += WRITE_LIMIT_CHUNK) {
513
- chunks.push(b.slice(i, i + WRITE_LIMIT_CHUNK));
513
+ chunks.push(b.subarray(i, i + WRITE_LIMIT_CHUNK));
514
514
  }
515
515
  }
516
516
  }
@@ -701,7 +701,7 @@ class FileMiddleware extends SerializerMiddleware {
701
701
  /** @type {number} */ (currentBufferUsed);
702
702
  // values passed to fs.read must be valid int32 values
703
703
  if (readOffset > 0x7fffffff) {
704
- readBuffer = currentBuffer.slice(readOffset);
704
+ readBuffer = currentBuffer.subarray(readOffset);
705
705
  readOffset = 0;
706
706
  }
707
707
  if (readLength > 0x7fffffff) {
@@ -10,7 +10,6 @@ const RuntimeGlobals = require("../RuntimeGlobals");
10
10
  const WebpackError = require("../WebpackError");
11
11
  const { parseOptions } = require("../container/options");
12
12
  const LazySet = require("../util/LazySet");
13
- const createSchemaValidation = require("../util/create-schema-validation");
14
13
  const { parseRange } = require("../util/semver");
15
14
  const ConsumeSharedFallbackDependency = require("./ConsumeSharedFallbackDependency");
16
15
  const ConsumeSharedModule = require("./ConsumeSharedModule");
@@ -32,15 +31,6 @@ const {
32
31
  /** @typedef {import("./ConsumeSharedModule").ConsumeOptions} ConsumeOptions */
33
32
  /** @typedef {import("./utils").DescriptionFile} DescriptionFile */
34
33
 
35
- const validate = createSchemaValidation(
36
- require("../../schemas/plugins/sharing/ConsumeSharedPlugin.check"),
37
- () => require("../../schemas/plugins/sharing/ConsumeSharedPlugin.json"),
38
- {
39
- name: "Consume Shared Plugin",
40
- baseDataPath: "options"
41
- }
42
- );
43
-
44
34
  /** @type {ResolveOptionsWithDependencyType} */
45
35
  const RESOLVE_OPTIONS = { dependencyType: "esm" };
46
36
  const PLUGIN_NAME = "ConsumeSharedPlugin";
@@ -50,13 +40,37 @@ class ConsumeSharedPlugin {
50
40
  * @param {ConsumeSharedPluginOptions} options options
51
41
  */
52
42
  constructor(options) {
53
- if (typeof options !== "string") {
54
- validate(options);
43
+ this.options = options;
44
+ }
45
+
46
+ /**
47
+ * Apply the plugin
48
+ * @param {Compiler} compiler the compiler instance
49
+ * @returns {void}
50
+ */
51
+ apply(compiler) {
52
+ // TODO webpack 6 remove string support
53
+ if (typeof this.options !== "string") {
54
+ compiler.hooks.validate.tap(PLUGIN_NAME, () => {
55
+ compiler.validate(
56
+ () =>
57
+ require("../../schemas/plugins/sharing/ConsumeSharedPlugin.json"),
58
+ this.options,
59
+ {
60
+ name: "Consume Shared Plugin",
61
+ baseDataPath: "options"
62
+ },
63
+ (options) =>
64
+ require("../../schemas/plugins/sharing/ConsumeSharedPlugin.check")(
65
+ options
66
+ )
67
+ );
68
+ });
55
69
  }
56
70
 
57
71
  /** @type {[string, ConsumeOptions][]} */
58
- this._consumes = parseOptions(
59
- options.consumes,
72
+ const consumes = parseOptions(
73
+ this.options.consumes,
60
74
  (item, key) => {
61
75
  if (Array.isArray(item)) throw new Error("Unexpected array in options");
62
76
  /** @type {ConsumeOptions} */
@@ -65,7 +79,7 @@ class ConsumeSharedPlugin {
65
79
  ? // item is a request/key
66
80
  {
67
81
  import: key,
68
- shareScope: options.shareScope || "default",
82
+ shareScope: this.options.shareScope || "default",
69
83
  shareKey: key,
70
84
  requiredVersion: undefined,
71
85
  packageName: undefined,
@@ -77,7 +91,7 @@ class ConsumeSharedPlugin {
77
91
  // item is a version
78
92
  {
79
93
  import: key,
80
- shareScope: options.shareScope || "default",
94
+ shareScope: this.options.shareScope || "default",
81
95
  shareKey: key,
82
96
  requiredVersion: parseRange(item),
83
97
  strictVersion: true,
@@ -89,7 +103,7 @@ class ConsumeSharedPlugin {
89
103
  },
90
104
  (item, key) => ({
91
105
  import: item.import === false ? undefined : item.import || key,
92
- shareScope: item.shareScope || options.shareScope || "default",
106
+ shareScope: item.shareScope || this.options.shareScope || "default",
93
107
  shareKey: item.shareKey || key,
94
108
  requiredVersion:
95
109
  typeof item.requiredVersion === "string"
@@ -104,14 +118,7 @@ class ConsumeSharedPlugin {
104
118
  eager: Boolean(item.eager)
105
119
  })
106
120
  );
107
- }
108
121
 
109
- /**
110
- * Apply the plugin
111
- * @param {Compiler} compiler the compiler instance
112
- * @returns {void}
113
- */
114
- apply(compiler) {
115
122
  compiler.hooks.thisCompilation.tap(
116
123
  PLUGIN_NAME,
117
124
  (compilation, { normalModuleFactory }) => {
@@ -128,7 +135,7 @@ class ConsumeSharedPlugin {
128
135
  let resolvedConsumes;
129
136
  /** @type {Consumes} */
130
137
  let prefixedConsumes;
131
- const promise = resolveMatchedConfigs(compilation, this._consumes).then(
138
+ const promise = resolveMatchedConfigs(compilation, consumes).then(
132
139
  ({ resolved, unresolved, prefixed }) => {
133
140
  resolvedConsumes = resolved;
134
141
  unresolvedConsumes = unresolved;
@@ -7,7 +7,6 @@
7
7
 
8
8
  const WebpackError = require("../WebpackError");
9
9
  const { parseOptions } = require("../container/options");
10
- const createSchemaValidation = require("../util/create-schema-validation");
11
10
  const ProvideForSharedDependency = require("./ProvideForSharedDependency");
12
11
  const ProvideSharedDependency = require("./ProvideSharedDependency");
13
12
  const ProvideSharedModuleFactory = require("./ProvideSharedModuleFactory");
@@ -17,15 +16,6 @@ const ProvideSharedModuleFactory = require("./ProvideSharedModuleFactory");
17
16
  /** @typedef {import("../Compiler")} Compiler */
18
17
  /** @typedef {import("../NormalModuleFactory").NormalModuleCreateData} NormalModuleCreateData */
19
18
 
20
- const validate = createSchemaValidation(
21
- require("../../schemas/plugins/sharing/ProvideSharedPlugin.check"),
22
- () => require("../../schemas/plugins/sharing/ProvideSharedPlugin.json"),
23
- {
24
- name: "Provide Shared Plugin",
25
- baseDataPath: "options"
26
- }
27
- );
28
-
29
19
  /**
30
20
  * @typedef {object} ProvideOptions
31
21
  * @property {string} shareKey
@@ -43,11 +33,33 @@ class ProvideSharedPlugin {
43
33
  * @param {ProvideSharedPluginOptions} options options
44
34
  */
45
35
  constructor(options) {
46
- validate(options);
36
+ this.options = options;
37
+ }
38
+
39
+ /**
40
+ * Apply the plugin
41
+ * @param {Compiler} compiler the compiler instance
42
+ * @returns {void}
43
+ */
44
+ apply(compiler) {
45
+ compiler.hooks.validate.tap(PLUGIN_NAME, () => {
46
+ compiler.validate(
47
+ () => require("../../schemas/plugins/sharing/ProvideSharedPlugin.json"),
48
+ this.options,
49
+ {
50
+ name: "Provide Shared Plugin",
51
+ baseDataPath: "options"
52
+ },
53
+ (options) =>
54
+ require("../../schemas/plugins/sharing/ProvideSharedPlugin.check")(
55
+ options
56
+ )
57
+ );
58
+ });
47
59
 
48
60
  /** @type {[string, ProvideOptions][]} */
49
- this._provides = parseOptions(
50
- options.provides,
61
+ const provides = parseOptions(
62
+ this.options.provides,
51
63
  (item) => {
52
64
  if (Array.isArray(item)) {
53
65
  throw new Error("Unexpected array of provides");
@@ -56,7 +68,7 @@ class ProvideSharedPlugin {
56
68
  const result = {
57
69
  shareKey: item,
58
70
  version: undefined,
59
- shareScope: options.shareScope || "default",
71
+ shareScope: this.options.shareScope || "default",
60
72
  eager: false
61
73
  };
62
74
  return result;
@@ -64,23 +76,15 @@ class ProvideSharedPlugin {
64
76
  (item) => ({
65
77
  shareKey: /** @type {string} */ (item.shareKey),
66
78
  version: item.version,
67
- shareScope: item.shareScope || options.shareScope || "default",
79
+ shareScope: item.shareScope || this.options.shareScope || "default",
68
80
  eager: Boolean(item.eager)
69
81
  })
70
- );
71
- this._provides.sort(([a], [b]) => {
82
+ ).sort(([a], [b]) => {
72
83
  if (a < b) return -1;
73
84
  if (b < a) return 1;
74
85
  return 0;
75
86
  });
76
- }
77
87
 
78
- /**
79
- * Apply the plugin
80
- * @param {Compiler} compiler the compiler instance
81
- * @returns {void}
82
- */
83
- apply(compiler) {
84
88
  /** @type {WeakMap<Compilation, ResolvedProvideMap>} */
85
89
  const compilationData = new WeakMap();
86
90
 
@@ -93,7 +97,7 @@ class ProvideSharedPlugin {
93
97
  const matchProvides = new Map();
94
98
  /** @type {Map<string, ProvideOptions>} */
95
99
  const prefixMatchProvides = new Map();
96
- for (const [request, config] of this._provides) {
100
+ for (const [request, config] of provides) {
97
101
  if (/^(?:\/|[A-Z]:\\|\\\\|\.\.?(?:\/|$))/i.test(request)) {
98
102
  // relative request
99
103
  resolvedProvideMap.set(request, {
@@ -73,4 +73,29 @@ const propertyName = (prop) => {
73
73
  return JSON.stringify(prop);
74
74
  };
75
75
 
76
- module.exports = { RESERVED_IDENTIFIER, SAFE_IDENTIFIER, propertyName };
76
+ /**
77
+ * @param {ArrayLike<string>} properties properties
78
+ * @param {number} start start index
79
+ * @returns {string} chain of property accesses
80
+ */
81
+ const propertyAccess = (properties, start = 0) => {
82
+ let str = "";
83
+ for (let i = start; i < properties.length; i++) {
84
+ const p = properties[i];
85
+ if (`${Number(p)}` === p) {
86
+ str += `[${p}]`;
87
+ } else if (SAFE_IDENTIFIER.test(p) && !RESERVED_IDENTIFIER.has(p)) {
88
+ str += `.${p}`;
89
+ } else {
90
+ str += `[${JSON.stringify(p)}]`;
91
+ }
92
+ }
93
+ return str;
94
+ };
95
+
96
+ module.exports = {
97
+ RESERVED_IDENTIFIER,
98
+ SAFE_IDENTIFIER,
99
+ propertyAccess,
100
+ propertyName
101
+ };
@@ -0,0 +1,148 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const RuntimeGlobals = require("../RuntimeGlobals");
9
+ const RuntimeModule = require("../RuntimeModule");
10
+ const Template = require("../Template");
11
+
12
+ /** @typedef {import("../Chunk")} Chunk */
13
+ /** @typedef {import("../Compilation")} Compilation */
14
+
15
+ /** @typedef {(wasmModuleSrcPath: string) => string} GenerateBeforeLoadBinaryCode */
16
+ /** @typedef {(wasmModuleSrcPath: string) => string} GenerateLoadBinaryCode */
17
+ /** @typedef {() => string} GenerateBeforeCompileStreaming */
18
+
19
+ /**
20
+ * @typedef {object} AsyncWasmCompileRuntimeModuleOptions
21
+ * @property {GenerateLoadBinaryCode} generateLoadBinaryCode
22
+ * @property {GenerateBeforeLoadBinaryCode=} generateBeforeLoadBinaryCode
23
+ * @property {GenerateBeforeCompileStreaming=} generateBeforeCompileStreaming
24
+ * @property {boolean} supportsStreaming
25
+ */
26
+
27
+ class AsyncWasmCompileRuntimeModule extends RuntimeModule {
28
+ /**
29
+ * @param {AsyncWasmCompileRuntimeModuleOptions} options options
30
+ */
31
+ constructor({
32
+ generateLoadBinaryCode,
33
+ generateBeforeLoadBinaryCode,
34
+ generateBeforeCompileStreaming,
35
+ supportsStreaming
36
+ }) {
37
+ super("wasm compile", RuntimeModule.STAGE_NORMAL);
38
+ /** @type {GenerateLoadBinaryCode} */
39
+ this.generateLoadBinaryCode = generateLoadBinaryCode;
40
+ /** @type {GenerateBeforeLoadBinaryCode | undefined} */
41
+ this.generateBeforeLoadBinaryCode = generateBeforeLoadBinaryCode;
42
+ /** @type {GenerateBeforeCompileStreaming | undefined} */
43
+ this.generateBeforeCompileStreaming = generateBeforeCompileStreaming;
44
+ /** @type {boolean} */
45
+ this.supportsStreaming = supportsStreaming;
46
+ }
47
+
48
+ /**
49
+ * @returns {string | null} runtime code
50
+ */
51
+ generate() {
52
+ const compilation = /** @type {Compilation} */ (this.compilation);
53
+ const chunk = /** @type {Chunk} */ (this.chunk);
54
+ const { outputOptions, runtimeTemplate } = compilation;
55
+ const fn = RuntimeGlobals.compileWasm;
56
+ const wasmModuleSrcPath = compilation.getPath(
57
+ JSON.stringify(outputOptions.webassemblyModuleFilename),
58
+ {
59
+ hash: `" + ${RuntimeGlobals.getFullHash}() + "`,
60
+ hashWithLength: (length) =>
61
+ `" + ${RuntimeGlobals.getFullHash}}().slice(0, ${length}) + "`,
62
+ module: {
63
+ id: '" + wasmModuleId + "',
64
+ hash: '" + wasmModuleHash + "',
65
+ hashWithLength(length) {
66
+ return `" + wasmModuleHash.slice(0, ${length}) + "`;
67
+ }
68
+ },
69
+ runtime: chunk.runtime
70
+ }
71
+ );
72
+
73
+ const loader = this.generateLoadBinaryCode(wasmModuleSrcPath);
74
+
75
+ // Fallback path: fetch -> arrayBuffer -> WebAssembly.compile
76
+ const fallback = [
77
+ `.then(${runtimeTemplate.returningFunction("x.arrayBuffer()", "x")})`,
78
+ `.then(${runtimeTemplate.returningFunction(
79
+ "WebAssembly.compile(bytes)",
80
+ "bytes"
81
+ )})`
82
+ ];
83
+
84
+ const getStreaming = () => {
85
+ /**
86
+ * @param {string[]} text text
87
+ * @returns {string} merged text
88
+ */
89
+ const concat = (...text) => text.join("");
90
+ return [
91
+ this.generateBeforeLoadBinaryCode
92
+ ? this.generateBeforeLoadBinaryCode(wasmModuleSrcPath)
93
+ : "",
94
+ `var req = ${loader};`,
95
+ `var fallback = ${runtimeTemplate.returningFunction(
96
+ Template.asString(["req", Template.indent(fallback)])
97
+ )};`,
98
+ concat(
99
+ "return req.then(",
100
+ runtimeTemplate.basicFunction("res", [
101
+ 'if (typeof WebAssembly.compileStreaming === "function") {',
102
+ Template.indent(
103
+ this.generateBeforeCompileStreaming
104
+ ? this.generateBeforeCompileStreaming()
105
+ : ""
106
+ ),
107
+ Template.indent([
108
+ "return WebAssembly.compileStreaming(res)",
109
+ Template.indent([
110
+ ".catch(",
111
+ Template.indent([
112
+ runtimeTemplate.basicFunction("e", [
113
+ 'if(res.headers.get("Content-Type") !== "application/wasm") {',
114
+ Template.indent([
115
+ 'console.warn("`WebAssembly.compileStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.compile` which is slower. Original error:\\n", e);',
116
+ "return fallback();"
117
+ ]),
118
+ "}",
119
+ "throw e;"
120
+ ])
121
+ ]),
122
+ ");"
123
+ ])
124
+ ]),
125
+ "}",
126
+ "return fallback();"
127
+ ]),
128
+ ");"
129
+ )
130
+ ];
131
+ };
132
+
133
+ return `${fn} = ${runtimeTemplate.basicFunction(
134
+ "wasmModuleId, wasmModuleHash",
135
+ this.supportsStreaming
136
+ ? getStreaming()
137
+ : [
138
+ this.generateBeforeLoadBinaryCode
139
+ ? this.generateBeforeLoadBinaryCode(wasmModuleSrcPath)
140
+ : "",
141
+ `return ${loader}`,
142
+ `${Template.indent(fallback)};`
143
+ ]
144
+ )};`;
145
+ }
146
+ }
147
+
148
+ module.exports = AsyncWasmCompileRuntimeModule;