webpack 5.58.1 → 5.60.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.

@@ -5,12 +5,13 @@
5
5
 
6
6
  "use strict";
7
7
 
8
- const { resolve, extname, dirname } = require("path");
8
+ const { extname, basename } = require("path");
9
9
  const { URL } = require("url");
10
10
  const { createGunzip, createBrotliDecompress, createInflate } = require("zlib");
11
11
  const NormalModule = require("../NormalModule");
12
+ const createSchemaValidation = require("../util/create-schema-validation");
12
13
  const createHash = require("../util/createHash");
13
- const { mkdirp } = require("../util/fs");
14
+ const { mkdirp, dirname, join } = require("../util/fs");
14
15
  const memoize = require("../util/memoize");
15
16
 
16
17
  /** @typedef {import("../../declarations/plugins/schemes/HttpUriPlugin").HttpUriPluginOptions} HttpUriPluginOptions */
@@ -19,6 +20,18 @@ const memoize = require("../util/memoize");
19
20
  const getHttp = memoize(() => require("http"));
20
21
  const getHttps = memoize(() => require("https"));
21
22
 
23
+ /** @type {(() => void)[] | undefined} */
24
+ let inProgressWrite = undefined;
25
+
26
+ const validate = createSchemaValidation(
27
+ require("../../schemas/plugins/schemes/HttpUriPlugin.check.js"),
28
+ () => require("../../schemas/plugins/schemes/HttpUriPlugin.json"),
29
+ {
30
+ name: "Http Uri Plugin",
31
+ baseDataPath: "options"
32
+ }
33
+ );
34
+
22
35
  const toSafePath = str =>
23
36
  str
24
37
  .replace(/^[^a-zA-Z0-9]+|[^a-zA-Z0-9]+$/g, "")
@@ -104,7 +117,6 @@ class Lockfile {
104
117
  this.version = 1;
105
118
  /** @type {Map<string, LockfileEntry | "ignore" | "no-cache">} */
106
119
  this.entries = new Map();
107
- this.outdated = false;
108
120
  }
109
121
 
110
122
  static parse(content) {
@@ -251,25 +263,17 @@ const cachedWithKey = (fn, forceFn = fn) => {
251
263
  return resultFn;
252
264
  };
253
265
 
254
- /**
255
- * @typedef {Object} HttpUriPluginAdvancedOptions
256
- * @property {string | typeof import("../util/Hash")=} hashFunction
257
- * @property {string=} hashDigest
258
- * @property {number=} hashDigestLength
259
- */
260
-
261
266
  class HttpUriPlugin {
262
267
  /**
263
- * @param {HttpUriPluginOptions & HttpUriPluginAdvancedOptions} options options
268
+ * @param {HttpUriPluginOptions} options options
264
269
  */
265
- constructor(options = {}) {
270
+ constructor(options) {
271
+ validate(options);
266
272
  this._lockfileLocation = options.lockfileLocation;
267
273
  this._cacheLocation = options.cacheLocation;
268
274
  this._upgrade = options.upgrade;
269
275
  this._frozen = options.frozen;
270
- this._hashFunction = options.hashFunction;
271
- this._hashDigest = options.hashDigest;
272
- this._hashDigestLength = options.hashDigestLength;
276
+ this._allowedUris = options.allowedUris;
273
277
  }
274
278
 
275
279
  /**
@@ -299,7 +303,8 @@ class HttpUriPlugin {
299
303
  const logger = compilation.getLogger("webpack.HttpUriPlugin");
300
304
  const lockfileLocation =
301
305
  this._lockfileLocation ||
302
- resolve(
306
+ join(
307
+ intermediateFs,
303
308
  compiler.context,
304
309
  compiler.name
305
310
  ? `${toSafePath(compiler.name)}.webpack.lock`
@@ -311,11 +316,10 @@ class HttpUriPlugin {
311
316
  : lockfileLocation + ".data";
312
317
  const upgrade = this._upgrade || false;
313
318
  const frozen = this._frozen || false;
314
- const hashFunction = this._hashFunction || "sha512";
315
- const hashDigest =
316
- this._hashDigest || compilation.outputOptions.hashDigest;
317
- const hashDigestLength =
318
- this._hashDigestLength || compilation.outputOptions.hashDigestLength;
319
+ const hashFunction = "sha512";
320
+ const hashDigest = "hex";
321
+ const hashDigestLength = 20;
322
+ const allowedUris = this._allowedUris;
319
323
 
320
324
  let warnedAboutEol = false;
321
325
 
@@ -400,11 +404,13 @@ class HttpUriPlugin {
400
404
  }
401
405
  );
402
406
 
403
- let outdatedLockfile = undefined;
407
+ /** @type {Map<string, LockfileEntry | "ignore" | "no-cache"> | undefined} */
408
+ let lockfileUpdates = undefined;
404
409
  const storeLockEntry = (lockfile, url, entry) => {
405
410
  const oldEntry = lockfile.entries.get(url);
411
+ if (lockfileUpdates === undefined) lockfileUpdates = new Map();
412
+ lockfileUpdates.set(url, entry);
406
413
  lockfile.entries.set(url, entry);
407
- outdatedLockfile = lockfile;
408
414
  if (!oldEntry) {
409
415
  logger.log(`${url} added to lockfile`);
410
416
  } else if (typeof oldEntry === "string") {
@@ -440,8 +446,8 @@ class HttpUriPlugin {
440
446
  if (!cacheLocation || !result.content)
441
447
  return callback(null, result);
442
448
  const key = getCacheKey(result.entry.resolved);
443
- const filePath = resolve(cacheLocation, key);
444
- mkdirp(intermediateFs, dirname(filePath), err => {
449
+ const filePath = join(intermediateFs, cacheLocation, key);
450
+ mkdirp(intermediateFs, dirname(intermediateFs, filePath), err => {
445
451
  if (err) return callback(err);
446
452
  intermediateFs.writeFile(filePath, result.content, err => {
447
453
  if (err) return callback(err);
@@ -671,6 +677,19 @@ class HttpUriPlugin {
671
677
  (url, callback) => fetchContentRaw(url, undefined, callback)
672
678
  );
673
679
 
680
+ const isAllowed = uri => {
681
+ for (const allowed of allowedUris) {
682
+ if (typeof allowed === "string") {
683
+ if (uri.startsWith(allowed)) return true;
684
+ } else if (typeof allowed === "function") {
685
+ if (allowed(uri)) return true;
686
+ } else {
687
+ if (allowed.test(uri)) return true;
688
+ }
689
+ }
690
+ return false;
691
+ };
692
+
674
693
  const getInfo = cachedWithKey(
675
694
  /**
676
695
  * @param {string} url the url
@@ -678,6 +697,15 @@ class HttpUriPlugin {
678
697
  * @returns {void}
679
698
  */
680
699
  (url, callback) => {
700
+ if (!isAllowed(url)) {
701
+ return callback(
702
+ new Error(
703
+ `${url} doesn't match the allowedUris policy. These URIs are allowed:\n${allowedUris
704
+ .map(uri => ` - ${uri}`)
705
+ .join("\n")}`
706
+ )
707
+ );
708
+ }
681
709
  getLockfile((err, lockfile) => {
682
710
  if (err) return callback(err);
683
711
  const entryOrString = lockfile.entries.get(url);
@@ -789,7 +817,7 @@ Remove this line from the lockfile to force upgrading.`
789
817
  // When there is a lockfile cache
790
818
  // we read the content from there
791
819
  const key = getCacheKey(entry.resolved);
792
- const filePath = resolve(cacheLocation, key);
820
+ const filePath = join(intermediateFs, cacheLocation, key);
793
821
  fs.readFile(filePath, (err, result) => {
794
822
  const content = /** @type {Buffer} */ (result);
795
823
  if (err) {
@@ -934,6 +962,7 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
934
962
  .tapAsync("HttpUriPlugin", (resource, module, callback) => {
935
963
  return getInfo(resource, (err, result) => {
936
964
  if (err) return callback(err);
965
+ module.buildInfo.resourceIntegrity = result.entry.integrity;
937
966
  callback(null, result.content);
938
967
  });
939
968
  });
@@ -963,12 +992,60 @@ Run build with un-frozen lockfile to automatically fix lockfile.`
963
992
  compilation.hooks.finishModules.tapAsync(
964
993
  "HttpUriPlugin",
965
994
  (modules, callback) => {
966
- if (!outdatedLockfile) return callback();
967
- intermediateFs.writeFile(
968
- lockfileLocation,
969
- outdatedLockfile.toString(),
970
- callback
995
+ if (!lockfileUpdates) return callback();
996
+ const ext = extname(lockfileLocation);
997
+ const tempFile = join(
998
+ intermediateFs,
999
+ dirname(intermediateFs, lockfileLocation),
1000
+ `.${basename(lockfileLocation, ext)}.${
1001
+ (Math.random() * 10000) | 0
1002
+ }${ext}`
971
1003
  );
1004
+
1005
+ const writeDone = () => {
1006
+ const nextOperation = inProgressWrite.shift();
1007
+ if (nextOperation) {
1008
+ nextOperation();
1009
+ } else {
1010
+ inProgressWrite = undefined;
1011
+ }
1012
+ };
1013
+ const runWrite = () => {
1014
+ intermediateFs.readFile(lockfileLocation, (err, buffer) => {
1015
+ if (err && err.code !== "ENOENT") {
1016
+ writeDone();
1017
+ return callback(err);
1018
+ }
1019
+ const lockfile = buffer
1020
+ ? Lockfile.parse(buffer.toString("utf-8"))
1021
+ : new Lockfile();
1022
+ for (const [key, value] of lockfileUpdates) {
1023
+ lockfile.entries.set(key, value);
1024
+ }
1025
+ intermediateFs.writeFile(tempFile, lockfile.toString(), err => {
1026
+ if (err) {
1027
+ writeDone();
1028
+ return intermediateFs.unlink(tempFile, () => callback(err));
1029
+ }
1030
+ intermediateFs.rename(tempFile, lockfileLocation, err => {
1031
+ if (err) {
1032
+ writeDone();
1033
+ return intermediateFs.unlink(tempFile, () =>
1034
+ callback(err)
1035
+ );
1036
+ }
1037
+ writeDone();
1038
+ callback();
1039
+ });
1040
+ });
1041
+ });
1042
+ };
1043
+ if (inProgressWrite) {
1044
+ inProgressWrite.push(runWrite);
1045
+ } else {
1046
+ inProgressWrite = [];
1047
+ runWrite();
1048
+ }
972
1049
  }
973
1050
  );
974
1051
  }
@@ -16,9 +16,7 @@ class Serializer {
16
16
  let current = obj;
17
17
  for (const middleware of this.serializeMiddlewares) {
18
18
  if (current && typeof current.then === "function") {
19
- current = current.then(
20
- data => data && middleware.serialize(data, context)
21
- );
19
+ current = current.then(data => data && middleware.serialize(data, ctx));
22
20
  } else if (current) {
23
21
  try {
24
22
  current = middleware.serialize(current, ctx);
@@ -36,7 +34,7 @@ class Serializer {
36
34
  let current = value;
37
35
  for (const middleware of this.deserializeMiddlewares) {
38
36
  if (current && typeof current.then === "function") {
39
- current = current.then(data => middleware.deserialize(data, context));
37
+ current = current.then(data => middleware.deserialize(data, ctx));
40
38
  } else {
41
39
  current = middleware.deserialize(current, ctx);
42
40
  }
package/lib/util/fs.js CHANGED
@@ -83,6 +83,8 @@ const path = require("path");
83
83
  * @returns {Watcher} a watcher
84
84
  */
85
85
 
86
+ // TODO webpack 6 make optional methods required
87
+
86
88
  /**
87
89
  * @typedef {Object} OutputFileSystem
88
90
  * @property {function(string, Buffer|string, Callback): void} writeFile
@@ -6,7 +6,7 @@
6
6
  "use strict";
7
7
 
8
8
  const SAFE_IDENTIFIER = /^[_a-zA-Z$][_a-zA-Z$0-9]*$/;
9
- const RESERVED_IDENTIFER = new Set([
9
+ const RESERVED_IDENTIFIER = new Set([
10
10
  "break",
11
11
  "case",
12
12
  "catch",
@@ -66,7 +66,7 @@ const propertyAccess = (properties, start = 0) => {
66
66
  const p = properties[i];
67
67
  if (`${+p}` === p) {
68
68
  str += `[${p}]`;
69
- } else if (SAFE_IDENTIFIER.test(p) && !RESERVED_IDENTIFER.has(p)) {
69
+ } else if (SAFE_IDENTIFIER.test(p) && !RESERVED_IDENTIFIER.has(p)) {
70
70
  str += `.${p}`;
71
71
  } else {
72
72
  str += `[${JSON.stringify(p)}]`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "5.58.1",
3
+ "version": "5.60.0",
4
4
  "author": "Tobias Koppers @sokra",
5
5
  "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
6
6
  "license": "MIT",