From 6a2251b8f52b0d663607c8c74d3f556dda1e09bd Mon Sep 17 00:00:00 2001 From: MK Date: Tue, 31 Mar 2026 20:01:52 +0800 Subject: [PATCH 1/4] fix(migration): pin @oxlint/migrate to bundled oxlint version Prevent version drift between @oxlint/migrate and the oxlint binary shipped with vite-plus. Without this, `vp migrate` fetches the latest @oxlint/migrate from npm, which may reference rules not yet supported by the bundled oxlint, causing `vp lint` errors after migration. --- packages/cli/src/migration/migrator.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/cli/src/migration/migrator.ts b/packages/cli/src/migration/migrator.ts index 74d5c40595..c599e1b190 100644 --- a/packages/cli/src/migration/migrator.ts +++ b/packages/cli/src/migration/migrator.ts @@ -1,4 +1,5 @@ import fs from 'node:fs'; +import { createRequire } from 'node:module'; import path from 'node:path'; import * as prompts from '@voidzero-dev/vite-plus-prompts'; @@ -233,7 +234,12 @@ export async function migrateEslintToOxlint( // Steps 1-2: Only run @oxlint/migrate if there's an eslint config at root if (eslintConfigFile) { - const migratePackage = '@oxlint/migrate'; + // Pin @oxlint/migrate to the bundled oxlint version. + // Uses createRequire to bypass the exports field (oxlint doesn't export ./package.json yet). + const { version: oxlintVersion }: { version: string } = createRequire(import.meta.url)( + 'oxlint/package.json', + ); + const migratePackage = `@oxlint/migrate@${oxlintVersion}`; // Step 1: Generate .oxlintrc.json from ESLint config spinner.start('Migrating ESLint config to Oxlint...'); From a3fe348f98b56ba0c428cf845f05ccaf695d6de4 Mon Sep 17 00:00:00 2001 From: MK Date: Tue, 31 Mar 2026 20:10:45 +0800 Subject: [PATCH 2/4] fix(migration): pin @oxlint/migrate to bundled oxlint version Prevent version drift between @oxlint/migrate and the oxlint binary shipped with vite-plus. Without this, `vp migrate` fetches the latest @oxlint/migrate from npm, which may reference rules not yet supported by the bundled oxlint, causing `vp lint` errors after migration. Reads the oxlint version from dist/versions.js via dynamic import, externalized in rolldown so it resolves at runtime. --- packages/cli/rolldown.config.ts | 24 ++++++++++++++++-------- packages/cli/src/migration/migrator.ts | 8 ++------ packages/cli/src/versions.d.ts | 11 +++++++++++ 3 files changed, 29 insertions(+), 14 deletions(-) create mode 100644 packages/cli/src/versions.d.ts diff --git a/packages/cli/rolldown.config.ts b/packages/cli/rolldown.config.ts index 549daae60e..265ef651b5 100644 --- a/packages/cli/rolldown.config.ts +++ b/packages/cli/rolldown.config.ts @@ -30,20 +30,28 @@ export default defineConfig({ if (source === '../../binding/index.js' || source === '../binding/index.js') { return true; } + if (source === '../versions.js') { + return true; + } return false; }, plugins: [ { - name: 'fix-binding-path', - // Rewrite the binding import path for the output directory. - // Source files import from ../../binding/index.js (relative to src/*/). - // Output is in dist/global/, so the correct path is ../../binding/index.js (two dirs up). - // Rolldown normalizes it to ../binding/index.js which is wrong. + name: 'fix-external-paths', + // Rewrite external import paths for the output directory (dist/global/). + // Rolldown normalizes relative paths from source locations, but the output + // is two directories deep (dist/global/), so the paths need adjustment. renderChunk(code) { - if (code.includes('../binding/index.js')) { - return { code: code.replaceAll('../binding/index.js', '../../binding/index.js') }; + let result = code; + // ../../binding/index.js → Rolldown normalizes to ../binding/index.js, needs ../../ + if (result.includes('../binding/index.js')) { + result = result.replaceAll('../binding/index.js', '../../binding/index.js'); } - return null; + // ../versions.js → Rolldown normalizes to ./versions.js, needs ../ + if (result.includes('./versions.js')) { + result = result.replaceAll('./versions.js', '../versions.js'); + } + return result !== code ? { code: result } : null; }, }, { diff --git a/packages/cli/src/migration/migrator.ts b/packages/cli/src/migration/migrator.ts index c599e1b190..d10afaa20f 100644 --- a/packages/cli/src/migration/migrator.ts +++ b/packages/cli/src/migration/migrator.ts @@ -1,5 +1,4 @@ import fs from 'node:fs'; -import { createRequire } from 'node:module'; import path from 'node:path'; import * as prompts from '@voidzero-dev/vite-plus-prompts'; @@ -235,11 +234,8 @@ export async function migrateEslintToOxlint( // Steps 1-2: Only run @oxlint/migrate if there's an eslint config at root if (eslintConfigFile) { // Pin @oxlint/migrate to the bundled oxlint version. - // Uses createRequire to bypass the exports field (oxlint doesn't export ./package.json yet). - const { version: oxlintVersion }: { version: string } = createRequire(import.meta.url)( - 'oxlint/package.json', - ); - const migratePackage = `@oxlint/migrate@${oxlintVersion}`; + const { versions } = await import('../versions.js'); + const migratePackage = `@oxlint/migrate@${versions.oxlint}`; // Step 1: Generate .oxlintrc.json from ESLint config spinner.start('Migrating ESLint config to Oxlint...'); diff --git a/packages/cli/src/versions.d.ts b/packages/cli/src/versions.d.ts new file mode 100644 index 0000000000..0646e854a4 --- /dev/null +++ b/packages/cli/src/versions.d.ts @@ -0,0 +1,11 @@ +// Type declaration for dist/versions.js (generated by build.ts syncVersionsExport). +// The actual module is resolved at runtime from dist/global/ → dist/versions.js. +export declare const versions: { + readonly vite: string; + readonly rolldown: string; + readonly tsdown: string; + readonly vitest: string; + readonly oxlint: string; + readonly oxfmt: string; + readonly 'oxlint-tsgolint': string; +}; From a568f8077d3225c090b2f3543827ad535c4fdb8b Mon Sep 17 00:00:00 2001 From: MK Date: Tue, 31 Mar 2026 20:11:25 +0800 Subject: [PATCH 3/4] fix(migration): use ts-ignore instead of type declaration for versions import --- packages/cli/src/migration/migrator.ts | 1 + packages/cli/src/versions.d.ts | 11 ----------- 2 files changed, 1 insertion(+), 11 deletions(-) delete mode 100644 packages/cli/src/versions.d.ts diff --git a/packages/cli/src/migration/migrator.ts b/packages/cli/src/migration/migrator.ts index d10afaa20f..9939c87ebc 100644 --- a/packages/cli/src/migration/migrator.ts +++ b/packages/cli/src/migration/migrator.ts @@ -234,6 +234,7 @@ export async function migrateEslintToOxlint( // Steps 1-2: Only run @oxlint/migrate if there's an eslint config at root if (eslintConfigFile) { // Pin @oxlint/migrate to the bundled oxlint version. + // @ts-ignore — resolved at runtime from dist/global/ → dist/versions.js const { versions } = await import('../versions.js'); const migratePackage = `@oxlint/migrate@${versions.oxlint}`; diff --git a/packages/cli/src/versions.d.ts b/packages/cli/src/versions.d.ts deleted file mode 100644 index 0646e854a4..0000000000 --- a/packages/cli/src/versions.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -// Type declaration for dist/versions.js (generated by build.ts syncVersionsExport). -// The actual module is resolved at runtime from dist/global/ → dist/versions.js. -export declare const versions: { - readonly vite: string; - readonly rolldown: string; - readonly tsdown: string; - readonly vitest: string; - readonly oxlint: string; - readonly oxfmt: string; - readonly 'oxlint-tsgolint': string; -}; From bd87fe8d70c9f0978903a1bf7ea66d3de15833dd Mon Sep 17 00:00:00 2001 From: MK Date: Tue, 31 Mar 2026 20:14:27 +0800 Subject: [PATCH 4/4] refactor: use @ts-expect-error instead of @ts-ignore for versions import --- packages/cli/src/migration/migrator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/migration/migrator.ts b/packages/cli/src/migration/migrator.ts index 9939c87ebc..aa0fa0ea0c 100644 --- a/packages/cli/src/migration/migrator.ts +++ b/packages/cli/src/migration/migrator.ts @@ -234,7 +234,7 @@ export async function migrateEslintToOxlint( // Steps 1-2: Only run @oxlint/migrate if there's an eslint config at root if (eslintConfigFile) { // Pin @oxlint/migrate to the bundled oxlint version. - // @ts-ignore — resolved at runtime from dist/global/ → dist/versions.js + // @ts-expect-error — resolved at runtime from dist/global/ → dist/versions.js const { versions } = await import('../versions.js'); const migratePackage = `@oxlint/migrate@${versions.oxlint}`;