-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
refactor(vite): make vite plugins environment-compatible #33445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
|
@nuxt/kit
nuxt
@nuxt/rspack-builder
@nuxt/schema
@nuxt/vite-builder
@nuxt/webpack-builder
commit: |
WalkthroughThe PR reorganises Nuxt's Vite integration: it streamlines the client build config in packages/vite/src/client.ts by removing bespoke resolve.alias, HMR/server-CORS overrides, Rollup output customization and dynamic dev-server middleware. It adds new internal plugins (AnalyzePlugin, DevServerPlugin, EnvironmentsPlugin, LayerDepOptimizePlugin, ReplacePlugin, VitePluginCheckerPlugin), rewrites SSRStylesPlugin and adjusts StableEntryPlugin to be environment-scoped. Import paths for ViteNode-related modules were moved to the plugins directory and the server pipeline now includes the vite-plugin-checker integration while several legacy dev-only and optimizeDeps customisations were removed. Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (1)**/*.{ts,tsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
🧬 Code graph analysis (1)packages/vite/src/server.ts (1)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/vite/src/runtime/vite-node-shared.mjs (1)
231-286: Request-level retries don’t run; promise is returned (not awaited)sendRequest only retries connectSocket failures; timeouts/connection drops after connect reject the returned promise and bypass the retry loop. Await the request promise inside the loop so errors trigger retries.
Apply this diff:
- for (let requestAttempt = 0; requestAttempt <= MAX_RETRY_ATTEMPTS; requestAttempt++) { + for (let requestAttempt = 0; requestAttempt <= MAX_RETRY_ATTEMPTS; requestAttempt++) { try { - const socket = await connectSocket() - - return new Promise((resolve, reject) => { + await connectSocket() + const result = await new Promise((resolve, reject) => { const timeoutId = setTimeout(() => { pendingRequests.delete(requestId) reject(new Error(`Request timeout after ${REQUEST_TIMEOUT_MS}ms for type: ${type}`)) }, REQUEST_TIMEOUT_MS) @@ try { socket.write(fullMessage) } catch (error) { clearTimeout(timeoutId) pendingRequests.delete(requestId) reject(error) } - }) + }) + return result } catch (error) { lastError = error if (requestAttempt < MAX_RETRY_ATTEMPTS) { const delay = calculateRetryDelay(requestAttempt) await new Promise(resolve => setTimeout(resolve, delay)) // clear current connection state to force reconnection if (clientSocket) { clientSocket.destroy() clientSocket = undefined } currentConnectPromise = undefined + continue } } }
🧹 Nitpick comments (6)
packages/vite/src/plugins/analyze.ts (1)
25-50: Optional: reduce noise in size statsConsider adding
legalComments: 'none'to the esbuild transform to avoid emitted licence comments skewing minified size comparisons.- transform(module.code || '', { minify: true }) + transform(module.code || '', { minify: true, legalComments: 'none' })packages/vite/src/plugins/dev-server.ts (3)
91-101: Safer route matching for dev handlersDynamic regex from variable input can be fragile and expose ReDoS risks. Prefer compiling routes with a safe library (e.g. path-to-regexp) or, at minimum, pre-validate patterns and avoid
.*.Example:
// import { pathToRegexp } from 'path-to-regexp' devHandlerRegexes.push(pathToRegexp(handler.route))Note: You already escape meta characters and anchor the pattern, which helps; this is a robustness suggestion. Based on static analysis hints.
77-83: Middleware insertion relies on function nameDetecting
viteTransformMiddlewarebyFunction.nameis brittle across versions/minification. Keep the current fallback (append), but consider a more robust heuristic (e.g. insert before first stack entry whose route is '' and handles transform, or expose a hook upstream).
104-112: Micro-optimisation: cache Vite routesYou rebuild
viteRouteson each request. Cache once after server start and invalidate only if the stack changes (rare).packages/vite/src/plugins/ssr-styles.ts (2)
45-46: Remove unusedidRefMap
idRefMapis written but not read anywhere in this file. Drop it to reduce noise.- const idRefMap: Record<string, string> = {} ... - idRefMap[relativeToSrcDir(file)] = ref ... - idRefMap[relativeToSrcDir(resolved.id)] = refAlso applies to: 263-265, 290-291
188-191: ClarifyinBundlecheck
!!relativeToSrcDir(moduleId)is always truthy for valid paths, soinBundlebecomes effectivelyisVue(moduleId) || isEntry. If that’s intentional, add a short comment; otherwise refine the condition.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
packages/vite/src/client.ts(2 hunks)packages/vite/src/plugins/analyze.ts(1 hunks)packages/vite/src/plugins/dev-server.ts(1 hunks)packages/vite/src/plugins/environments.ts(1 hunks)packages/vite/src/plugins/layer-dep-optimize.ts(1 hunks)packages/vite/src/plugins/replace.ts(1 hunks)packages/vite/src/plugins/ssr-styles.ts(1 hunks)packages/vite/src/plugins/stable-entry.ts(1 hunks)packages/vite/src/plugins/vite-node.ts(1 hunks)packages/vite/src/plugins/vite-plugin-checker.ts(1 hunks)packages/vite/src/runtime/vite-node-shared.mjs(2 hunks)packages/vite/src/server.ts(2 hunks)packages/vite/src/vite.ts(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Follow standard TypeScript conventions and best practices
Files:
packages/vite/src/plugins/vite-node.tspackages/vite/src/server.tspackages/vite/src/plugins/environments.tspackages/vite/src/plugins/stable-entry.tspackages/vite/src/plugins/vite-plugin-checker.tspackages/vite/src/plugins/layer-dep-optimize.tspackages/vite/src/plugins/analyze.tspackages/vite/src/plugins/replace.tspackages/vite/src/client.tspackages/vite/src/plugins/ssr-styles.tspackages/vite/src/plugins/dev-server.tspackages/vite/src/vite.ts
🧠 Learnings (1)
📚 Learning: 2024-11-05T15:22:54.759Z
Learnt from: GalacticHypernova
PR: nuxt/nuxt#26468
File: packages/nuxt/src/components/plugins/loader.ts:24-24
Timestamp: 2024-11-05T15:22:54.759Z
Learning: In `packages/nuxt/src/components/plugins/loader.ts`, the references to `resolve` and `distDir` are legacy code from before Nuxt used the new unplugin VFS and will be removed.
Applied to files:
packages/vite/src/plugins/vite-node.ts
🧬 Code graph analysis (4)
packages/vite/src/server.ts (1)
packages/vite/src/plugins/vite-plugin-checker.ts (1)
VitePluginCheckerPlugin(5-23)
packages/vite/src/client.ts (3)
packages/vite/src/plugins/analyze.ts (1)
AnalyzePlugin(7-53)packages/vite/src/plugins/dev-server.ts (1)
DevServerPlugin(10-140)packages/vite/src/plugins/vite-plugin-checker.ts (1)
VitePluginCheckerPlugin(5-23)
packages/vite/src/plugins/ssr-styles.ts (2)
packages/schema/src/types/nuxt.ts (1)
Nuxt(89-116)packages/vite/src/utils/config.ts (1)
resolveClientEntry(3-15)
packages/vite/src/vite.ts (3)
packages/vite/src/plugins/replace.ts (1)
ReplacePlugin(5-31)packages/vite/src/plugins/layer-dep-optimize.ts (1)
LayerDepOptimizePlugin(6-40)packages/vite/src/plugins/ssr-styles.ts (1)
SSRStylesPlugin(17-297)
🪛 ast-grep (0.39.6)
packages/vite/src/plugins/dev-server.ts
[warning] 93-99: 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(
^${handler.route .replace(/[.+?^${}()|[\]\\]/g, '\\$&') // escape regex syntax characters .replace(/:[^/]+/g, '[^/]+') // dynamic segments (:param) .replace(/\*\*/g, '.*') // double wildcard (**) to match any path .replace(/\*/g, '[^/]*')}$, // single wildcard (*) to match any segment
)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: code
- GitHub Check: build
🔇 Additional comments (6)
packages/vite/src/runtime/vite-node-shared.mjs (2)
7-10: Typedef path updates look correctPointing to ../plugins/vite-node aligns with the refactor.
221-225: JSDoc types aligned with plugins/vite-nodeReferences updated consistently; no issues spotted.
packages/vite/src/server.ts (2)
12-12: Import path switch to plugins/vite-nodeMatches the new structure; OK.
33-34: Async checker plugin in SSR pipelineUsing VitePluginCheckerPlugin(nuxt, 'ssr') directly in plugins is acceptable since Vite supports Promise and nested arrays. Manually verify your installed Vite version’s PluginOption type includes Promise support.
packages/vite/src/vite.ts (1)
149-152: Plugin ordering looks goodPublicDirs → Replace → LayerDepOptimize → SSRStyles is sensible for resolves/replacements before style processing.
packages/vite/src/client.ts (1)
122-125: Async plugins in array are acceptableAnalyze/Checker return async plugin options; Vite handles Promise and nested arrays. Looks fine.
If any issue arises with plugin resolution order, explicitly await them:
- AnalyzePlugin(nuxt), - DevServerPlugin(nuxt), - VitePluginCheckerPlugin(nuxt, 'client'), + await AnalyzePlugin(nuxt), + DevServerPlugin(nuxt), + await VitePluginCheckerPlugin(nuxt, 'client'),
WalkthroughThe PR restructures Nuxt’s Vite integration to a plugin-based architecture. It introduces multiple plugins (DevServerPlugin, EnvironmentsPlugin, ReplacePlugin, LayerDepOptimizePlugin, SSRStylesPlugin, VitePluginCheckerPlugin) and updates AnalyzePlugin and StableEntryPlugin. Significant inlined config and server logic in client/server/vite orchestration is removed and delegated to these plugins. Dev server behaviour, environment-specific aliases/outputs, replace handling, layer dep optimisation, SSR CSS handling, and type-checker integration are moved into dedicated plugins. Vite Node imports and runtime typedefs are updated to the plugins path. Function signatures change for AnalyzePlugin and SSRStylesPlugin. Client and server build flows are adjusted to use the new plugins. Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/vite/src/client.ts (1)
117-119: Remove duplicate TypeCheckPlugin registrationTypeCheckPlugin only injects the vite-plugin-checker runtime entry, which VitePluginCheckerPlugin already handles (plus actual type-checking). Delete its import and invocation in client.ts to avoid duplicate overlays.
-import { TypeCheckPlugin } from './plugins/type-check' ... - // Type checking client panel - TypeCheckPlugin(nuxt),
🧹 Nitpick comments (12)
packages/vite/src/plugins/vite-node.ts (2)
221-232: Deduplicate socket cleanup logic in buildEndbuildEnd repeats cleanupSocket. Call the helper to keep behaviour consistent.
- async buildEnd () { - if (socketServer && socketServer.listening) { - await new Promise<void>(resolveClose => socketServer!.close(() => resolveClose())) - } - if (socketPath && !socketPath.startsWith('\\\\.\\pipe\\')) { - try { - await unlink(socketPath) - } catch { - // Error is ignored if the file doesn't exist or cannot be unlinked - } - } - }, + async buildEnd () { + await cleanupSocket() + },
416-424: Skip unlink for Linux abstract sockets and avoid sync FS call (optional)currentSocketPath may be an abstract socket ('\0…'), which isn’t a filesystem entry. Guard for that (and consider using async unlink for non-blocking IO).
- // Clean up existing socket file (Unix only) - if (!currentSocketPath.startsWith('\\\\.\\pipe\\')) { + // Clean up existing socket file (Unix only; skip Windows pipes and Linux abstract sockets) + if (!currentSocketPath.startsWith('\\\\.\\pipe\\') && currentSocketPath.charCodeAt(0) !== 0) { try { - fs.unlinkSync(currentSocketPath) + fs.unlinkSync(currentSocketPath) } catch (unlinkError: any) { if (unlinkError.code !== 'ENOENT') { // Socket cleanup failed, but continue anyway } } }packages/vite/src/plugins/replace.ts (2)
9-20: Micro-optimisation: return early if there’s nothing to replaceAvoid adding a no-op plugin when no import.meta.* defines exist.
const replaceOptions: Record<string, string> = Object.create(null) @@ - for (const define of [config.define || {}, environment.config.define || {}]) { + for (const define of [config.define || {}, environment.config.define || {}]) { // ... } + if (Object.keys(replaceOptions).length === 0) { + return false + }
22-29: Avoid identifier shadowing between rollup and rolldown replace pluginsShadowing replacePlugin can be confusing. Rename for clarity and ensure option shape matches rolldown’s expected API.
-import replacePlugin from '@rollup/plugin-replace' +import rollupReplacePlugin from '@rollup/plugin-replace' @@ - if (vite.rolldownVersion) { - const { replacePlugin } = await import('rolldown/experimental') - return replacePlugin(replaceOptions) + if (vite.rolldownVersion) { + const { replacePlugin: rolldownReplacePlugin } = await import('rolldown/experimental') + return rolldownReplacePlugin(replaceOptions) } else { - return replacePlugin({ ...replaceOptions, preventAssignment: true }) + return rollupReplacePlugin({ ...replaceOptions, preventAssignment: true }) }packages/vite/src/plugins/stable-entry.ts (1)
67-71: Stale TODO commentYou’ve adopted the environment API here already. Consider removing or updating the TODO to reflect remaining gaps (if any).
packages/vite/src/plugins/ssr-styles.ts (3)
96-160: Avoid shadowing and clarify variable names in generateBundle (optional)Inner const file shadows the outer loop variable file. It’s correct due to block scope, but renaming improves readability.
- for (const css of files) { - const file = this.getFileName(css) + for (const css of files) { + const outFile = this.getFileName(css) if (cssImports.has(file)) { continue } - cssImports.add(file) + cssImports.add(outFile) const name = `style_${i++}` - importStatements.add(genImport(`./${relative(baseDir, file)}`, name)) + importStatements.add(genImport(`./${relative(baseDir, outFile)}`, name)) exportNames.add(name) }
196-226: Global CSS handling: warn path is good; also import as side-effect when unresolved (optional)When a global CSS entry can’t be resolved for inlining, you prepend an import — good fallback. Consider normalising nuxt.options.css to string[] earlier to handle objects like { src } consistently.
228-246: Early-return condition may skip static CSS import scanning for non-island modulestransform() returns early when !(id in clientCSSMap) and not an island, which skips the later static import scan. If that’s intentional (teleport only client-observed CSS), ignore. Otherwise, consider moving the static import scan before this guard.
packages/vite/src/plugins/layer-dep-optimize.ts (1)
15-19: Normalise both paths to avoid Windows mismatchesNormalise layer directories too (and rootDir) before startsWith checks; currently only the importer is normalised.
- const delimitedRootDir = nuxt.options.rootDir + '/' + const root = normalize(nuxt.options.rootDir) + const delimitedRootDir = root.endsWith('/') ? root : root + '/' - if (dirs.app !== nuxt.options.srcDir && !dirs.app.startsWith(delimitedRootDir)) { - layerDirs.push(dirs.app) + if (dirs.app !== nuxt.options.srcDir) { + const appDir = normalize(dirs.app) + if (!appDir.startsWith(delimitedRootDir)) { + layerDirs.push(appDir) + } }Also applies to: 29-36
packages/vite/src/plugins/analyze.ts (1)
19-51: Optionally gate analyse to build mode.Visualizer and generateBundle are no-ops in dev but still add plugin overhead. Consider enabling only when !nuxt.options.dev.
packages/vite/src/plugins/environments.ts (1)
23-31: Consider scoping base override to the client environment.Setting base: './' globally may affect SSR tooling unintentionally. If only the client build needs a relative base, move this into configEnvironment('client').
packages/vite/src/plugins/dev-server.ts (1)
91-101: Dynamic regex from routes: safe but consider path-to-regexp for robustness.You escape and normalise well; still, using a proven router pattern compiler (e.g. path-to-regexp) reduces future maintenance and ReDoS risks.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
packages/vite/src/client.ts(2 hunks)packages/vite/src/plugins/analyze.ts(1 hunks)packages/vite/src/plugins/dev-server.ts(1 hunks)packages/vite/src/plugins/environments.ts(1 hunks)packages/vite/src/plugins/layer-dep-optimize.ts(1 hunks)packages/vite/src/plugins/replace.ts(1 hunks)packages/vite/src/plugins/ssr-styles.ts(1 hunks)packages/vite/src/plugins/stable-entry.ts(1 hunks)packages/vite/src/plugins/vite-node.ts(1 hunks)packages/vite/src/plugins/vite-plugin-checker.ts(1 hunks)packages/vite/src/runtime/vite-node-shared.mjs(2 hunks)packages/vite/src/server.ts(2 hunks)packages/vite/src/vite.ts(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Follow standard TypeScript conventions and best practices
Files:
packages/vite/src/plugins/dev-server.tspackages/vite/src/plugins/replace.tspackages/vite/src/plugins/analyze.tspackages/vite/src/plugins/stable-entry.tspackages/vite/src/server.tspackages/vite/src/plugins/vite-node.tspackages/vite/src/plugins/vite-plugin-checker.tspackages/vite/src/plugins/environments.tspackages/vite/src/plugins/layer-dep-optimize.tspackages/vite/src/client.tspackages/vite/src/vite.tspackages/vite/src/plugins/ssr-styles.ts
🧠 Learnings (1)
📚 Learning: 2024-11-05T15:22:54.759Z
Learnt from: GalacticHypernova
PR: nuxt/nuxt#26468
File: packages/nuxt/src/components/plugins/loader.ts:24-24
Timestamp: 2024-11-05T15:22:54.759Z
Learning: In `packages/nuxt/src/components/plugins/loader.ts`, the references to `resolve` and `distDir` are legacy code from before Nuxt used the new unplugin VFS and will be removed.
Applied to files:
packages/vite/src/plugins/vite-node.ts
🧬 Code graph analysis (4)
packages/vite/src/server.ts (1)
packages/vite/src/plugins/vite-plugin-checker.ts (1)
VitePluginCheckerPlugin(5-23)
packages/vite/src/client.ts (3)
packages/vite/src/plugins/analyze.ts (1)
AnalyzePlugin(7-53)packages/vite/src/plugins/dev-server.ts (1)
DevServerPlugin(10-140)packages/vite/src/plugins/vite-plugin-checker.ts (1)
VitePluginCheckerPlugin(5-23)
packages/vite/src/vite.ts (4)
packages/vite/src/plugins/replace.ts (1)
ReplacePlugin(5-31)packages/vite/src/plugins/layer-dep-optimize.ts (1)
LayerDepOptimizePlugin(6-40)packages/vite/src/plugins/ssr-styles.ts (1)
SSRStylesPlugin(17-297)packages/vite/src/plugins/environments.ts (1)
EnvironmentsPlugin(10-84)
packages/vite/src/plugins/ssr-styles.ts (2)
packages/schema/src/types/nuxt.ts (1)
Nuxt(89-116)packages/vite/src/utils/config.ts (1)
resolveClientEntry(3-15)
🪛 ast-grep (0.39.6)
packages/vite/src/plugins/dev-server.ts
[warning] 93-99: 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(
^${handler.route .replace(/[.+?^${}()|[\]\\]/g, '\\$&') // escape regex syntax characters .replace(/:[^/]+/g, '[^/]+') // dynamic segments (:param) .replace(/\*\*/g, '.*') // double wildcard (**) to match any path .replace(/\*/g, '[^/]*')}$, // single wildcard (*) to match any segment
)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: codeql (javascript-typescript)
- GitHub Check: build
- GitHub Check: code
🔇 Additional comments (10)
packages/vite/src/plugins/vite-node.ts (2)
19-21: Import path updates look fine; please confirm resolution across the refactorSwitching to parent-scoped utilities matches the new plugins layout. Just confirm ../dirs, ../utils, and ../utils/config are the intended canonical entry points to avoid duplicate bundles or circular refs.
182-205: Potential hook timing race: ensure the SSR server hook is registered before SSR server creationconfigureServer runs for the client environment only, and registers the 'vite:serverCreated' hook. If the SSR Vite server can be created before this hook is registered, the socket server won’t be initialised. Please verify creation order or register this hook earlier (or handle the already-created case).
packages/vite/src/plugins/stable-entry.ts (1)
26-40: Environment gating logic looks goodApplies only in prod with entryImportMap, client env, supported targets, and hashed entry filenames. This aligns with import maps support constraints. LGTM.
Please confirm toArray returns [] for undefined output to avoid accidental truthiness on [undefined].
packages/vite/src/runtime/vite-node-shared.mjs (1)
7-10: Type path move to plugins/vite-node: looks correct; verify runtime packagingPaths now reference ../plugins/vite-node. Ensure the runtime bundle includes these types/exports after the refactor so downstream JSDoc types resolve, and that the generated dist preserves the same relative structure.
Also applies to: 221-225
packages/vite/src/plugins/ssr-styles.ts (1)
17-25: No-op in dev and Nitro manifest wiring: sensibleEarly return in dev and build:manifest hook to strip CSS where inlined looks sound.
packages/vite/src/server.ts (2)
17-17: Checker integration for SSR looks goodEnvironment-scoped usage via applyToEnvironment aligns with Vite 6 Environment API. No issues spotted.
Also applies to: 33-34
12-12: No action needed –writeDevServeris correctly exported
Export found in packages/vite/src/plugins/vite-node.ts at line 502.packages/vite/src/client.ts (1)
15-16: ViteNodePlugin import path is correctThe
ViteNodePluginfunction is exported frompackages/vite/src/plugins/vite-node.ts, matching the import inclient.ts.packages/vite/src/plugins/vite-plugin-checker.ts (1)
5-22: LGTM: environment-scoped type checking vite-plugin-checker (^0.11.0) is declared in packages/vite/package.json.packages/vite/src/vite.ts (1)
3-3: Add missing static import for replacePluginThe
elsebranch inpackages/vite/src/plugins/replace.tscallsreplacePlugin(...)without importing it. Insert at the top:+ import replacePlugin from '@rollup/plugin-replace'Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (3)
packages/vite/src/plugins/dev-server.ts (2)
21-23: Good fix: safe Set construction from possibly undefined excludeUsing item.exclude ?? [] avoids runtime errors. This resolves earlier feedback.
33-36: Good fix: guard config.server before writing corsInitialising config.server prevents TypeError when setting cors.
packages/vite/src/plugins/analyze.ts (1)
12-15: Fix boolean build.analyse semantics: true should enable plugindefu({}, true) → {} so .enabled is undefined and the plugin exits. Normalise boolean to enabled.
- const analyzeOptions = defu({}, nuxt.options.build.analyze) as Exclude<NuxtOptions['build']['analyze'], boolean> - if (!analyzeOptions.enabled) { - return - } + const analyze = nuxt.options.build.analyze + if (!analyze) { + return + } + const analyzeOptions = typeof analyze === 'boolean' + ? { enabled: true } + : defu({ enabled: true }, analyze as Exclude<NuxtOptions['build']['analyze'], boolean>) + if (analyzeOptions.enabled === false) { + return + }
🧹 Nitpick comments (4)
packages/vite/src/plugins/dev-server.ts (3)
79-84: Insert skip-transform middleware before transform deterministicallyIf viteTransformMiddleware is not found, pushing to the end may place mw after transform. Unshift to guarantee it runs before transform.
- if (transformHandler === -1) { - viteServer.middlewares.stack.push(mw) - } else { + if (transformHandler === -1) { + viteServer.middlewares.stack.unshift(mw) + } else { viteServer.middlewares.stack.splice(transformHandler, 0, mw) }
93-104: Route regex construction from variable input: consider safer, faster approachDynamic RegExp can still be error-prone and potentially expensive. Prefer a battle-tested router pattern utility (e.g. path-to-regexp) to compile handler.route safely with anchors and segment semantics, or at least cap greedy patterns.
Based on static analysis hints
114-118: Skip-transform condition likely never triggers when base is "/" (unnecessary base check)With base "/" the first predicate is always false, so _skip_transform is never set; transform won’t be bypassed for non‑Vite routes. Rely solely on discovered viteRoutes.
- if (!event.path.startsWith(viteServer.config.base!) && !viteRoutes.some(route => event.path.startsWith(route))) { + if (!viteRoutes.some(route => event.path.startsWith(route))) { // @ts-expect-error _skip_transform is a private property event.node.req._skip_transform = true } else if (!useViteCors) {packages/vite/src/vite.ts (1)
150-154: Filter optional plugins to avoid undefined entriesLayerDepOptimizePlugin and SSRStylesPlugin may return undefined. Filter falsy to keep Vite’s plugin array clean.
- plugins: [ + plugins: ([ // add resolver for files in public assets directories PublicDirsPlugin({ dev: nuxt.options.dev, baseURL: nuxt.options.app.baseURL, }), ReplacePlugin(), LayerDepOptimizePlugin(nuxt), SSRStylesPlugin(nuxt), EnvironmentsPlugin(nuxt), - ], + ] as (vite.Plugin | undefined)[]).filter(Boolean) as vite.Plugin[],
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/vite/src/plugins/analyze.ts(1 hunks)packages/vite/src/plugins/dev-server.ts(1 hunks)packages/vite/src/vite.ts(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Follow standard TypeScript conventions and best practices
Files:
packages/vite/src/vite.tspackages/vite/src/plugins/dev-server.tspackages/vite/src/plugins/analyze.ts
🧬 Code graph analysis (1)
packages/vite/src/vite.ts (4)
packages/vite/src/plugins/replace.ts (1)
ReplacePlugin(5-31)packages/vite/src/plugins/layer-dep-optimize.ts (1)
LayerDepOptimizePlugin(6-40)packages/vite/src/plugins/ssr-styles.ts (1)
SSRStylesPlugin(17-297)packages/vite/src/plugins/environments.ts (1)
EnvironmentsPlugin(10-84)
🪛 ast-grep (0.39.6)
packages/vite/src/plugins/dev-server.ts
[warning] 95-101: 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(
^${handler.route .replace(/[.+?^${}()|[\]\\]/g, '\\$&') // escape regex syntax characters .replace(/:[^/]+/g, '[^/]+') // dynamic segments (:param) .replace(/\*\*/g, '.*') // double wildcard (**) to match any path .replace(/\*/g, '[^/]*')}$, // single wildcard (*) to match any segment
)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: code
🔇 Additional comments (1)
packages/vite/src/plugins/dev-server.ts (1)
134-138: Handled-state check is solidUsing res.writableEnded || event.handled avoids false 404s when upstream ended the response. LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
packages/vite/src/plugins/analyze.ts (1)
12-15: Preserve build.analyze boolean semantics (true should enable plugin)defu({}, true) => {} so analyzeOptions.enabled is undefined and the plugin exits; build.analyze: true should enable defaults. This is a regression already noted earlier.
- const analyzeOptions = defu({}, nuxt.options.build.analyze) as Exclude<NuxtOptions['build']['analyze'], boolean> - if (!analyzeOptions.enabled) { - return - } + const analyze = nuxt.options.build.analyze + if (!analyze) { + return + } + const analyzeOptions = typeof analyze === 'boolean' + ? { enabled: true } + : defu({ enabled: true }, analyze as Exclude<NuxtOptions['build']['analyze'], boolean>) + if (analyzeOptions.enabled === false) { + return + }
🧹 Nitpick comments (2)
packages/vite/src/vite.ts (1)
123-131: Avoid possible undefined access in assetFileNameschunk.names[0]! can be undefined for some assets. Use a safe fallback (names[0], then name, then a default).
- assetFileNames: nuxt.options.dev - ? undefined - : chunk => withoutLeadingSlash(join(nuxt.options.app.buildAssetsDir, `${sanitizeFilePath(filename(chunk.names[0]!))}.[hash].[ext]`)), + assetFileNames: nuxt.options.dev + ? undefined + : (chunk) => { + const primaryName = + (Array.isArray((chunk as any).names) && (chunk as any).names[0]) || + (chunk as any).name || + 'asset' + return withoutLeadingSlash( + join(nuxt.options.app.buildAssetsDir, `${sanitizeFilePath(filename(primaryName))}.[hash].[ext]`), + ) + },packages/vite/src/plugins/dev-server.ts (1)
95-103: Harden dynamic route-to-RegExp conversion (ReDoS/perf risk)Routes are user-configurable. Even with escaping/anchoring, constructing RegExp from variable input risks catastrophic backtracking.
- Prefer using a proven router/compilator (e.g. path-to-regexp) to compile patterns safely.
- If staying with strings:
- Keep anchors (^ $) and escape as you do.
- Replace patterns with atomic/possessive equivalents where supported, or simplify:
- Use
[^/]+for:param- Use non-greedy segments for
*/**with explicit path boundaries- Consider bounding input length or pre-validating allowed tokens.
Example with path-to-regexp:
import { pathToRegexp } from 'path-to-regexp' // ... devHandlerRegexes.push(pathToRegexp(handler.route))Based on static analysis hints.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/vite/src/plugins/analyze.ts(1 hunks)packages/vite/src/plugins/dev-server.ts(1 hunks)packages/vite/src/vite.ts(3 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Follow standard TypeScript conventions and best practices
Files:
packages/vite/src/vite.tspackages/vite/src/plugins/analyze.tspackages/vite/src/plugins/dev-server.ts
🧬 Code graph analysis (2)
packages/vite/src/vite.ts (4)
packages/vite/src/plugins/replace.ts (1)
ReplacePlugin(5-31)packages/vite/src/plugins/layer-dep-optimize.ts (1)
LayerDepOptimizePlugin(6-40)packages/vite/src/plugins/ssr-styles.ts (1)
SSRStylesPlugin(17-297)packages/vite/src/plugins/environments.ts (1)
EnvironmentsPlugin(10-84)
packages/vite/src/plugins/analyze.ts (1)
packages/vite/src/vite.ts (1)
bundle(31-189)
🪛 ast-grep (0.39.6)
packages/vite/src/plugins/dev-server.ts
[warning] 95-101: 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(
^${handler.route .replace(/[.+?^${}()|[\]\\]/g, '\\$&') // escape regex syntax characters .replace(/:[^/]+/g, '[^/]+') // dynamic segments (:param) .replace(/\*\*/g, '.*') // double wildcard (**) to match any path .replace(/\*/g, '[^/]*')}$, // single wildcard (*) to match any segment
)
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (19)
- GitHub Check: test-fixtures (ubuntu-latest, built, rspack, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, built, webpack, default, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, built, vite, default, manifest-off, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, built, webpack, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, built, rspack, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, built, vite, async, manifest-off, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, built, webpack, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, built, vite, default, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, dev, vite, default, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, dev, vite, default, manifest-off, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, dev, vite, async, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (windows-latest, dev, vite, async, manifest-off, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, dev, vite, default, manifest-off, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, built, rspack, default, manifest-on, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-on, js, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-off, json, lts/-1)
- GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-on, json, lts/-1)
- GitHub Check: test-benchmark
- GitHub Check: typecheck (windows-latest, bundler)
CodSpeed Performance ReportMerging #33445 will improve performances by 23.79%Comparing Summary
Benchmarks breakdown
|
🔗 Linked issue
📚 Description
this is an initial step to make vite plugins compatible with the environment api