diff --git a/.changeset/silent-cows-drive.md b/.changeset/silent-cows-drive.md new file mode 100644 index 0000000..9d0a817 --- /dev/null +++ b/.changeset/silent-cows-drive.md @@ -0,0 +1,13 @@ +--- +"eslint-import-resolver-typescript": minor +--- + +feat: make `is-bun-module` as optional peer dependency + +Technically this is a BREAKING CHANGE, but considering we just raise out v4 recently and this only affects `bun` users, `bun --bun eslint` even works without this dependency, so I'd consider this as a minor change. + +So for `bun` users, there are three options: + +1. install `is-bun-module` dependency manually and use `bun: true` option +2. run `eslint` with `bun --bun eslint` w/o `bun: true` option +3. enable `run#bun` in [`bunfig.toml`](https://bun.sh/docs/runtime/bunfig#run-bun-auto-alias-node-to-bun) w/o `bun: true` option diff --git a/.size-limit.json b/.size-limit.json index c601a11..f8a0842 100644 --- a/.size-limit.json +++ b/.size-limit.json @@ -1,6 +1,6 @@ [ { "path": "./lib/index.js", - "limit": "1.6kB" + "limit": "1.5kB" } ] diff --git a/package.json b/package.json index 16df65b..5dd14c2 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,8 @@ "peerDependencies": { "eslint": "*", "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" + "eslint-plugin-import-x": "*", + "is-bun-module": "*" }, "peerDependenciesMeta": { "eslint-plugin-import": { @@ -73,12 +74,14 @@ }, "eslint-plugin-import-x": { "optional": true + }, + "is-bun-module": { + "optional": true } }, "dependencies": { "debug": "^4.4.0", "get-tsconfig": "^4.10.0", - "is-bun-module": "^1.3.0", "rspack-resolver": "^1.1.2", "stable-hash": "^0.0.5", "tinyglobby": "^0.2.12" @@ -100,6 +103,7 @@ "eslint": "^9.22.0", "eslint-import-resolver-typescript": "link:.", "eslint-plugin-import-x": "^4.8.0", + "is-bun-module": "^1.3.0", "lint-staged": "^15.5.0", "npm-run-all2": "^7.0.2", "prettier": "^3.5.3", diff --git a/src/helpers.ts b/src/helpers.ts index 4bc993e..cecfdd3 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -1,6 +1,9 @@ import fs from 'node:fs' +import { createRequire } from 'node:module' import path from 'node:path' +import type { IsBunModule } from './types.js' + /** * For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */ @@ -71,3 +74,17 @@ export const toGlobPath = (pathname: string) => pathname.replaceAll('\\', '/') export const toNativePath = (pathname: string) => '/' === path.sep ? pathname : pathname.replaceAll('/', '\\') + +let isBunModule: IsBunModule | undefined + +const _filename = typeof __filename === 'string' ? __filename : import.meta.url + +const DEFAULT_BUN_VERSION = 'latest' + +export const isBunBuiltin = (source: string) => { + isBunModule ??= createRequire(_filename)('is-bun-module') + return ( + isBunModule!.isBunModule(source, DEFAULT_BUN_VERSION) || + isBunModule!.isSupportedNodeModule(source, DEFAULT_BUN_VERSION) + ) +} diff --git a/src/index.ts b/src/index.ts index f200b6c..a946a0d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,12 +8,12 @@ import { createFilesMatcher, parseTsconfig, } from 'get-tsconfig' -import { type Version, isBunModule, isSupportedNodeModule } from 'is-bun-module' import { ResolverFactory } from 'rspack-resolver' import { stableHash } from 'stable-hash' import { IMPORT_RESOLVER_NAME, JS_EXT_PATTERN } from './constants.js' import { + isBunBuiltin, mangleScopedPackage, removeQuerystring, sortProjectsByAffinity, @@ -62,22 +62,9 @@ export const resolve = ( ): ResolvedResult => { options ||= {} - let bunVersion = process.versions.bun as Version | undefined - - // don't worry about bun core modules - if (bunVersion || options.bun) { - if ( - bunVersion - ? module.isBuiltin(source) - : isBunModule(source, (bunVersion = 'latest')) || - isSupportedNodeModule(source, bunVersion) - ) { - log('matched bun core:', source) - return { found: true, path: null } - } - } else if (module.isBuiltin(source)) { - // don't worry about node core modules - log('matched node core:', source) + // don't worry about node/bun core modules + if (module.isBuiltin(source) || (options.bun && isBunBuiltin(source))) { + log('matched core:', source) return { found: true, path: null } } @@ -105,8 +92,6 @@ export const resolve = ( resolver = cached } - options ||= {} - // eslint-disable-next-line sonarjs/label-position, sonarjs/no-labels createResolver: if (!resolver) { // must be a array with 2+ items here already ensured by `normalizeOptions` diff --git a/src/types.ts b/src/types.ts index 8f255a2..7f5c3e7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -12,3 +12,5 @@ export interface TypeScriptResolverOptions extends NapiResolveOptions { bun?: boolean noWarnOnMultipleProjects?: boolean } + +export type IsBunModule = typeof import('is-bun-module') diff --git a/yarn.lock b/yarn.lock index 465cfd7..d64142b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6715,11 +6715,14 @@ __metadata: eslint: "*" eslint-plugin-import: "*" eslint-plugin-import-x: "*" + is-bun-module: "*" peerDependenciesMeta: eslint-plugin-import: optional: true eslint-plugin-import-x: optional: true + is-bun-module: + optional: true languageName: unknown linkType: soft