Skip to content

Commit a3fe348

Browse files
committed
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.
1 parent 6a2251b commit a3fe348

3 files changed

Lines changed: 29 additions & 14 deletions

File tree

packages/cli/rolldown.config.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,28 @@ export default defineConfig({
3030
if (source === '../../binding/index.js' || source === '../binding/index.js') {
3131
return true;
3232
}
33+
if (source === '../versions.js') {
34+
return true;
35+
}
3336
return false;
3437
},
3538
plugins: [
3639
{
37-
name: 'fix-binding-path',
38-
// Rewrite the binding import path for the output directory.
39-
// Source files import from ../../binding/index.js (relative to src/*/).
40-
// Output is in dist/global/, so the correct path is ../../binding/index.js (two dirs up).
41-
// Rolldown normalizes it to ../binding/index.js which is wrong.
40+
name: 'fix-external-paths',
41+
// Rewrite external import paths for the output directory (dist/global/).
42+
// Rolldown normalizes relative paths from source locations, but the output
43+
// is two directories deep (dist/global/), so the paths need adjustment.
4244
renderChunk(code) {
43-
if (code.includes('../binding/index.js')) {
44-
return { code: code.replaceAll('../binding/index.js', '../../binding/index.js') };
45+
let result = code;
46+
// ../../binding/index.js → Rolldown normalizes to ../binding/index.js, needs ../../
47+
if (result.includes('../binding/index.js')) {
48+
result = result.replaceAll('../binding/index.js', '../../binding/index.js');
4549
}
46-
return null;
50+
// ../versions.js → Rolldown normalizes to ./versions.js, needs ../
51+
if (result.includes('./versions.js')) {
52+
result = result.replaceAll('./versions.js', '../versions.js');
53+
}
54+
return result !== code ? { code: result } : null;
4755
},
4856
},
4957
{

packages/cli/src/migration/migrator.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import fs from 'node:fs';
2-
import { createRequire } from 'node:module';
32
import path from 'node:path';
43

54
import * as prompts from '@voidzero-dev/vite-plus-prompts';
@@ -235,11 +234,8 @@ export async function migrateEslintToOxlint(
235234
// Steps 1-2: Only run @oxlint/migrate if there's an eslint config at root
236235
if (eslintConfigFile) {
237236
// Pin @oxlint/migrate to the bundled oxlint version.
238-
// Uses createRequire to bypass the exports field (oxlint doesn't export ./package.json yet).
239-
const { version: oxlintVersion }: { version: string } = createRequire(import.meta.url)(
240-
'oxlint/package.json',
241-
);
242-
const migratePackage = `@oxlint/migrate@${oxlintVersion}`;
237+
const { versions } = await import('../versions.js');
238+
const migratePackage = `@oxlint/migrate@${versions.oxlint}`;
243239

244240
// Step 1: Generate .oxlintrc.json from ESLint config
245241
spinner.start('Migrating ESLint config to Oxlint...');

packages/cli/src/versions.d.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Type declaration for dist/versions.js (generated by build.ts syncVersionsExport).
2+
// The actual module is resolved at runtime from dist/global/ → dist/versions.js.
3+
export declare const versions: {
4+
readonly vite: string;
5+
readonly rolldown: string;
6+
readonly tsdown: string;
7+
readonly vitest: string;
8+
readonly oxlint: string;
9+
readonly oxfmt: string;
10+
readonly 'oxlint-tsgolint': string;
11+
};

0 commit comments

Comments
 (0)