fix(nitro): include nested layers in nitro transforms#35327
Conversation
@nuxt/kit
@nuxt/nitro-server
nuxt
@nuxt/rspack-builder
@nuxt/schema
@nuxt/vite-builder
@nuxt/webpack-builder
commit: |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Actionable comments posted: 1
π€ Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/nitro-server/src/utils.ts`:
- Around line 31-38: The generated node_modules exclusion RegExp is too
permissive because entries from excludePaths are inserted as raw suffixes (used
in NODE_MODULES_RE), allowing partial matches like "foo" to also match "foobar";
update the regex construction so each excludePaths entry is escaped and anchored
to a path segment boundary (e.g., transform each entry via escapeRE and append
(?:\/|$) or equivalent) before joining, so the returned RegExp uses
node_modules\\/(?!<anchored-alternatives>) and only exempts exact package path
prefixes.
πͺ Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
βΉοΈ Review info
βοΈ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 9e83896e-9cad-43b9-8350-3b507e2037f1
π Files selected for processing (3)
packages/nitro-server/src/index.tspackages/nitro-server/src/utils.test.tspackages/nitro-server/src/utils.ts
| excludePaths.push(escapeRE(suffix)) | ||
| } | ||
| NODE_MODULES_RE.lastIndex = match.index + 1 | ||
| } | ||
| } | ||
| return excludePaths.length | ||
| ? new RegExp(`node_modules\\/(?!${excludePaths.join('|')})`) | ||
| : /node_modules/ |
There was a problem hiding this comment.
Regex lookahead is over-broad and lets non-layer packages bypass exclusion.
At Line 37, the alternatives are inserted as raw suffixes (for example foo), so node_modules/(?!foo) also exempts node_modules/foobar/**. This causes unrelated dependencies to be transformed as if they were layer-owned.
Suggested fix
- if (suffix) {
- excludePaths.push(escapeRE(suffix))
- }
+ if (suffix) {
+ excludePaths.push(`${escapeRE(suffix)}(?:\\/|$)`)
+ }π§° Tools
πͺ ast-grep (0.43.0)
[warning] 36-36: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(node_modules\\/(?!${excludePaths.join('|')}))
Note: [CWE-1333] Inefficient Regular Expression Complexity
(regexp-from-variable)
π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/nitro-server/src/utils.ts` around lines 31 - 38, The generated
node_modules exclusion RegExp is too permissive because entries from
excludePaths are inserted as raw suffixes (used in NODE_MODULES_RE), allowing
partial matches like "foo" to also match "foobar"; update the regex construction
so each excludePaths entry is escaped and anchored to a path segment boundary
(e.g., transform each entry via escapeRE and append (?:\/|$) or equivalent)
before joining, so the returned RegExp uses
node_modules\\/(?!<anchored-alternatives>) and only exempts exact package path
prefixes.
Merging this PR will improve performance by 16.68%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| β‘ | loadNuxt in the basic test fixture |
449.3 ms | 385.1 ms | +16.68% |
Tip
Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.
Comparing fix/nested-layer-transform (eeadba8) with main (a9f522c)
Footnotes
-
3 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. β©
| name: 'nuxt', | ||
| version: nuxtPkg.version || nitroBuilder.version, | ||
| }, | ||
| imports: nuxt.options.experimental.nitroAutoImports === false |
There was a problem hiding this comment.
Unrelated question to this PR but why don't we use && instead of === false ? ternary ?
There was a problem hiding this comment.
it feels clearer - also I try to avoid && as it can sometimes pass-through other falsy values like 0, undefined, etc.
π Linked issue
resolves #35324
π Description
this handles nested
node_modulesdirs with both pnpm + npm