webpack 5.108.2 → 5.108.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1383,6 +1383,16 @@ class JavascriptParser extends Parser {
1383
1383
  return handleConstOperation((l, r) => l <= r);
1384
1384
  } else if (expr.operator === ">=") {
1385
1385
  return handleConstOperation((l, r) => l >= r);
1386
+ } else if (expr.operator === "in") {
1387
+ // `x in y` always evaluates to a boolean, so it is never nullish
1388
+ const left = this.evaluateExpression(expr.left);
1389
+ const right = this.evaluateExpression(expr.right);
1390
+ return new BasicEvaluatedExpression()
1391
+ .setNullish(false)
1392
+ .setSideEffects(
1393
+ left.couldHaveSideEffects() || right.couldHaveSideEffects()
1394
+ )
1395
+ .setRange(/** @type {Range} */ (expr.range));
1386
1396
  }
1387
1397
  });
1388
1398
  this.hooks.evaluate.for("UnaryExpression").tap(CLASS_NAME, (_expr) => {
@@ -56,6 +56,32 @@ const isMetaUrl = (parser, arg) => {
56
56
  return true;
57
57
  };
58
58
 
59
+ /**
60
+ * Whether the request points to a directory and thus can't be an asset.
61
+ * @param {string} request request
62
+ * @returns {boolean} true when the request is a directory reference
63
+ */
64
+ const isDirectoryRequest = (request) =>
65
+ request === "." || request === ".." || request.endsWith("/");
66
+
67
+ /**
68
+ * Replaces `import.meta.url` with the runtime base URI, leaving the
69
+ * `new URL(...)` construction untouched so it's evaluated at runtime.
70
+ * @param {JavascriptParser} parser parser
71
+ * @param {NewExpressionNode} expr expression
72
+ * @returns {void}
73
+ */
74
+ const keepNewURL = (parser, expr) => {
75
+ const [, arg2] = expr.arguments;
76
+ const dep = new ConstDependency(
77
+ RuntimeGlobals.baseURI,
78
+ /** @type {Range} */ (arg2.range),
79
+ [RuntimeGlobals.baseURI]
80
+ );
81
+ dep.loc = /** @type {DependencyLocation} */ (expr.loc);
82
+ parser.state.module.addPresentationalDependency(dep);
83
+ };
84
+
59
85
  /** @type {WeakMap<NewExpressionNode, BasicEvaluatedExpression | undefined>} */
60
86
  const getEvaluatedExprCache = new WeakMap();
61
87
 
@@ -157,13 +183,7 @@ class URLParserPlugin {
157
183
  return;
158
184
  }
159
185
 
160
- const dep = new ConstDependency(
161
- RuntimeGlobals.baseURI,
162
- /** @type {Range} */ (arg2.range),
163
- [RuntimeGlobals.baseURI]
164
- );
165
- dep.loc = /** @type {DependencyLocation} */ (expr.loc);
166
- parser.state.module.addPresentationalDependency(dep);
186
+ keepNewURL(parser, expr);
167
187
 
168
188
  return true;
169
189
  }
@@ -177,6 +197,12 @@ class URLParserPlugin {
177
197
 
178
198
  // static URL
179
199
  if ((request = evaluatedExpr.asString())) {
200
+ // A directory is not an asset; keep `new URL(...)` as-is, matching Node/browsers.
201
+ if (isDirectoryRequest(request)) {
202
+ keepNewURL(parser, expr);
203
+ return true;
204
+ }
205
+
180
206
  const [arg1, arg2] = expr.arguments;
181
207
  const dep = new URLDependency(
182
208
  request,
@@ -29,17 +29,18 @@ class LocConverter {
29
29
  get(pos) {
30
30
  if (this.pos !== pos) {
31
31
  if (this.pos < pos) {
32
- const str = this._input.slice(this.pos, pos);
33
- let i = str.lastIndexOf("\n");
34
- if (i === -1) {
35
- this.column += str.length;
36
- } else {
37
- this.column = str.length - i - 1;
38
- this.line++;
39
- while (i > 0 && (i = str.lastIndexOf("\n", i - 1)) !== -1) {
32
+ // Advance: delta-bounded scan of [this.pos, pos), allocation-free
33
+ // (unbounded index scans go quadratic on newline-free input).
34
+ const input = this._input;
35
+ let last = -1;
36
+ for (let j = this.pos; j < pos; j++) {
37
+ if (input.charCodeAt(j) === 10) {
40
38
  this.line++;
39
+ last = j;
41
40
  }
42
41
  }
42
+ this.column =
43
+ last === -1 ? this.column + (pos - this.pos) : pos - last - 1;
43
44
  } else {
44
45
  // Retreat: count newlines crossed in (pos, this.pos), i.e.
45
46
  // exclude the newline at `this.pos` itself. By convention a
@@ -6,36 +6,41 @@
6
6
 
7
7
  /**
8
8
  * Babel-style visitor map keyed by a numeric node-type discriminator; a bucket
9
- * is a function (enter-only) or `{ enter?, exit? }`. `ctx.skipChildren()`
10
- * (enter only) stops the walker descending into the node's children.
11
- * @typedef {{ skipChildren(): void }} VisitorContext
12
- */
13
- /**
14
- * @template TNode
15
- * @typedef {(node: TNode, parent: TNode | null, ctx: VisitorContext) => void} VisitorFn
9
+ * is a function (enter-only) or `{ enter?, exit? }`.
10
+ *
11
+ * A visitor receives a single `path` argument (the Babel `path` shape): the
12
+ * language's AST accessor with the current position on it — `path.node`,
13
+ * `path.parent` (null at a root) — plus `path.skipChildren()` (enter only)
14
+ * to stop the walk descending, and every field-read method (which defaults
15
+ * to the current node). The path is one reused object rebound before each callback:
16
+ * it is only valid during the callback, and future per-node functionality
17
+ * lands on it without changing any visitor signature.
18
+ * @template TPath
19
+ * @typedef {(path: TPath) => void} VisitorFn
16
20
  */
17
21
  /**
18
- * @template TNode
19
- * @typedef {VisitorFn<TNode> | { enter?: VisitorFn<TNode>, exit?: VisitorFn<TNode> }} VisitorBucket
22
+ * @template TPath
23
+ * @typedef {VisitorFn<TPath> | { enter?: VisitorFn<TPath>, exit?: VisitorFn<TPath> }} VisitorBucket
20
24
  */
21
25
  /**
22
- * @template TNode
23
- * @typedef {{ [nodeType: number]: VisitorBucket<TNode> }} VisitorMap
26
+ * @template TPath
27
+ * @typedef {{ [nodeType: number]: VisitorBucket<TPath> }} VisitorMap
24
28
  */
25
29
  /**
26
- * @template TNode
27
- * @typedef {{ enter: VisitorFn<TNode>[], exit: VisitorFn<TNode>[] }} CompiledVisitorBucket
30
+ * @template TPath
31
+ * @typedef {{ enter: VisitorFn<TPath>[], exit: VisitorFn<TPath>[] }} CompiledVisitorBucket
28
32
  */
29
33
  /**
30
- * @template TNode
31
- * @typedef {CompiledVisitorBucket<TNode>[]} CompiledVisitorMap a sparse array indexed by node type
34
+ * @template TPath
35
+ * @typedef {CompiledVisitorBucket<TPath>[]} CompiledVisitorMap a sparse array indexed by node type
32
36
  */
33
37
  /**
34
38
  * A language grammar: parse `input` and fire the compiled visitors in source
35
- * order (the grammar owns tokenizing, parsing, and walking).
36
- * @template TNode
39
+ * order (the grammar owns tokenizing, parsing, walking — and the `path`
40
+ * object each visitor receives).
41
+ * @template TPath
37
42
  * @template TProcessOptions
38
- * @typedef {(input: string, visitors: CompiledVisitorMap<TNode>, options: TProcessOptions) => void} Grammar
43
+ * @typedef {(input: string, visitors: CompiledVisitorMap<TPath>, options: TProcessOptions) => void} Grammar
39
44
  */
40
45
 
41
46
  /**
@@ -44,28 +49,31 @@
44
49
  * binds its own grammar and node-type enum. Babel-style usage:
45
50
  *
46
51
  * ```
47
- * processor.use({ [NodeType.X]: (node) => {}, [NodeType.Y]: { enter, exit } });
52
+ * processor.use({ [NodeType.X]: (path) => {}, [NodeType.Y]: { enter, exit } });
48
53
  * processor.process(source);
49
54
  * ```
50
- * @template TNode
55
+ * @template TPath
51
56
  * @template [TProcessOptions=object]
52
57
  */
53
58
  class SourceProcessor {
54
59
  /**
55
- * @param {Grammar<TNode, TProcessOptions>} grammar the grammar to drive over the source
60
+ * @param {Grammar<TPath, TProcessOptions>} grammar the grammar to drive over the source
61
+ * @param {TProcessOptions=} options default process options (e.g. `skip`) merged under each `process` call's own options
56
62
  */
57
- constructor(grammar) {
58
- /** @type {Grammar<TNode, TProcessOptions>} */
63
+ constructor(grammar, options) {
64
+ /** @type {Grammar<TPath, TProcessOptions>} */
59
65
  this._grammar = grammar;
60
- /** @type {CompiledVisitorMap<TNode>} */
66
+ /** @type {CompiledVisitorMap<TPath>} */
61
67
  this._visitors = [];
68
+ /** @type {TProcessOptions | undefined} */
69
+ this._options = options;
62
70
  }
63
71
 
64
72
  /**
65
73
  * Register a Babel-style visitor map; calls accumulate per node type.
66
74
  * A bucket is a function (= `{ enter }`) or `{ enter?, exit? }`.
67
- * @param {VisitorMap<TNode>} map visitor map keyed by node type
68
- * @returns {SourceProcessor<TNode, TProcessOptions>} `this`, for chaining
75
+ * @param {VisitorMap<TPath>} map visitor map keyed by node type
76
+ * @returns {SourceProcessor<TPath, TProcessOptions>} `this`, for chaining
69
77
  */
70
78
  use(map) {
71
79
  // `map`'s keys are node-type enum members; `Object.keys` stringifies them,
@@ -90,15 +98,20 @@ class SourceProcessor {
90
98
 
91
99
  /**
92
100
  * Run the grammar over `input`, firing visitors in source order. No
93
- * AST retained.
101
+ * AST retained. Per-call `options` override the instance defaults.
94
102
  * @param {string} input source text
95
103
  * @param {TProcessOptions=} options grammar-specific options
96
104
  */
97
105
  process(input, options) {
106
+ const defaults = this._options;
98
107
  this._grammar(
99
108
  input,
100
109
  this._visitors,
101
- options || /** @type {TProcessOptions} */ ({})
110
+ defaults
111
+ ? options
112
+ ? { ...defaults, ...options }
113
+ : defaults
114
+ : options || /** @type {TProcessOptions} */ ({})
102
115
  );
103
116
  }
104
117
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack",
3
- "version": "5.108.2",
3
+ "version": "5.108.4",
4
4
  "description": "Packs ECMAScript/CommonJs/AMD modules for the browser. Allows you to split your codebase into multiple bundles, which can be loaded on demand. Supports loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
5
5
  "homepage": "https://github.com/webpack/webpack",
6
6
  "bugs": "https://github.com/webpack/webpack/issues",
@@ -176,7 +176,7 @@
176
176
  "node-gyp": "^13.0.0",
177
177
  "nyc": "^18.0.0",
178
178
  "open-cli": "^9.0.0",
179
- "oxc-parser": "^0.137.0",
179
+ "oxc-parser": "^0.138.0",
180
180
  "pkg-pr-new": "^0.0.75",
181
181
  "prettier": "^3.8.2",
182
182
  "prettier-2": "npm:prettier@^2",
@@ -197,7 +197,7 @@
197
197
  "simple-git": "^3.28.0",
198
198
  "style-loader": "^4.0.0",
199
199
  "terser": "^5.46.2",
200
- "three": "^0.184.0",
200
+ "three": "^0.185.1",
201
201
  "tinybench": "^6.0.1",
202
202
  "toml": "^4.1.1",
203
203
  "tooling": "webpack/tooling#v1.26.4",