From 2a06ff23dc5544b9db27cafda527358b8bda01eb Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 3 Dec 2024 15:43:36 +0800 Subject: [PATCH 1/4] feat: implement interface version 3 --- src/index.ts | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index d7425a2..73bb2cb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,18 +6,23 @@ import { normalizeOptions } from './normalizeOptions' import { hashObject } from './utils' let cacheOptionsHash: string | undefined -let resolver: ResolverFactory | undefined -export function resolve(source: string, file: string, options?: NapiResolveOptions | null): { found: boolean, path: string | null | undefined } { +let cachedResolver: ResolverFactory | undefined + +export function resolve(source: string, file: string, options?: NapiResolveOptions | null, resolver: ResolverFactory | null = null): { found: boolean, path: string | null | undefined } { if (isBuiltin(source)) return { found: true, path: null } - options ??= {} - const optionsHash = hashObject(options) + if (resolver == null) { + options ??= {} + const optionsHash = hashObject(options) + + if (!cachedResolver || cacheOptionsHash !== optionsHash) { + options = normalizeOptions(options) + cachedResolver = new ResolverFactory(options) + cacheOptionsHash = optionsHash + } - if (!resolver || cacheOptionsHash !== optionsHash) { - options = normalizeOptions(options) - resolver = new ResolverFactory(options) - cacheOptionsHash = optionsHash + resolver = cachedResolver } // https://github.com/oxc-project/oxc-resolver/blob/main/npm/README.md#api @@ -30,3 +35,15 @@ export function resolve(source: string, file: string, options?: NapiResolveOptio } export const interfaceVersion = 2 + +export function createOxcResolver(options?: NapiResolveOptions | null) { + const resolver = new ResolverFactory(options) + + return { + interfaceVersion: 3, + name: 'eslint-import-resolver-oxc', + resolve(source: string, file: string) { + return resolve(source, file, null, resolver) + }, + } +} From 9701c1fcea2ee493309e6032ea79c2718fda56f1 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 3 Dec 2024 15:56:37 +0800 Subject: [PATCH 2/4] test: fix tests w/ eslint-plugin-import-x@4.5.0 --- pnpm-lock.yaml | 21 +++++++++++---------- tests/eslint-plugin/rules/no-cycle.test.ts | 3 ++- tests/eslint-plugin/utils.ts | 11 ++++++----- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30d61dc..2482a79 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: version: 2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6)) eslint-plugin-import-x: specifier: '*' - version: 4.4.3(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) + version: 4.5.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) oxc-resolver: specifier: ^2.1.1 version: 2.1.1 @@ -23,7 +23,7 @@ importers: version: 22.10.1 '@vida0905/eslint-config': specifier: ^1.1.1 - version: 1.1.1(@typescript-eslint/utils@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(@vue/compiler-sfc@3.5.13)(eslint-plugin-import-x@4.4.3(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6)))(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2)(vitest@2.1.6(@types/node@22.10.1)(jiti@1.21.6)(yaml@2.6.1)) + version: 1.1.1(@typescript-eslint/utils@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(@vue/compiler-sfc@3.5.13)(eslint-plugin-import-x@4.5.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6)))(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2)(vitest@2.1.6(@types/node@22.10.1)(jiti@1.21.6)(yaml@2.6.1)) bumpp: specifier: ^9.8.1 version: 9.8.1 @@ -1212,8 +1212,8 @@ packages: peerDependencies: eslint: '>=8' - eslint-plugin-import-x@4.4.3: - resolution: {integrity: sha512-QBprHvhLsfDhP++2T1NnjsOUt6bLDX3NMHaYwAB1FD3xmYTkdFH+HS1OamGhz28jLkRyIZa6UNAzTxbHnJwz5w==} + eslint-plugin-import-x@4.5.0: + resolution: {integrity: sha512-l0OTfnPF8RwmSXfjT75N8d6ZYLVrVYWpaGlgvVkVqFERCI5SyBfDP7QEMr3kt0zWi2sOa9EQ47clbdFsHkF83Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2845,7 +2845,7 @@ snapshots: eslint-merge-processors: 0.1.0(eslint@9.16.0(jiti@1.21.6)) eslint-plugin-antfu: 2.7.0(eslint@9.16.0(jiti@1.21.6)) eslint-plugin-command: 0.2.6(eslint@9.16.0(jiti@1.21.6)) - eslint-plugin-import-x: 4.4.3(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) + eslint-plugin-import-x: 4.5.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) eslint-plugin-jsdoc: 50.6.0(eslint@9.16.0(jiti@1.21.6)) eslint-plugin-jsonc: 2.18.2(eslint@9.16.0(jiti@1.21.6)) eslint-plugin-n: 17.14.0(eslint@9.16.0(jiti@1.21.6)) @@ -3359,11 +3359,11 @@ snapshots: '@typescript-eslint/types': 8.16.0 eslint-visitor-keys: 4.2.0 - '@vida0905/eslint-config@1.1.1(@typescript-eslint/utils@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(@vue/compiler-sfc@3.5.13)(eslint-plugin-import-x@4.4.3(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6)))(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2)(vitest@2.1.6(@types/node@22.10.1)(jiti@1.21.6)(yaml@2.6.1))': + '@vida0905/eslint-config@1.1.1(@typescript-eslint/utils@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(@vue/compiler-sfc@3.5.13)(eslint-plugin-import-x@4.5.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6)))(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2)(vitest@2.1.6(@types/node@22.10.1)(jiti@1.21.6)(yaml@2.6.1))': dependencies: '@antfu/eslint-config': 3.11.2(@typescript-eslint/utils@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(@vue/compiler-sfc@3.5.13)(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2)(vitest@2.1.6(@types/node@22.10.1)(jiti@1.21.6)(yaml@2.6.1)) eslint: 9.16.0(jiti@1.21.6) - eslint-import-resolver-oxc: 0.5.0(eslint-plugin-import-x@4.4.3(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6)))(eslint@9.16.0(jiti@1.21.6)) + eslint-import-resolver-oxc: 0.5.0(eslint-plugin-import-x@4.5.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6)))(eslint@9.16.0(jiti@1.21.6)) eslint-plugin-pinia: 0.4.1(@typescript-eslint/utils@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6)) local-pkg: 0.5.1 transitivePeerDependencies: @@ -3964,13 +3964,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-oxc@0.5.0(eslint-plugin-import-x@4.4.3(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6)))(eslint@9.16.0(jiti@1.21.6)): + eslint-import-resolver-oxc@0.5.0(eslint-plugin-import-x@4.5.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6)))(eslint@9.16.0(jiti@1.21.6)): dependencies: eslint: 9.16.0(jiti@1.21.6) oxc-resolver: 2.1.1 optionalDependencies: eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2))(eslint@9.16.0(jiti@1.21.6)) - eslint-plugin-import-x: 4.4.3(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) + eslint-plugin-import-x: 4.5.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) eslint-json-compat-utils@0.2.1(eslint@9.16.0(jiti@1.21.6))(jsonc-eslint-parser@2.4.0): dependencies: @@ -4009,8 +4009,9 @@ snapshots: eslint: 9.16.0(jiti@1.21.6) eslint-compat-utils: 0.5.1(eslint@9.16.0(jiti@1.21.6)) - eslint-plugin-import-x@4.4.3(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2): + eslint-plugin-import-x@4.5.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2): dependencies: + '@typescript-eslint/scope-manager': 8.16.0 '@typescript-eslint/utils': 8.16.0(eslint@9.16.0(jiti@1.21.6))(typescript@5.7.2) debug: 4.3.7 doctrine: 3.0.0 diff --git a/tests/eslint-plugin/rules/no-cycle.test.ts b/tests/eslint-plugin/rules/no-cycle.test.ts index a7d20a6..6f7aa1e 100644 --- a/tests/eslint-plugin/rules/no-cycle.test.ts +++ b/tests/eslint-plugin/rules/no-cycle.test.ts @@ -2,7 +2,8 @@ import { run } from '../utils' function createCycleSourceError(p: string) { return { - message: `Dependency cycle via ${p}`, + messageId: 'cycleSource', + data: { source: p }, } } diff --git a/tests/eslint-plugin/utils.ts b/tests/eslint-plugin/utils.ts index 5092e8c..b81b953 100644 --- a/tests/eslint-plugin/utils.ts +++ b/tests/eslint-plugin/utils.ts @@ -1,11 +1,12 @@ import type { RuleTesterInitOptions, TestCasesOptions } from 'eslint-vitest-rule-tester' -import type { NapiResolveOptions } from 'oxc-resolver' import path from 'node:path' import { cwd } from 'node:process' import tsParser from '@typescript-eslint/parser' import { rules } from 'eslint-plugin-import-x' import { run as _run } from 'eslint-vitest-rule-tester' +import { createOxcResolver } from '../../src' + export * from 'eslint-vitest-rule-tester' export { unindent as $ } from 'eslint-vitest-rule-tester' @@ -35,15 +36,15 @@ export function run(options: ExtendedRuleTesterOptions) { configs: { settings: { ...(options.lang === 'js' ? {} : { 'import-x/parsers': { [require.resolve('@typescript-eslint/parser')]: ['.ts'] } }), - 'import-x/resolver': { - [oxcResolver]: { + 'import-x/resolver-next': [ + createOxcResolver({ tsconfig: { configFile: path.resolve(FIXTURES_PATH, 'tsconfig.json'), references: 'auto', }, roots: [FIXTURES_PATH], - } satisfies NapiResolveOptions, - }, + }), + ], }, }, ...(options.lang === 'js' ? {} : { parser: tsParser as any }), From 866e1ec6f885b552a11d3b687389650c96a72101 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Tue, 3 Dec 2024 16:44:22 +0800 Subject: [PATCH 3/4] refactor: rename v3 interface factory function --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 73bb2cb..ab34a83 100644 --- a/src/index.ts +++ b/src/index.ts @@ -36,7 +36,7 @@ export function resolve(source: string, file: string, options?: NapiResolveOptio export const interfaceVersion = 2 -export function createOxcResolver(options?: NapiResolveOptions | null) { +export function createOxcImportResolver(options?: NapiResolveOptions | null) { const resolver = new ResolverFactory(options) return { From 1a51670cf9781c12154c7892b59a48e5f1f66f4d Mon Sep 17 00:00:00 2001 From: Vida Xie <38204901+9romise@users.noreply.github.com> Date: Tue, 3 Dec 2024 22:44:58 +0800 Subject: [PATCH 4/4] chore: update --- src/index.ts | 8 ++++---- .../rules/no-extraneous-dependencies.test.ts | 19 +++++++++---------- .../rules/no-internal-modules.test.ts | 11 +++++------ tests/eslint-plugin/rules/order.test.ts | 11 +++++------ tests/eslint-plugin/utils.ts | 11 ++++------- 5 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/index.ts b/src/index.ts index ab34a83..d32b5b6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,7 +5,7 @@ import { ResolverFactory } from 'oxc-resolver' import { normalizeOptions } from './normalizeOptions' import { hashObject } from './utils' -let cacheOptionsHash: string | undefined +let cachedOptionsHash: string | undefined let cachedResolver: ResolverFactory | undefined export function resolve(source: string, file: string, options?: NapiResolveOptions | null, resolver: ResolverFactory | null = null): { found: boolean, path: string | null | undefined } { @@ -16,10 +16,10 @@ export function resolve(source: string, file: string, options?: NapiResolveOptio options ??= {} const optionsHash = hashObject(options) - if (!cachedResolver || cacheOptionsHash !== optionsHash) { + if (!cachedResolver || cachedOptionsHash !== optionsHash) { options = normalizeOptions(options) cachedResolver = new ResolverFactory(options) - cacheOptionsHash = optionsHash + cachedOptionsHash = optionsHash } resolver = cachedResolver @@ -37,7 +37,7 @@ export function resolve(source: string, file: string, options?: NapiResolveOptio export const interfaceVersion = 2 export function createOxcImportResolver(options?: NapiResolveOptions | null) { - const resolver = new ResolverFactory(options) + const resolver = new ResolverFactory(normalizeOptions(options)) return { interfaceVersion: 3, diff --git a/tests/eslint-plugin/rules/no-extraneous-dependencies.test.ts b/tests/eslint-plugin/rules/no-extraneous-dependencies.test.ts index c7d45b8..0102321 100644 --- a/tests/eslint-plugin/rules/no-extraneous-dependencies.test.ts +++ b/tests/eslint-plugin/rules/no-extraneous-dependencies.test.ts @@ -1,5 +1,4 @@ -import type { NapiResolveOptions } from 'oxc-resolver' -import { oxcResolver, run, testFilePath } from '../utils' +import { createOxcImportResolver, run, testFilePath } from '../utils' run({ rule: 'no-extraneous-dependencies', @@ -13,13 +12,13 @@ run({ { code: 'import "@custom-internal-alias/api/service";', settings: { - 'import-x/resolver': { - [oxcResolver]: { + 'import-x/resolver-next': [ + createOxcImportResolver({ alias: { '@custom-internal-alias': [testFilePath('internal-modules')], }, - } satisfies NapiResolveOptions, - }, + }), + ], }, }, ], @@ -27,13 +26,13 @@ run({ { code: 'import jest from "alias/jest";', settings: { - 'import-x/resolver': { - [oxcResolver]: { + 'import-x/resolver-next': [ + createOxcImportResolver({ alias: { 'alias/jest': ['jest'], }, - } satisfies NapiResolveOptions, - }, + }), + ], }, errors: [ // missing dependency is jest not alias diff --git a/tests/eslint-plugin/rules/no-internal-modules.test.ts b/tests/eslint-plugin/rules/no-internal-modules.test.ts index 3885d0f..f0e92ff 100644 --- a/tests/eslint-plugin/rules/no-internal-modules.test.ts +++ b/tests/eslint-plugin/rules/no-internal-modules.test.ts @@ -1,5 +1,4 @@ -import type { NapiResolveOptions } from 'oxc-resolver' -import { oxcResolver, run, testFilePath } from '../utils' +import { createOxcImportResolver, run, testFilePath } from '../utils' run({ rule: 'no-internal-modules', @@ -19,13 +18,13 @@ run({ }, ], settings: { - 'import-x/resolver': { - [oxcResolver]: { + 'import-x/resolver-next': [ + createOxcImportResolver({ alias: { '@': [testFilePath('internal-modules')], }, - } satisfies NapiResolveOptions, - }, + }), + ], }, }, ], diff --git a/tests/eslint-plugin/rules/order.test.ts b/tests/eslint-plugin/rules/order.test.ts index fc0926f..83083a0 100644 --- a/tests/eslint-plugin/rules/order.test.ts +++ b/tests/eslint-plugin/rules/order.test.ts @@ -1,5 +1,4 @@ -import type { NapiResolveOptions } from 'oxc-resolver' -import { oxcResolver, run, testFilePath } from '../utils' +import { createOxcImportResolver, run, testFilePath } from '../utils' run({ rule: 'order', @@ -54,13 +53,13 @@ run({ }, ], settings: { - 'import-x/resolver': { - [oxcResolver]: { + 'import-x/resolver-next': [ + createOxcImportResolver({ alias: { '@': [testFilePath('internal-modules')], }, - } satisfies NapiResolveOptions, - }, + }), + ], }, }, ], diff --git a/tests/eslint-plugin/utils.ts b/tests/eslint-plugin/utils.ts index b81b953..aa14e2a 100644 --- a/tests/eslint-plugin/utils.ts +++ b/tests/eslint-plugin/utils.ts @@ -1,14 +1,13 @@ import type { RuleTesterInitOptions, TestCasesOptions } from 'eslint-vitest-rule-tester' import path from 'node:path' -import { cwd } from 'node:process' import tsParser from '@typescript-eslint/parser' import { rules } from 'eslint-plugin-import-x' import { run as _run } from 'eslint-vitest-rule-tester' +import { createOxcImportResolver } from '../../src' -import { createOxcResolver } from '../../src' - -export * from 'eslint-vitest-rule-tester' +export { createOxcImportResolver } from '../../src' export { unindent as $ } from 'eslint-vitest-rule-tester' +export * from 'eslint-vitest-rule-tester' export interface ExtendedRuleTesterOptions extends RuleTesterInitOptions, TestCasesOptions { lang?: 'js' | 'ts' @@ -26,8 +25,6 @@ const defaultFilenames = { ts: 'tests/eslint-plugin/fixtures/foo.ts', } -export const oxcResolver = path.resolve(cwd(), 'dist/index.cjs') - export function run(options: ExtendedRuleTesterOptions) { return _run({ recursive: false, @@ -37,7 +34,7 @@ export function run(options: ExtendedRuleTesterOptions) { settings: { ...(options.lang === 'js' ? {} : { 'import-x/parsers': { [require.resolve('@typescript-eslint/parser')]: ['.ts'] } }), 'import-x/resolver-next': [ - createOxcResolver({ + createOxcImportResolver({ tsconfig: { configFile: path.resolve(FIXTURES_PATH, 'tsconfig.json'), references: 'auto',