Skip to content

Conversation

@Flo0806
Copy link
Member

@Flo0806 Flo0806 commented Oct 23, 2025

🔗 Linked issue

Fixes: #33538

Summary

Fixes dependency optimization errors in Vite by excluding Nuxt virtual modules from optimizeDeps.

Summary

Fixes Vite dependency optimization errors by properly configuring optimizeDeps for the client environment.

Problem

When using Vite's environment API, users encountered errors like:
✘ [ERROR] The entry point "ufo" cannot be marked as external
Error during dependency optimization

Root Cause:
In Vite, optimizeDeps configuration is not inherited by environments (see Vite
docs
). The clientEnvironment() function in client.ts defines the proper
optimizeDeps configuration, but it wasn't being applied to the client environment in configEnvironment().

Solution

1. /packages/vite/src/plugins/environments.ts:
Explicitly set optimizeDeps from clientEnvironment() configuration:

  const clientEnv = clientEnvironment(nuxt, entry)
  config.optimizeDeps = clientEnv.optimizeDeps

2. /packages/vite/src/shared/client.ts:
Extended the optimizeDeps.exclude list to include all Nuxt virtual modules (#imports, #app, #build/*, etc.) that are
resolved by Nuxt's own module resolution and should not be optimized by Vite.

Test Plan

  • Run test suite - all tests pass
  • Verify "entry point cannot be marked as external" error is resolved
  • Verify no "#imports" or "#build/*" resolution errors

References

@Flo0806 Flo0806 requested a review from danielroe as a code owner October 23, 2025 17:50
@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@github-actions github-actions bot added the 4.x label Oct 23, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 23, 2025

Walkthrough

The Vite environments plugin now captures the Vite inline config via a local viteConfig set in the config(config) hook and uses it in configEnvironment. When the experimental viteEnvironmentApi is disabled and SSR is active the code ensures optimizeDeps exists and clears its include list. In SSR paths the plugin disables manualChunks when output is present and not an array, and disables advanced chunking when a Rollup version is detected. The client shared module extends optimizeDeps.exclude with test utils, get-port-please and several Nuxt virtual-module patterns. The resolved-externals plugin now exposes a config() hook returning optimizeDeps.exclude and moves its resolveId logic inside the object returned by applyToEnvironment (as a named hook with per-id resolveId).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues Check ✅ Passed The code changes address the core requirements of linked issue #33538. The pull request implements the two primary solutions: explicitly setting optimizeDeps from clientEnvironment() in environments.ts, and extending optimizeDeps.exclude in client.ts to include Nuxt virtual modules (#imports, #app, #build/*, etc.) that should not be optimised by Vite. Additionally, resolved-externals.ts has been refactored to properly surface the external set as optimizeDeps.exclude configuration. These changes directly target the root cause of the "entry point cannot be marked as external" error by ensuring the client environment's optimizeDeps configuration is applied and Nuxt virtual modules are excluded from dependency optimisation.
Out of Scope Changes Check ✅ Passed The code changes appear to be within scope of the stated objective to fix Vite dependency optimisation errors. The primary changes—setting optimizeDeps configuration, extending the exclude list with Nuxt virtual modules, and refactoring resolved-externals to properly handle optimizeDeps.exclude—directly address the linked issue. Additional SSR-specific configuration logic for handling optimizeDeps guards and Rolldown-related settings are supporting changes that enable proper configuration across different environment scenarios. All modifications serve the core objective of preventing dependency optimisation errors by ensuring correct Vite configuration.
Description Check ✅ Passed The pull request description is comprehensive and directly related to the changeset. It provides the linked issue reference, explains the root cause (optimizeDeps not being inherited by environments), outlines the solution with specific code changes to environments.ts and client.ts, and includes a test plan. The description demonstrates a clear understanding of the problem and the implemented fix, and all explained changes are present in the actual code modifications.
Title Check ✅ Passed The pull request title "fix(vite): unset optimizeDeps.include for server environment" accurately describes one specific change present in the changeset—the clearing of the optimizeDeps.include list in the SSR branch within packages/vite/src/plugins/environments.ts. However, this is a partial representation of the overall PR objectives. The primary purpose stated in the PR objectives is to "exclude Nuxt virtual modules from dependency optimization and correctly apply client-specific optimizeDeps configuration," which is achieved mainly through modifications to packages/vite/src/shared/client.ts (adding extensive exclusions for virtual modules like '#imports', '#app', '#build/*', etc.). The title focuses on a secondary aspect of the implementation rather than highlighting the main problem being solved and the primary changes driving the fix.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 08900f6 and 6088f37.

📒 Files selected for processing (2)
  • packages/vite/src/plugins/environments.ts (3 hunks)
  • packages/vite/src/shared/client.ts (1 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/shared/client.ts
  • packages/vite/src/plugins/environments.ts
🧬 Code graph analysis (1)
packages/vite/src/plugins/environments.ts (2)
packages/vite/src/plugins/dev-server.ts (1)
  • config (15-57)
packages/vite/src/shared/client.ts (1)
  • clientEnvironment (4-87)
⏰ 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). (1)
  • GitHub Check: build
🔇 Additional comments (2)
packages/vite/src/shared/client.ts (1)

50-61: Virtual module exclusions look comprehensive and well-documented.

The updated comment clearly explains why these modules are excluded, and the list covers the key Nuxt virtual modules that should not undergo Vite's dependency optimisation. This directly addresses the PR objective of preventing the "entry point cannot be marked as external" error.

Note: Some patterns may be redundant (e.g., '#build' when '#build/*' is present, and 'virtual:nuxt:' when 'virtual:nuxt:*' is present), but this doesn't affect functionality and may provide explicit documentation of exact module names.

packages/vite/src/plugins/environments.ts (1)

71-78: Documentation improvements enhance code clarity.

The added comments clearly explain why manual chunks are disabled for the SSR environment and the conditional disabling of advanced chunks when using Rolldown. These clarifications improve code maintainability.

Comment on lines 35 to 47
// Extract entry point for clientEnvironment configuration
const input = config.build?.rollupOptions?.input
const entry = typeof input === 'object' && input !== null && !Array.isArray(input)
? (input as Record<string, string>).entry || ''
: typeof input === 'string' ? input : ''

// Get client environment configuration including optimizeDeps
const clientEnv = clientEnvironment(nuxt, entry)

// Explicitly set optimizeDeps from client environment configuration
// This is necessary because optimizeDeps is not inherited by environments
// See: https://vite.dev/guide/api-environment
config.optimizeDeps = clientEnv.optimizeDeps
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Core logic correctly applies optimizeDeps from clientEnvironment.

This implementation directly addresses the PR objective by explicitly setting config.optimizeDeps from the client environment configuration, resolving the issue where optimizeDeps was not inherited by environments.

However, verify that the empty string fallback on line 39 doesn't cause issues when no valid entry point is found. When entry is '', the clientEnvironment function will receive it and set entries: [''], which may result in ineffective dependency optimisation configuration.


🏁 Script executed:

#!/bin/bash
# Verify how Vite handles empty string in optimizeDeps.entries
# Search for other usages of Rollup input extraction in Nuxt codebase

rg -n -C3 --type=ts "rollupOptions.*input" -g '!node_modules' -g '!dist' -g '!.nuxt'

Length of output: 2225


Use utility function to ensure entry point validation.

The code at lines 35-47 correctly applies optimizeDeps from client environment configuration. However, the entry point extraction (lines 36-39) allows an empty string fallback without validation, which is inconsistent with the error handling in resolveClientEntry and resolveServerEntry utility functions in packages/vite/src/utils/config.ts. Those functions throw an error when no entry is found, establishing a validation pattern that environments.ts should follow.

Replace the manual extraction logic with resolveClientEntry to ensure proper validation:

const entry = resolveClientEntry(config)
const clientEnv = clientEnvironment(nuxt, entry)

This ensures the entry point is validated before being passed to clientEnvironment, preventing silent fallback to empty string and maintaining consistency with existing error-handling patterns in the codebase.

🤖 Prompt for AI Agents
In packages/vite/src/plugins/environments.ts around lines 35 to 47, the entry
extraction silently falls back to an empty string instead of validating the
client entry; replace the manual extraction with a call to the existing
resolveClientEntry(config) utility so the entry is validated (and will throw if
missing) before passing it to clientEnvironment, remove the current manual
input/type checks, and add the necessary import for resolveClientEntry from
packages/vite/src/utils/config.ts.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Oct 23, 2025

Open in StackBlitz

@nuxt/kit

npm i https://pkg.pr.new/@nuxt/kit@33550

nuxt

npm i https://pkg.pr.new/nuxt@33550

@nuxt/rspack-builder

npm i https://pkg.pr.new/@nuxt/rspack-builder@33550

@nuxt/schema

npm i https://pkg.pr.new/@nuxt/schema@33550

@nuxt/vite-builder

npm i https://pkg.pr.new/@nuxt/vite-builder@33550

@nuxt/webpack-builder

npm i https://pkg.pr.new/@nuxt/webpack-builder@33550

commit: f9976f2

@Flo0806 Flo0806 changed the title fix(nuxt): exclude Nuxt virtual modules from dependency optimization fix(vite): exclude Nuxt virtual modules from dependency optimization Oct 23, 2025
@Flo0806 Flo0806 changed the title fix(vite): exclude Nuxt virtual modules from dependency optimization fix(vite): exclude Nuxt virtual modules from dependency optimization Oct 23, 2025
@codspeed-hq
Copy link

codspeed-hq bot commented Oct 23, 2025

CodSpeed Performance Report

Merging #33550 will improve performances by 12.17%

Comparing Flo0806:fix/vite-virtual-modules-optimization (17b80d3) with main (b51cb30)1

Summary

⚡ 1 improvement
✅ 9 untouched

Benchmarks breakdown

Benchmark BASE HEAD Change
loadNuxtConfig in the empty directory 24.3 ms 21.7 ms +12.17%

Footnotes

  1. No successful run was found on main (b7ccf17) during the generation of this report, so b51cb30 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Comment on lines +56 to +63
'#imports',
'#app',
'#build',
'#build/*',
'#components',
'#head',
'virtual:nuxt:',
'virtual:nuxt:*',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Flo0806 was there a particular reason you added these?

Copy link
Member Author

@Flo0806 Flo0806 Oct 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, without these many tests was failing, because the client part was searching for these imports - and they doesn't exists. (pnpm test:runtime)

@danielroe danielroe changed the title fix(vite): exclude Nuxt virtual modules from dependency optimization fix(vite): unset optimizeDeps.include for server environment Oct 24, 2025
@danielroe danielroe merged commit 7db30a6 into nuxt:main Oct 24, 2025
53 of 56 checks passed
@github-actions github-actions bot mentioned this pull request Oct 24, 2025
@github-actions github-actions bot mentioned this pull request Nov 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[nightly] vite-env-api: The entry point "ufo" cannot be marked as external

2 participants