Skip to content

Conversation

danielroe
Copy link
Member

🔗 Linked issue

📚 Description

we've had some bits of code that have respected compatibilityVersion: 3 but this is removed in v4 and we can remove the duplicate handling

@Copilot Copilot AI review requested due to automatic review settings June 1, 2025 22:01
Copy link

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

Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Removes legacy compatibilityVersion: 3 handling and simplifies v4-only logic across schema resolvers, Nuxt modules, and tests.

  • Deletes conditional branches based on compatibilityVersion and assumes v4 behavior by default.
  • Cleans up async resolvers and simplifies path resolution in schema and Nuxt core.
  • Updates tests to drop explicit version flags and expect v4 defaults.

Reviewed Changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/schema/test/folder-structure.spec.ts Remove explicit v4 opt-in flags and update test titles
packages/schema/src/config/experimental.ts Strip out compatibilityVersion checks in experimental resolvers
packages/schema/src/config/common.ts Simplify directory resolvers by removing version branches
packages/schema/src/config/app.ts Streamline renderSSRHeadOptions and drop async version logic
packages/nuxt/test/shared-dir-config.test.ts Assume v4 default in Nitro import dirs test
packages/nuxt/src/pages/module.ts Always include all extraction keys, drop version guard
packages/nuxt/src/imports/module.ts Merge composablesDirs logic, remove version-based filtering
packages/nuxt/src/head/runtime/composables/v3.ts Remove entire v3 head runtime file
packages/nuxt/src/head/module.ts Always alias to new composables path, drop version detection
packages/nuxt/src/core/nitro.ts Remove legacy Nitro config hook and v3 guard
packages/nuxt/src/core/app.ts Always include index middleware files, eliminate version checks
packages/nuxt/package.json Update #unhead/composables import paths to non-v4 suffixes
packages/kit/src/template.ts Drop version flag checks in type generation settings
Comments suppressed due to low confidence (4)

packages/schema/src/config/common.ts:157

  • The serverDir resolver references rootDir without declaring it in the function scope. You should add const rootDir = await get('rootDir') before using it.
return resolve(rootDir, val && typeof val === 'string' ? val : 'server')

packages/schema/src/config/common.ts:348

  • [nitpick] The isV4 constant is always true and only used once. Consider inlining this branch or removing the unused variable to simplify the code.
const isV4 = true

packages/schema/src/config/common.ts:376

  • [nitpick] This isV4 flag is hardcoded to true and not needed—either remove it or inline the conditional to reduce clutter.
const isV4 = true

packages/schema/src/config/common.ts:409

  • [nitpick] Since v3 support is removed, this always-true isV4 declaration can be removed and its branch inlined.
const isV4 = true

Copy link

pkg-pr-new bot commented Jun 1, 2025

Open in StackBlitz

@nuxt/kit

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

nuxt

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

@nuxt/rspack-builder

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

@nuxt/schema

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

@nuxt/vite-builder

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

@nuxt/webpack-builder

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

commit: 8d05f20

Copy link

coderabbitai bot commented Jun 1, 2025

Walkthrough

This change set removes all conditional logic and code branches related to the future.compatibilityVersion flag, specifically eliminating checks for version 4 compatibility across multiple packages. As a result, code paths and configuration resolvers that previously adjusted behaviour based on the compatibility version now assume version 4 unconditionally. This includes always enabling certain TypeScript options, including specific directories for imports and middleware, and setting static defaults for several experimental features. Associated test cases and TypeScript path mappings were updated to reflect the removal of version-based branching. Several version-specific files and functions were deleted or refactored to simplify the codebase.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e6ebb2e and 8d05f20.

📒 Files selected for processing (1)
  • packages/schema/src/config/common.ts (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/schema/src/config/common.ts
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: build
  • GitHub Check: codeql (javascript-typescript)
  • GitHub Check: code
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 0

🔭 Outside diff range comments (1)
packages/schema/src/config/common.ts (1)

4-4: ⚠️ Potential issue

Remove unused import.

The join import is unused and should be removed to fix the pipeline failure.

-import { basename, join, relative, resolve } from 'pathe'
+import { basename, relative, resolve } from 'pathe'
🧰 Tools
🪛 GitHub Check: code

[failure] 4-4:
'join' is defined but never used

🪛 GitHub Actions: autofix.ci

[error] 4-4: ESLint: 'join' is defined but never used. (@typescript-eslint/no-unused-vars)

🧹 Nitpick comments (3)
packages/schema/src/config/common.ts (3)

348-354: Consider further simplification by removing hardcoded isV4.

Whilst the hardcoded isV4 = true correctly assumes v4 behaviour, the conditional branch could be removed entirely for cleaner code.

-    $resolve: async (val, get) => {
-        const isV4 = true
-        if (isV4) {
-          const [srcDir, rootDir] = await Promise.all([get('srcDir'), get('rootDir')])
-          return resolve(await get('srcDir'), val && typeof val === 'string' ? val : (srcDir === rootDir ? 'app' : '.'))
-        }
-        return val && typeof val === 'string' ? val : 'app'
-      },
+    $resolve: async (val, get) => {
+      const [srcDir, rootDir] = await Promise.all([get('srcDir'), get('rootDir')])
+      return resolve(await get('srcDir'), val && typeof val === 'string' ? val : (srcDir === rootDir ? 'app' : '.'))
+    },

375-381: Consider further simplification by removing hardcoded isV4.

Similar to the app directory resolver, the hardcoded isV4 branch could be removed for cleaner code.

-    $resolve: async (val, get) => {
-        const isV4 = true
-        if (isV4) {
-          return resolve(await get('rootDir'), val && typeof val === 'string' ? val : 'modules')
-        }
-        return val && typeof val === 'string' ? val : 'modules'
-      },
+    $resolve: async (val, get) => {
+      return resolve(await get('rootDir'), val && typeof val === 'string' ? val : 'modules')
+    },

408-415: Consider further simplification by removing hardcoded isV4.

The conditional branch with hardcoded isV4 could be removed for consistency and cleaner code.

-    $resolve: async (val, get) => {
-        const isV4 = true
-        if (isV4) {
-          return resolve(await get('rootDir'), val && typeof val === 'string' ? val : (await get('dir.static') || 'public'))
-        }
-        return val && typeof val === 'string' ? val : (await get('dir.static') || 'public')
-      },
+    $resolve: async (val, get) => {
+      return resolve(await get('rootDir'), val && typeof val === 'string' ? val : (await get('dir.static') || 'public'))
+    },
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ec609c and e6ebb2e.

⛔ Files ignored due to path filters (1)
  • packages/nuxt/package.json is excluded by !**/package.json
📒 Files selected for processing (13)
  • packages/kit/src/template.ts (2 hunks)
  • packages/nuxt/src/core/app.ts (1 hunks)
  • packages/nuxt/src/core/nitro.ts (1 hunks)
  • packages/nuxt/src/head/module.ts (2 hunks)
  • packages/nuxt/src/head/runtime/composables/v3.ts (0 hunks)
  • packages/nuxt/src/imports/module.ts (1 hunks)
  • packages/nuxt/src/pages/module.ts (1 hunks)
  • packages/nuxt/test/shared-dir-config.test.ts (1 hunks)
  • packages/schema/src/config/app.ts (1 hunks)
  • packages/schema/src/config/common.ts (5 hunks)
  • packages/schema/src/config/experimental.ts (8 hunks)
  • packages/schema/test/folder-structure.spec.ts (3 hunks)
  • tsconfig.json (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/nuxt/src/head/runtime/composables/v3.ts
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/nuxt/src/pages/module.ts (1)
packages/nuxt/src/pages/utils.ts (1)
  • defaultExtractionKeys (211-211)
🪛 GitHub Actions: autofix.ci
packages/schema/src/config/common.ts

[error] 4-4: ESLint: 'join' is defined but never used. (@typescript-eslint/no-unused-vars)

⏰ Context from checks skipped due to timeout of 90000ms (20)
  • GitHub Check: test-fixtures (windows-latest, built, vite, default, manifest-on, json, 20)
  • GitHub Check: test-fixtures (windows-latest, built, rspack, async, manifest-on, json, 20)
  • GitHub Check: test-fixtures (windows-latest, built, vite, async, manifest-off, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, webpack, async, manifest-on, json, 20)
  • GitHub Check: test-fixtures (windows-latest, dev, vite, async, manifest-on, json, 20)
  • GitHub Check: test-fixtures (windows-latest, dev, vite, async, manifest-off, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, default, manifest-off, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, default, manifest-on, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, rspack, default, manifest-on, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, default, manifest-on, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, async, manifest-on, js, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, async, manifest-on, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, default, manifest-off, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-off, json, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-on, js, 20)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-on, json, 20)
  • GitHub Check: release-pr
  • GitHub Check: typecheck (ubuntu-latest, bundler)
  • GitHub Check: test-benchmark
  • GitHub Check: typecheck (windows-latest, bundler)
🔇 Additional comments (25)
packages/schema/src/config/experimental.ts (9)

69-69: LGTM! Simplified inlineStyles resolver.

The removal of async logic and compatibility version checks correctly simplifies the resolver to return a default function for Vue components when no explicit value is provided.


332-334: LGTM! Synchronous scanPageMeta resolver.

The resolver has been simplified from async to synchronous, removing compatibility version dependencies whilst maintaining the same default behaviour of returning 'after-resolve'.


370-372: LGTM! Simplified sharedPrerenderData resolver.

The resolver now directly returns true as the default value when not explicitly set to a boolean, removing the async complexity and compatibility version checks.


438-440: LGTM! Synchronous normalizeComponentNames resolver.

The simplification correctly defaults to true when not explicitly set to a boolean value, removing the previous async and compatibility version dependencies.


448-452: LGTM! Simplified spaLoadingTemplateLocation resolver.

The resolver now directly validates and defaults to 'body' without async operations, maintaining type safety whilst removing compatibility version complexity.


588-590: LGTM! Synchronous granularCachedData resolver.

The resolver has been appropriately simplified to default to true when not explicitly set to a boolean, removing async complexity.


599-601: LGTM! Simplified alwaysRunFetchOnKeyChange resolver.

The resolver now directly defaults to false when not explicitly set to a boolean value, correctly removing async operations and compatibility version checks.


608-610: LGTM! Synchronous parseErrorData resolver.

The simplification appropriately defaults to true when not explicitly set to a boolean, removing the previous async complexity.


622-624: LGTM! Simplified pendingWhenIdle resolver.

The resolver has been correctly simplified to default to false when not explicitly set to a boolean value, maintaining consistency with the overall simplification effort.

tsconfig.json (1)

37-37: LGTM! Simplified path mapping for unhead composables.

The removal of the version-specific /v4 suffix correctly unifies the composables path, aligning with the broader removal of compatibility version logic throughout the codebase.

packages/nuxt/test/shared-dir-config.test.ts (1)

11-11: LGTM! Simplified test to use default compatibility version.

The removal of explicit compatibility version overrides correctly simplifies the test whilst maintaining validation of shared directory import functionality. The test now relies on the default behaviour rather than testing version-specific logic.

packages/nuxt/src/core/app.ts (1)

181-181: LGTM! Unconditional middleware index pattern resolution.

The removal of the compatibility version check correctly ensures that nested middleware files with index patterns (e.g., middleware/auth/index.ts) are always resolved, simplifying the middleware discovery logic whilst maintaining full functionality.

packages/kit/src/template.ts (2)

219-219: LGTM: Correct unconditional v4 behavior

The change to always default hasTypescriptVersionWithModulePreserve to true correctly implements the v4 behavior without version-specific branching.


237-237: LGTM: Stricter TypeScript checking now always enabled

Setting noUncheckedIndexedAccess to always true correctly enforces the stricter TypeScript checking that was conditional in v4 compatibility mode. This improves type safety across the codebase.

packages/nuxt/src/imports/module.ts (1)

77-82: LGTM: Shared directories now unconditionally included

The removal of the isNuxtV4 conditional logic correctly implements the v4-only behavior. Shared directories (shared/utils and shared/types) are now always included alongside composables and utils, which simplifies the code and ensures consistent import scanning behavior.

packages/schema/test/folder-structure.spec.ts (3)

47-48: LGTM: Test updated to reflect v4 default behavior

Removing the explicit future.compatibilityVersion: 4 configuration is correct since v4 is now the default and only supported behavior. The test expectations remain unchanged, confirming that the default configuration now provides the same behavior.


65-65: LGTM: Consistent test simplification

The removal of the explicit compatibility version configuration is consistent with the broader changes and correctly relies on the new v4 default behavior.


82-82: LGTM: Test streamlined for v4-only behavior

The test correctly removes the explicit compatibility version setting, demonstrating that the default behavior now matches the previously conditional v4 configuration.

packages/nuxt/src/pages/module.ts (1)

492-492: LGTM: Page metadata extraction keys now unconditionally comprehensive

The change correctly removes the compatibility version check and always includes the full set of extraction keys (defaultExtractionKeys, 'middleware', and extraPageMetaExtractionKeys). This ensures consistent and comprehensive page metadata extraction, which aligns with the v4-only behavior this PR implements.

From the relevant code snippet, defaultExtractionKeys includes essential page metadata like 'name', 'path', 'props', 'alias', 'redirect', and 'middleware', so including these unconditionally improves the page metadata extraction capabilities.

packages/schema/src/config/app.ts (1)

472-475: LGTM! Simplified resolver correctly assumes v4 behaviour.

The simplification from an async resolver with compatibility version checks to a synchronous resolver that unconditionally sets omitLineBreaks: true is correct and aligns with the removal of compatibilityVersion: 3 support.

packages/nuxt/src/head/module.ts (2)

42-42: LGTM! Simplified alias resolution.

The alias now correctly points to the generic composables directory without version-specific branching, consistent with the removal of compatibility version checks.


56-56: LGTM! Simplified template generation logic.

Removing the isNuxtV4 check and only evaluating options.legacy correctly simplifies the conditional logic whilst maintaining the intended behaviour.

packages/nuxt/src/core/nitro.ts (1)

54-64: LGTM! Simplified shared directories inclusion.

The removal of compatibility version checks and unconditional inclusion of shared directories when imports are enabled correctly assumes v4 behaviour and aligns with the broader simplification effort.

packages/schema/src/config/common.ts (2)

115-116: LGTM! Simplified srcDir resolver.

The removal of compatibility version checks correctly simplifies the resolver logic whilst maintaining the intended functionality.


156-157: LGTM! Simplified serverDir resolver.

The resolver is now appropriately synchronous and assumes v4 behaviour consistently.

Copy link

codspeed-hq bot commented Jun 1, 2025

CodSpeed Performance Report

Merging #32255 will not alter performance

Comparing fix/remove-compat (8d05f20) with main (8ec609c)

Summary

✅ 10 untouched benchmarks

@danielroe danielroe merged commit 3c5e043 into main Jun 1, 2025
46 of 47 checks passed
@danielroe danielroe deleted the fix/remove-compat branch June 1, 2025 22:30
@github-actions github-actions bot mentioned this pull request Jun 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant