From 40206ba4ab7b2e88212102d5422c0e0a1930062e Mon Sep 17 00:00:00 2001 From: thuggys <150315417+thuggys@users.noreply.github.com> Date: Thu, 15 Oct 2026 10:50:58 -0400 Subject: [PATCH] fix(migrate): keep vite/rolldown imports as they are --- crates/vp_migration/src/import_rewriter.rs | 39 +++++++++++++++++++++- docs/guide/migrate-rules.md | 2 ++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/crates/vp_migration/src/import_rewriter.rs b/crates/vp_migration/src/import_rewriter.rs index c02af5e2dd..f731e937a2 100644 --- a/crates/vp_migration/src/import_rewriter.rs +++ b/crates/vp_migration/src/import_rewriter.rs @@ -112,6 +112,8 @@ rule: pattern: $STR kind: string regex: ^['"]vite/.+['"]$ + not: + regex: ^['"]vite/rolldown(/.*)?['"]$ inside: kind: import_statement transform: @@ -128,6 +130,8 @@ rule: pattern: $STR kind: string regex: ^['"]vite/.+['"]$ + not: + regex: ^['"]vite/rolldown(/.*)?['"]$ inside: kind: export_statement transform: @@ -144,6 +148,8 @@ rule: pattern: $STR kind: string regex: ^['"]vite/.+['"]$ + not: + regex: ^['"]vite/rolldown(/.*)?['"]$ inside: kind: arguments inside: @@ -165,6 +171,8 @@ rule: pattern: $STR kind: string regex: ^['"]vite/.+['"]$ + not: + regex: ^['"]vite/rolldown(/.*)?['"]$ inside: kind: arguments inside: @@ -202,6 +210,8 @@ rule: pattern: $STR kind: string regex: ^['\"]vite/.+['\"]$ + not: + regex: ^['"]vite/rolldown(/.*)?['"]$ inside: kind: module transform: @@ -1738,6 +1748,11 @@ static RE_REF_VITE_SUBPATH: LazyLock = LazyLock::new(|| { Regex::new(r#"^(\s*///\s*)"#).unwrap() }); +/// `vite/rolldown[/...]` is not re-exported by `vite-plus`, so it stays untouched. +static RE_REF_VITE_ROLLDOWN: LazyLock = LazyLock::new(|| { + Regex::new(r#"^\s*///\s* = LazyLock::new(|| { Regex::new(r#"^(\s*///\s*)"#).unwrap() @@ -1986,7 +2001,9 @@ fn rewrite_reference_types( } } if !skip_packages.skip_vite { - if apply_regex_replace(line, &RE_REF_VITE_SUBPATH, "${1}vite-plus/${2}${3}") { + if !RE_REF_VITE_ROLLDOWN.is_match(line) + && apply_regex_replace(line, &RE_REF_VITE_SUBPATH, "${1}vite-plus/${2}${3}") + { changed = true; continue; } @@ -3305,6 +3322,26 @@ export default ModuleRunner;"# ); } + #[test] + fn test_rewrite_import_content_vite_rolldown_subpath_is_kept() { + let vite_config = r#"/// +import "vite/rolldown/plugins"; +import { viteAliasPlugin } from 'vite/rolldown/plugins'; +import 'vite/rolldown'; +export * from "vite/rolldown/utils"; +const a = require('vite/rolldown/plugins'); +const b = await import('vite/rolldown/plugins'); +declare module 'vite/rolldown/plugins' {} +import { ModuleRunner } from 'vite/module-runner';"#; + + let result = rewrite_import_content(vite_config, &SkipPackages::default()).unwrap(); + assert!(result.updated); + assert_eq!( + result.content, + vite_config.replace("'vite/module-runner'", "'vite-plus/module-runner'") + ); + } + #[test] fn test_rewrite_import_content_vite_subpath_double_quotes() { let vite_config = r#"import { ModuleRunner } from "vite/module-runner"; diff --git a/docs/guide/migrate-rules.md b/docs/guide/migrate-rules.md index 1a868d7202..a7cb01c342 100644 --- a/docs/guide/migrate-rules.md +++ b/docs/guide/migrate-rules.md @@ -185,6 +185,8 @@ Object-valued nested npm and Bun overrides are preserved: they are user-defined Plugin packages (an unscoped name starting with `vite-plugin-` or `unplugin-`, or `vite` in `peerDependencies`/`dependencies`) skip the rewrite even in config files. Only the `vite` specifier is in scope for this rule. +`vite/rolldown` and `vite/rolldown/*` are never rewritten, because `vite-plus` does not export those subpaths; they keep resolving through the core alias. + `declare module 'vite'` augmentations follow the same rule and are preserved outside config files. Through the core alias they reach the same `@voidzero-dev/vite-plus-core` module whose `UserConfig` types `defineConfig` from `vite-plus`, so they keep working after migration; `vite-plus` itself exports no `UserConfig` symbol, so a rewritten `declare module 'vite-plus'` augmentation would merge with nothing. Extensions aimed at `vite-plus`'s own surface are written against `vite-plus` by hand. ### `vitest` and Browser Imports