webpack 5.80.0 → 5.82.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.
Potentially problematic release.
This version of webpack might be problematic. Click here for more details.
- package/bin/webpack.js +13 -2
- package/lib/AsyncDependenciesBlock.js +8 -0
- package/lib/CodeGenerationResults.js +2 -2
- package/lib/Compilation.js +4 -2
- package/lib/ContextModule.js +8 -0
- package/lib/CssModule.js +169 -0
- package/lib/DefinePlugin.js +81 -44
- package/lib/DelegatedModule.js +5 -0
- package/lib/DependenciesBlock.js +8 -0
- package/lib/Dependency.js +8 -0
- package/lib/DllModule.js +8 -0
- package/lib/ExportsInfo.js +3 -0
- package/lib/ExternalModule.js +8 -0
- package/lib/FileSystemInfo.js +8 -0
- package/lib/LoaderOptionsPlugin.js +12 -2
- package/lib/Module.js +8 -0
- package/lib/ModuleBuildError.js +9 -0
- package/lib/ModuleError.js +9 -0
- package/lib/ModuleFilenameHelpers.js +113 -4
- package/lib/ModuleParseError.js +9 -0
- package/lib/ModuleTypeConstants.js +21 -0
- package/lib/ModuleWarning.js +9 -0
- package/lib/NormalModule.js +8 -0
- package/lib/NormalModuleFactory.js +15 -3
- package/lib/RawModule.js +8 -0
- package/lib/WebpackError.js +8 -0
- package/lib/WebpackOptionsApply.js +33 -40
- package/lib/asset/RawDataUrlModule.js +8 -0
- package/lib/cache/MemoryWithGcCachePlugin.js +2 -0
- package/lib/cache/ResolverCachePlugin.js +3 -0
- package/lib/config/defaults.js +1 -0
- package/lib/config/normalization.js +1 -0
- package/lib/container/ContainerEntryModule.js +5 -0
- package/lib/container/ContainerExposedDependency.js +9 -0
- package/lib/container/FallbackDependency.js +6 -0
- package/lib/container/FallbackModule.js +5 -0
- package/lib/container/RemoteModule.js +5 -0
- package/lib/css/CssGenerator.js +4 -0
- package/lib/css/CssLoadingRuntimeModule.js +9 -2
- package/lib/css/CssModulesPlugin.js +201 -57
- package/lib/css/CssParser.js +270 -147
- package/lib/css/walkCssTokens.js +121 -65
- package/lib/debug/ProfilingPlugin.js +2 -0
- package/lib/dependencies/AMDDefineDependency.js +8 -0
- package/lib/dependencies/AMDRequireArrayDependency.js +8 -0
- package/lib/dependencies/AMDRequireContextDependency.js +9 -0
- package/lib/dependencies/AMDRequireDependency.js +8 -0
- package/lib/dependencies/CachedConstDependency.js +8 -0
- package/lib/dependencies/CommonJsDependencyHelpers.js +9 -0
- package/lib/dependencies/CommonJsExportRequireDependency.js +8 -0
- package/lib/dependencies/CommonJsExportsDependency.js +8 -0
- package/lib/dependencies/CommonJsExportsParserPlugin.js +65 -3
- package/lib/dependencies/CommonJsFullRequireDependency.js +8 -0
- package/lib/dependencies/CommonJsRequireContextDependency.js +9 -0
- package/lib/dependencies/CommonJsSelfReferenceDependency.js +8 -0
- package/lib/dependencies/ConstDependency.js +8 -0
- package/lib/dependencies/ContextDependency.js +8 -0
- package/lib/dependencies/ContextElementDependency.js +8 -0
- package/lib/dependencies/CreateScriptUrlDependency.js +8 -0
- package/lib/dependencies/CssExportDependency.js +8 -0
- package/lib/dependencies/CssImportDependency.js +52 -1
- package/lib/dependencies/CssLocalIdentifierDependency.js +8 -0
- package/lib/dependencies/CssSelfLocalIdentifierDependency.js +8 -0
- package/lib/dependencies/CssUrlDependency.js +8 -0
- package/lib/dependencies/DllEntryDependency.js +9 -0
- package/lib/dependencies/ExportsInfoDependency.js +5 -0
- package/lib/dependencies/HarmonyAcceptDependency.js +8 -0
- package/lib/dependencies/HarmonyEvaluatedImportSpecifierDependency.js +8 -0
- package/lib/dependencies/HarmonyExportExpressionDependency.js +8 -0
- package/lib/dependencies/HarmonyExportHeaderDependency.js +8 -0
- package/lib/dependencies/HarmonyExportImportedSpecifierDependency.js +14 -0
- package/lib/dependencies/HarmonyExportSpecifierDependency.js +8 -0
- package/lib/dependencies/HarmonyImportDependency.js +8 -0
- package/lib/dependencies/HarmonyImportDependencyParserPlugin.js +1 -0
- package/lib/dependencies/HarmonyImportSpecifierDependency.js +8 -0
- package/lib/dependencies/ImportContextDependency.js +9 -0
- package/lib/dependencies/ImportDependency.js +8 -0
- package/lib/dependencies/JsonExportsDependency.js +8 -0
- package/lib/dependencies/LocalModuleDependency.js +8 -0
- package/lib/dependencies/ModuleDecoratorDependency.js +8 -0
- package/lib/dependencies/ModuleDependency.js +8 -0
- package/lib/dependencies/ProvidedDependency.js +8 -0
- package/lib/dependencies/PureExpressionDependency.js +8 -0
- package/lib/dependencies/RequireEnsureDependency.js +8 -0
- package/lib/dependencies/RequireHeaderDependency.js +5 -0
- package/lib/dependencies/RequireResolveContextDependency.js +9 -0
- package/lib/dependencies/RequireResolveHeaderDependency.js +5 -0
- package/lib/dependencies/RuntimeRequirementsDependency.js +8 -0
- package/lib/dependencies/StaticExportsDependency.js +8 -0
- package/lib/dependencies/URLDependency.js +8 -0
- package/lib/dependencies/UnsupportedDependency.js +8 -0
- package/lib/dependencies/WebAssemblyExportImportedDependency.js +8 -0
- package/lib/dependencies/WebAssemblyImportDependency.js +8 -0
- package/lib/dependencies/WorkerDependency.js +8 -0
- package/lib/index.js +1 -0
- package/lib/javascript/BasicEvaluatedExpression.js +108 -1
- package/lib/javascript/JavascriptParser.js +133 -12
- package/lib/json/JsonData.js +25 -0
- package/lib/json/JsonGenerator.js +15 -3
- package/lib/json/JsonModulesPlugin.js +1 -0
- package/lib/json/JsonParser.js +2 -1
- package/lib/library/ModuleLibraryPlugin.js +2 -1
- package/lib/optimize/RealContentHashPlugin.js +6 -0
- package/lib/runtime/AutoPublicPathRuntimeModule.js +6 -1
- package/lib/runtime/GetChunkFilenameRuntimeModule.js +4 -0
- package/lib/runtime/GetTrustedTypesPolicyRuntimeModule.js +22 -3
- package/lib/schemes/DataUriPlugin.js +4 -0
- package/lib/schemes/HttpUriPlugin.js +38 -0
- package/lib/serialization/ObjectMiddleware.js +2 -0
- package/lib/sharing/ConsumeSharedModule.js +8 -0
- package/lib/sharing/ConsumeSharedRuntimeModule.js +9 -3
- package/lib/sharing/ProvideSharedDependency.js +6 -0
- package/lib/sharing/ProvideSharedModule.js +5 -0
- package/lib/sharing/ShareRuntimeModule.js +7 -4
- package/lib/sharing/utils.js +293 -7
- package/lib/stats/DefaultStatsPrinterPlugin.js +25 -0
- package/lib/util/LazySet.js +10 -2
- package/lib/util/MapHelpers.js +19 -5
- package/lib/util/StackedCacheMap.js +6 -0
- package/lib/util/StringXor.js +51 -0
- package/lib/util/binarySearchBounds.js +49 -0
- package/lib/util/compileBooleanMatcher.js +31 -0
- package/lib/util/deprecation.js +8 -0
- package/lib/util/identifier.js +4 -0
- package/lib/util/internalSerializables.js +1 -0
- package/lib/util/numberHash.js +75 -21
- package/lib/util/propertyAccess.js +5 -0
- package/lib/util/semver.js +1 -1
- package/lib/wasm/EnableWasmLoadingPlugin.js +4 -0
- package/lib/wasm-async/AsyncWebAssemblyJavascriptGenerator.js +1 -0
- package/lib/wasm-async/AsyncWebAssemblyParser.js +1 -1
- package/package.json +4 -5
- package/schemas/WebpackOptions.check.js +1 -1
- package/schemas/WebpackOptions.json +33 -0
- package/types.d.ts +176 -48
package/lib/sharing/utils.js
CHANGED
@@ -9,13 +9,299 @@ const { join, dirname, readJson } = require("../util/fs");
|
|
9
9
|
|
10
10
|
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
11
11
|
|
12
|
+
// Extreme shorthand only for github. eg: foo/bar
|
13
|
+
const RE_URL_GITHUB_EXTREME_SHORT = /^[^/@:.\s][^/@:\s]*\/[^@:\s]*[^/@:\s]#\S+/;
|
14
|
+
|
15
|
+
// Short url with specific protocol. eg: github:foo/bar
|
16
|
+
const RE_GIT_URL_SHORT = /^(github|gitlab|bitbucket|gist):\/?[^/.]+\/?/i;
|
17
|
+
|
18
|
+
// Currently supported protocols
|
19
|
+
const RE_PROTOCOL =
|
20
|
+
/^((git\+)?(ssh|https?|file)|git|github|gitlab|bitbucket|gist):$/i;
|
21
|
+
|
22
|
+
// Has custom protocol
|
23
|
+
const RE_CUSTOM_PROTOCOL = /^((git\+)?(ssh|https?|file)|git):\/\//i;
|
24
|
+
|
25
|
+
// Valid hash format for npm / yarn ...
|
26
|
+
const RE_URL_HASH_VERSION = /#(?:semver:)?(.+)/;
|
27
|
+
|
28
|
+
// Simple hostname validate
|
29
|
+
const RE_HOSTNAME = /^(?:[^/.]+(\.[^/]+)+|localhost)$/;
|
30
|
+
|
31
|
+
// For hostname with colon. eg: ssh://user@github.com:foo/bar
|
32
|
+
const RE_HOSTNAME_WITH_COLON =
|
33
|
+
/([^/@#:.]+(?:\.[^/@#:.]+)+|localhost):([^#/0-9]+)/;
|
34
|
+
|
35
|
+
// Reg for url without protocol
|
36
|
+
const RE_NO_PROTOCOL = /^([^/@#:.]+(?:\.[^/@#:.]+)+)/;
|
37
|
+
|
38
|
+
// RegExp for version string
|
39
|
+
const VERSION_PATTERN_REGEXP = /^([\d^=v<>~]|[*xX]$)/;
|
40
|
+
|
41
|
+
// Specific protocol for short url without normal hostname
|
42
|
+
const PROTOCOLS_FOR_SHORT = [
|
43
|
+
"github:",
|
44
|
+
"gitlab:",
|
45
|
+
"bitbucket:",
|
46
|
+
"gist:",
|
47
|
+
"file:"
|
48
|
+
];
|
49
|
+
|
50
|
+
// Default protocol for git url
|
51
|
+
const DEF_GIT_PROTOCOL = "git+ssh://";
|
52
|
+
|
53
|
+
// thanks to https://github.com/npm/hosted-git-info/blob/latest/git-host-info.js
|
54
|
+
const extractCommithashByDomain = {
|
55
|
+
"github.com": (pathname, hash) => {
|
56
|
+
let [, user, project, type, commithash] = pathname.split("/", 5);
|
57
|
+
if (type && type !== "tree") {
|
58
|
+
return;
|
59
|
+
}
|
60
|
+
|
61
|
+
if (!type) {
|
62
|
+
commithash = hash;
|
63
|
+
} else {
|
64
|
+
commithash = "#" + commithash;
|
65
|
+
}
|
66
|
+
|
67
|
+
if (project && project.endsWith(".git")) {
|
68
|
+
project = project.slice(0, -4);
|
69
|
+
}
|
70
|
+
|
71
|
+
if (!user || !project) {
|
72
|
+
return;
|
73
|
+
}
|
74
|
+
|
75
|
+
return commithash;
|
76
|
+
},
|
77
|
+
"gitlab.com": (pathname, hash) => {
|
78
|
+
const path = pathname.slice(1);
|
79
|
+
if (path.includes("/-/") || path.includes("/archive.tar.gz")) {
|
80
|
+
return;
|
81
|
+
}
|
82
|
+
|
83
|
+
const segments = path.split("/");
|
84
|
+
let project = segments.pop();
|
85
|
+
if (project.endsWith(".git")) {
|
86
|
+
project = project.slice(0, -4);
|
87
|
+
}
|
88
|
+
|
89
|
+
const user = segments.join("/");
|
90
|
+
if (!user || !project) {
|
91
|
+
return;
|
92
|
+
}
|
93
|
+
|
94
|
+
return hash;
|
95
|
+
},
|
96
|
+
"bitbucket.org": (pathname, hash) => {
|
97
|
+
let [, user, project, aux] = pathname.split("/", 4);
|
98
|
+
if (["get"].includes(aux)) {
|
99
|
+
return;
|
100
|
+
}
|
101
|
+
|
102
|
+
if (project && project.endsWith(".git")) {
|
103
|
+
project = project.slice(0, -4);
|
104
|
+
}
|
105
|
+
|
106
|
+
if (!user || !project) {
|
107
|
+
return;
|
108
|
+
}
|
109
|
+
|
110
|
+
return hash;
|
111
|
+
},
|
112
|
+
"gist.github.com": (pathname, hash) => {
|
113
|
+
let [, user, project, aux] = pathname.split("/", 4);
|
114
|
+
if (aux === "raw") {
|
115
|
+
return;
|
116
|
+
}
|
117
|
+
|
118
|
+
if (!project) {
|
119
|
+
if (!user) {
|
120
|
+
return;
|
121
|
+
}
|
122
|
+
|
123
|
+
project = user;
|
124
|
+
user = null;
|
125
|
+
}
|
126
|
+
|
127
|
+
if (project.endsWith(".git")) {
|
128
|
+
project = project.slice(0, -4);
|
129
|
+
}
|
130
|
+
|
131
|
+
return hash;
|
132
|
+
}
|
133
|
+
};
|
134
|
+
|
135
|
+
/**
|
136
|
+
* extract commit hash from parsed url
|
137
|
+
*
|
138
|
+
* @inner
|
139
|
+
* @param {Object} urlParsed parsed url
|
140
|
+
* @returns {string} commithash
|
141
|
+
*/
|
142
|
+
function getCommithash(urlParsed) {
|
143
|
+
let { hostname, pathname, hash } = urlParsed;
|
144
|
+
hostname = hostname.replace(/^www\./, "");
|
145
|
+
|
146
|
+
try {
|
147
|
+
hash = decodeURIComponent(hash);
|
148
|
+
// eslint-disable-next-line no-empty
|
149
|
+
} catch (e) {}
|
150
|
+
|
151
|
+
if (extractCommithashByDomain[hostname]) {
|
152
|
+
return extractCommithashByDomain[hostname](pathname, hash) || "";
|
153
|
+
}
|
154
|
+
|
155
|
+
return hash;
|
156
|
+
}
|
157
|
+
|
158
|
+
/**
|
159
|
+
* make url right for URL parse
|
160
|
+
*
|
161
|
+
* @inner
|
162
|
+
* @param {string} gitUrl git url
|
163
|
+
* @returns {string} fixed url
|
164
|
+
*/
|
165
|
+
function correctUrl(gitUrl) {
|
166
|
+
// like:
|
167
|
+
// proto://hostname.com:user/repo -> proto://hostname.com/user/repo
|
168
|
+
return gitUrl.replace(RE_HOSTNAME_WITH_COLON, "$1/$2");
|
169
|
+
}
|
170
|
+
|
171
|
+
/**
|
172
|
+
* make url protocol right for URL parse
|
173
|
+
*
|
174
|
+
* @inner
|
175
|
+
* @param {string} gitUrl git url
|
176
|
+
* @returns {string} fixed url
|
177
|
+
*/
|
178
|
+
function correctProtocol(gitUrl) {
|
179
|
+
// eg: github:foo/bar#v1.0. Should not add double slash, in case of error parsed `pathname`
|
180
|
+
if (RE_GIT_URL_SHORT.test(gitUrl)) {
|
181
|
+
return gitUrl;
|
182
|
+
}
|
183
|
+
|
184
|
+
// eg: user@github.com:foo/bar
|
185
|
+
if (!RE_CUSTOM_PROTOCOL.test(gitUrl)) {
|
186
|
+
return `${DEF_GIT_PROTOCOL}${gitUrl}`;
|
187
|
+
}
|
188
|
+
|
189
|
+
return gitUrl;
|
190
|
+
}
|
191
|
+
|
192
|
+
/**
|
193
|
+
* extract git dep version from hash
|
194
|
+
*
|
195
|
+
* @inner
|
196
|
+
* @param {string} hash hash
|
197
|
+
* @returns {string} git dep version
|
198
|
+
*/
|
199
|
+
function getVersionFromHash(hash) {
|
200
|
+
const matched = hash.match(RE_URL_HASH_VERSION);
|
201
|
+
|
202
|
+
return (matched && matched[1]) || "";
|
203
|
+
}
|
204
|
+
|
205
|
+
/**
|
206
|
+
* if string can be decoded
|
207
|
+
*
|
208
|
+
* @inner
|
209
|
+
* @param {string} str str to be checked
|
210
|
+
* @returns {boolean} if can be decoded
|
211
|
+
*/
|
212
|
+
function canBeDecoded(str) {
|
213
|
+
try {
|
214
|
+
decodeURIComponent(str);
|
215
|
+
} catch (e) {
|
216
|
+
return false;
|
217
|
+
}
|
218
|
+
|
219
|
+
return true;
|
220
|
+
}
|
221
|
+
|
222
|
+
/**
|
223
|
+
* get right dep version from git url
|
224
|
+
*
|
225
|
+
* @inner
|
226
|
+
* @param {string} gitUrl git url
|
227
|
+
* @returns {string} dep version
|
228
|
+
*/
|
229
|
+
function getGitUrlVersion(gitUrl) {
|
230
|
+
let oriGitUrl = gitUrl;
|
231
|
+
// github extreme shorthand
|
232
|
+
if (RE_URL_GITHUB_EXTREME_SHORT.test(gitUrl)) {
|
233
|
+
gitUrl = "github:" + gitUrl;
|
234
|
+
} else {
|
235
|
+
gitUrl = correctProtocol(gitUrl);
|
236
|
+
}
|
237
|
+
|
238
|
+
gitUrl = correctUrl(gitUrl);
|
239
|
+
|
240
|
+
let parsed;
|
241
|
+
try {
|
242
|
+
parsed = new URL(gitUrl);
|
243
|
+
// eslint-disable-next-line no-empty
|
244
|
+
} catch (e) {}
|
245
|
+
|
246
|
+
if (!parsed) {
|
247
|
+
return "";
|
248
|
+
}
|
249
|
+
|
250
|
+
const { protocol, hostname, pathname, username, password } = parsed;
|
251
|
+
if (!RE_PROTOCOL.test(protocol)) {
|
252
|
+
return "";
|
253
|
+
}
|
254
|
+
|
255
|
+
// pathname shouldn't be empty or URL malformed
|
256
|
+
if (!pathname || !canBeDecoded(pathname)) {
|
257
|
+
return "";
|
258
|
+
}
|
259
|
+
|
260
|
+
// without protocol, there should have auth info
|
261
|
+
if (RE_NO_PROTOCOL.test(oriGitUrl) && !username && !password) {
|
262
|
+
return "";
|
263
|
+
}
|
264
|
+
|
265
|
+
if (!PROTOCOLS_FOR_SHORT.includes(protocol.toLowerCase())) {
|
266
|
+
if (!RE_HOSTNAME.test(hostname)) {
|
267
|
+
return "";
|
268
|
+
}
|
269
|
+
|
270
|
+
const commithash = getCommithash(parsed);
|
271
|
+
return getVersionFromHash(commithash) || commithash;
|
272
|
+
}
|
273
|
+
|
274
|
+
// for protocol short
|
275
|
+
return getVersionFromHash(gitUrl);
|
276
|
+
}
|
277
|
+
|
12
278
|
/**
|
13
279
|
* @param {string} str maybe required version
|
14
280
|
* @returns {boolean} true, if it looks like a version
|
15
281
|
*/
|
16
|
-
|
17
|
-
return
|
18
|
-
}
|
282
|
+
function isRequiredVersion(str) {
|
283
|
+
return VERSION_PATTERN_REGEXP.test(str);
|
284
|
+
}
|
285
|
+
|
286
|
+
exports.isRequiredVersion = isRequiredVersion;
|
287
|
+
|
288
|
+
/**
|
289
|
+
* @see https://docs.npmjs.com/cli/v7/configuring-npm/package-json#urls-as-dependencies
|
290
|
+
* @param {string} versionDesc version to be normalized
|
291
|
+
* @returns {string} normalized version
|
292
|
+
*/
|
293
|
+
function normalizeVersion(versionDesc) {
|
294
|
+
versionDesc = (versionDesc && versionDesc.trim()) || "";
|
295
|
+
|
296
|
+
if (isRequiredVersion(versionDesc)) {
|
297
|
+
return versionDesc;
|
298
|
+
}
|
299
|
+
|
300
|
+
// add handle for URL Dependencies
|
301
|
+
return getGitUrlVersion(versionDesc.toLowerCase());
|
302
|
+
}
|
303
|
+
|
304
|
+
exports.normalizeVersion = normalizeVersion;
|
19
305
|
|
20
306
|
/**
|
21
307
|
*
|
@@ -64,27 +350,27 @@ exports.getRequiredVersionFromDescriptionFile = (data, packageName) => {
|
|
64
350
|
typeof data.optionalDependencies === "object" &&
|
65
351
|
packageName in data.optionalDependencies
|
66
352
|
) {
|
67
|
-
return data.optionalDependencies[packageName];
|
353
|
+
return normalizeVersion(data.optionalDependencies[packageName]);
|
68
354
|
}
|
69
355
|
if (
|
70
356
|
data.dependencies &&
|
71
357
|
typeof data.dependencies === "object" &&
|
72
358
|
packageName in data.dependencies
|
73
359
|
) {
|
74
|
-
return data.dependencies[packageName];
|
360
|
+
return normalizeVersion(data.dependencies[packageName]);
|
75
361
|
}
|
76
362
|
if (
|
77
363
|
data.peerDependencies &&
|
78
364
|
typeof data.peerDependencies === "object" &&
|
79
365
|
packageName in data.peerDependencies
|
80
366
|
) {
|
81
|
-
return data.peerDependencies[packageName];
|
367
|
+
return normalizeVersion(data.peerDependencies[packageName]);
|
82
368
|
}
|
83
369
|
if (
|
84
370
|
data.devDependencies &&
|
85
371
|
typeof data.devDependencies === "object" &&
|
86
372
|
packageName in data.devDependencies
|
87
373
|
) {
|
88
|
-
return data.devDependencies[packageName];
|
374
|
+
return normalizeVersion(data.devDependencies[packageName]);
|
89
375
|
}
|
90
376
|
};
|
@@ -12,6 +12,12 @@
|
|
12
12
|
const DATA_URI_CONTENT_LENGTH = 16;
|
13
13
|
const MAX_MODULE_IDENTIFIER_LENGTH = 80;
|
14
14
|
|
15
|
+
/**
|
16
|
+
* @param {number} n a number
|
17
|
+
* @param {string} singular singular
|
18
|
+
* @param {string} plural plural
|
19
|
+
* @returns {string} if n is 1, singular, else plural
|
20
|
+
*/
|
15
21
|
const plural = (n, singular, plural) => (n === 1 ? singular : plural);
|
16
22
|
|
17
23
|
/**
|
@@ -29,6 +35,10 @@ const printSizes = (sizes, { formatSize = n => `${n}` }) => {
|
|
29
35
|
}
|
30
36
|
};
|
31
37
|
|
38
|
+
/**
|
39
|
+
* @param {string} resource resource
|
40
|
+
* @returns {string} resource name for display
|
41
|
+
*/
|
32
42
|
const getResourceName = resource => {
|
33
43
|
const dataUrl = /^data:[^,]+,/.exec(resource);
|
34
44
|
if (!dataUrl) return resource;
|
@@ -41,6 +51,10 @@ const getResourceName = resource => {
|
|
41
51
|
)}..`;
|
42
52
|
};
|
43
53
|
|
54
|
+
/**
|
55
|
+
* @param {string} name module name
|
56
|
+
* @returns {[string,string]} prefix and module name
|
57
|
+
*/
|
44
58
|
const getModuleName = name => {
|
45
59
|
const [, prefix, resource] = /^(.*!)?([^!]*)$/.exec(name);
|
46
60
|
|
@@ -59,6 +73,11 @@ const getModuleName = name => {
|
|
59
73
|
return [prefix, getResourceName(resource)];
|
60
74
|
};
|
61
75
|
|
76
|
+
/**
|
77
|
+
* @param {string} str string
|
78
|
+
* @param {function(string): string} fn function to apply to each line
|
79
|
+
* @returns {string} joined string
|
80
|
+
*/
|
62
81
|
const mapLines = (str, fn) => str.split("\n").map(fn).join("\n");
|
63
82
|
|
64
83
|
/**
|
@@ -71,6 +90,12 @@ const isValidId = id => {
|
|
71
90
|
return typeof id === "number" || id;
|
72
91
|
};
|
73
92
|
|
93
|
+
/**
|
94
|
+
* @template T
|
95
|
+
* @param {Array<T>} list of items
|
96
|
+
* @param {number} count number of items to show
|
97
|
+
* @returns {string} string representation of list
|
98
|
+
*/
|
74
99
|
const moreCount = (list, count) => {
|
75
100
|
return list && list.length > 0 ? `+ ${count}` : `${count}`;
|
76
101
|
};
|
package/lib/util/LazySet.js
CHANGED
@@ -87,7 +87,7 @@ class LazySet {
|
|
87
87
|
|
88
88
|
/**
|
89
89
|
* @param {T} item an item
|
90
|
-
* @returns {
|
90
|
+
* @returns {LazySet<T>} itself
|
91
91
|
*/
|
92
92
|
add(item) {
|
93
93
|
this._set.add(item);
|
@@ -96,7 +96,7 @@ class LazySet {
|
|
96
96
|
|
97
97
|
/**
|
98
98
|
* @param {Iterable<T> | LazySet<T>} iterable a immutable iterable or another immutable LazySet which will eventually be merged into the Set
|
99
|
-
* @returns {
|
99
|
+
* @returns {LazySet<T>} itself
|
100
100
|
*/
|
101
101
|
addAll(iterable) {
|
102
102
|
if (this._deopt) {
|
@@ -187,12 +187,20 @@ class LazySet {
|
|
187
187
|
return "LazySet";
|
188
188
|
}
|
189
189
|
|
190
|
+
/**
|
191
|
+
* @param {import("../serialization/ObjectMiddleware").ObjectSerializerContext} context context
|
192
|
+
*/
|
190
193
|
serialize({ write }) {
|
191
194
|
if (this._needMerge) this._merge();
|
192
195
|
write(this._set.size);
|
193
196
|
for (const item of this._set) write(item);
|
194
197
|
}
|
195
198
|
|
199
|
+
/**
|
200
|
+
* @template T
|
201
|
+
* @param {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} context context
|
202
|
+
* @returns {LazySet<T>} lazy set
|
203
|
+
*/
|
196
204
|
static deserialize({ read }) {
|
197
205
|
const count = read();
|
198
206
|
const items = [];
|
package/lib/util/MapHelpers.js
CHANGED
@@ -6,16 +6,30 @@
|
|
6
6
|
"use strict";
|
7
7
|
|
8
8
|
/**
|
9
|
+
* getOrInsert is a helper function for maps that allows you to get a value
|
10
|
+
* from a map if it exists, or insert a new value if it doesn't. If it value doesn't
|
11
|
+
* exist, it will be computed by the provided function.
|
12
|
+
*
|
9
13
|
* @template K
|
10
14
|
* @template V
|
11
|
-
* @param {Map<K, V>} map
|
12
|
-
* @param {K} key
|
13
|
-
* @param {function(): V} computer compute value
|
14
|
-
* @returns {V} value
|
15
|
+
* @param {Map<K, V>} map The map object to check
|
16
|
+
* @param {K} key The key to check
|
17
|
+
* @param {function(): V} computer function which will compute the value if it doesn't exist
|
18
|
+
* @returns {V} The value from the map, or the computed value
|
19
|
+
*
|
20
|
+
* @example
|
21
|
+
* ```js
|
22
|
+
* const map = new Map();
|
23
|
+
* const value = getOrInsert(map, "key", () => "value");
|
24
|
+
* console.log(value); // "value"
|
25
|
+
* ```
|
15
26
|
*/
|
16
|
-
exports.
|
27
|
+
exports.getOrInsert = (map, key, computer) => {
|
28
|
+
// Grab key from map
|
17
29
|
const value = map.get(key);
|
30
|
+
// If the value already exists, return it
|
18
31
|
if (value !== undefined) return value;
|
32
|
+
// Otherwise compute the value, set it in the map, and return it
|
19
33
|
const newValue = computer();
|
20
34
|
map.set(key, newValue);
|
21
35
|
return newValue;
|
@@ -83,6 +83,9 @@ class StackedCacheMap {
|
|
83
83
|
this.map.clear();
|
84
84
|
}
|
85
85
|
|
86
|
+
/**
|
87
|
+
* @returns {number} size of the map
|
88
|
+
*/
|
86
89
|
get size() {
|
87
90
|
let size = this.map.size;
|
88
91
|
for (const map of this.stack) {
|
@@ -91,6 +94,9 @@ class StackedCacheMap {
|
|
91
94
|
return size;
|
92
95
|
}
|
93
96
|
|
97
|
+
/**
|
98
|
+
* @returns {Iterator<[K, V]>} iterator
|
99
|
+
*/
|
94
100
|
[Symbol.iterator]() {
|
95
101
|
const iterators = this.stack.map(map => map[Symbol.iterator]());
|
96
102
|
let current = this.map[Symbol.iterator]();
|
package/lib/util/StringXor.js
CHANGED
@@ -5,12 +5,46 @@
|
|
5
5
|
|
6
6
|
"use strict";
|
7
7
|
|
8
|
+
/** @typedef {import("../util/Hash")} Hash */
|
9
|
+
|
10
|
+
/**
|
11
|
+
* StringXor class provides methods for performing
|
12
|
+
* [XOR operations](https://en.wikipedia.org/wiki/Exclusive_or) on strings. In this context
|
13
|
+
* we operating on the character codes of two strings, which are represented as
|
14
|
+
* [Buffer](https://nodejs.org/api/buffer.html) objects.
|
15
|
+
*
|
16
|
+
* We use [StringXor in webpack](https://github.com/webpack/webpack/commit/41a8e2ea483a544c4ccd3e6217bdfb80daffca39)
|
17
|
+
* to create a hash of the current state of the compilation. By XOR'ing the Module hashes, it
|
18
|
+
* doesn't matter if the Module hashes are sorted or not. This is useful because it allows us to avoid sorting the
|
19
|
+
* Module hashes.
|
20
|
+
*
|
21
|
+
* @example
|
22
|
+
* ```js
|
23
|
+
* const xor = new StringXor();
|
24
|
+
* xor.add('hello');
|
25
|
+
* xor.add('world');
|
26
|
+
* console.log(xor.toString());
|
27
|
+
* ```
|
28
|
+
*
|
29
|
+
* @example
|
30
|
+
* ```js
|
31
|
+
* const xor = new StringXor();
|
32
|
+
* xor.add('foo');
|
33
|
+
* xor.add('bar');
|
34
|
+
* const hash = createHash('sha256');
|
35
|
+
* hash.update(xor.toString());
|
36
|
+
* console.log(hash.digest('hex'));
|
37
|
+
* ```
|
38
|
+
*/
|
8
39
|
class StringXor {
|
9
40
|
constructor() {
|
41
|
+
/** @type {Buffer|undefined} */
|
10
42
|
this._value = undefined;
|
11
43
|
}
|
12
44
|
|
13
45
|
/**
|
46
|
+
* Adds a string to the current StringXor object.
|
47
|
+
*
|
14
48
|
* @param {string} str string
|
15
49
|
* @returns {void}
|
16
50
|
*/
|
@@ -18,6 +52,10 @@ class StringXor {
|
|
18
52
|
const len = str.length;
|
19
53
|
const value = this._value;
|
20
54
|
if (value === undefined) {
|
55
|
+
/**
|
56
|
+
* We are choosing to use Buffer.allocUnsafe() because it is often faster than Buffer.alloc() because
|
57
|
+
* it allocates a new buffer of the specified size without initializing the memory.
|
58
|
+
*/
|
21
59
|
const newValue = (this._value = Buffer.allocUnsafe(len));
|
22
60
|
for (let i = 0; i < len; i++) {
|
23
61
|
newValue[i] = str.charCodeAt(i);
|
@@ -41,11 +79,24 @@ class StringXor {
|
|
41
79
|
}
|
42
80
|
}
|
43
81
|
|
82
|
+
/**
|
83
|
+
* Returns a string that represents the current state of the StringXor object. We chose to use "latin1" encoding
|
84
|
+
* here because "latin1" encoding is a single-byte encoding that can represent all characters in the
|
85
|
+
* [ISO-8859-1 character set](https://en.wikipedia.org/wiki/ISO/IEC_8859-1). This is useful when working
|
86
|
+
* with binary data that needs to be represented as a string.
|
87
|
+
*
|
88
|
+
* @returns {string} Returns a string that represents the current state of the StringXor object.
|
89
|
+
*/
|
44
90
|
toString() {
|
45
91
|
const value = this._value;
|
46
92
|
return value === undefined ? "" : value.toString("latin1");
|
47
93
|
}
|
48
94
|
|
95
|
+
/**
|
96
|
+
* Updates the hash with the current state of the StringXor object.
|
97
|
+
*
|
98
|
+
* @param {Hash} hash Hash instance
|
99
|
+
*/
|
49
100
|
updateHash(hash) {
|
50
101
|
const value = this._value;
|
51
102
|
if (value !== undefined) hash.update(value);
|
@@ -8,6 +8,28 @@
|
|
8
8
|
/* cspell:disable-next-line */
|
9
9
|
// Refactor: Peter Somogyvari @petermetz
|
10
10
|
|
11
|
+
/** @typedef {">=" | "<=" | "<" | ">" | "-" } BinarySearchPredicate */
|
12
|
+
/** @typedef {"GE" | "GT" | "LT" | "LE" | "EQ" } SearchPredicateSuffix */
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Helper function for compiling binary search functions.
|
16
|
+
*
|
17
|
+
* The generated code uses a while loop to repeatedly divide the search interval
|
18
|
+
* in half until the desired element is found, or the search interval is empty.
|
19
|
+
*
|
20
|
+
* The following is an example of a generated function for calling `compileSearch("P", "c(x,y)<=0", true, ["y", "c"], false)`:
|
21
|
+
*
|
22
|
+
* ```js
|
23
|
+
* function P(a,l,h,y,c){var i=l-1;while(l<=h){var m=(l+h)>>>1,x=a[m];if(c(x,y)<=0){i=m;l=m+1}else{h=m-1}}return i};
|
24
|
+
* ```
|
25
|
+
*
|
26
|
+
* @param {string} funcName The name of the function to be compiled.
|
27
|
+
* @param {string} predicate The predicate / comparison operator to be used in the binary search.
|
28
|
+
* @param {boolean} reversed Whether the search should be reversed.
|
29
|
+
* @param {string[]} extraArgs Extra arguments to be passed to the function.
|
30
|
+
* @param {boolean=} earlyOut Whether the search should return as soon as a match is found.
|
31
|
+
* @returns {string} The compiled binary search function.
|
32
|
+
*/
|
11
33
|
const compileSearch = (funcName, predicate, reversed, extraArgs, earlyOut) => {
|
12
34
|
const code = [
|
13
35
|
"function ",
|
@@ -43,6 +65,18 @@ const compileSearch = (funcName, predicate, reversed, extraArgs, earlyOut) => {
|
|
43
65
|
return code.join("");
|
44
66
|
};
|
45
67
|
|
68
|
+
/**
|
69
|
+
* This helper functions generate code for two binary search functions:
|
70
|
+
* A(): Performs a binary search on an array using the comparison operator specified.
|
71
|
+
* P(): Performs a binary search on an array using a _custom comparison function_
|
72
|
+
* `c(x,y)` **and** comparison operator specified by `predicate`.
|
73
|
+
*
|
74
|
+
* @param {BinarySearchPredicate} predicate The predicate / comparison operator to be used in the binary search.
|
75
|
+
* @param {boolean} reversed Whether the search should be reversed.
|
76
|
+
* @param {SearchPredicateSuffix} suffix The suffix to be used in the function name.
|
77
|
+
* @param {boolean=} earlyOut Whether the search should return as soon as a match is found.
|
78
|
+
* @returns {function} The compiled binary search function.
|
79
|
+
*/
|
46
80
|
const compileBoundsSearch = (predicate, reversed, suffix, earlyOut) => {
|
47
81
|
const arg1 = compileSearch(
|
48
82
|
"A",
|
@@ -77,6 +111,21 @@ return dispatchBinarySearch";
|
|
77
111
|
return result();
|
78
112
|
};
|
79
113
|
|
114
|
+
/**
|
115
|
+
* These functions are used to perform binary searches on arrays.
|
116
|
+
*
|
117
|
+
* @example
|
118
|
+
* ```js
|
119
|
+
* const { gt, le} = require("./binarySearchBounds");
|
120
|
+
* const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
121
|
+
*
|
122
|
+
* // Find the index of the first element greater than 5
|
123
|
+
* const index1 = gt(arr, 5); // index1 === 3
|
124
|
+
*
|
125
|
+
* // Find the index of the first element less than or equal to 5
|
126
|
+
* const index2 = le(arr, 5); // index2 === 4
|
127
|
+
* ```
|
128
|
+
*/
|
80
129
|
module.exports = {
|
81
130
|
ge: compileBoundsSearch(">=", false, "GE"),
|
82
131
|
gt: compileBoundsSearch(">", false, "GT"),
|