diff --git a/package.json b/package.json index 9f3cdc60c..a56871dc3 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,6 @@ "eslint": "^8.57.0 || ^9.0.0" }, "dependencies": { - "@dual-bundle/import-meta-resolve": "^4.1.0", "@types/doctrine": "^0.0.9", "@typescript-eslint/scope-manager": "^8.1.0", "@typescript-eslint/utils": "^8.1.0", @@ -97,7 +96,7 @@ "@typescript-eslint/rule-tester": "^8.15.0", "@unts/patch-package": "^8.0.0", "cross-env": "^7.0.3", - "enhanced-resolve": "^5.16.0", + "enhanced-resolve": "^5.17.1", "escope": "^4.0.0", "eslint": "^9.15.0", "eslint-config-prettier": "^9.1.0", diff --git a/src/node-resolver.ts b/src/node-resolver.ts index eab0befcb..a02cfbad4 100644 --- a/src/node-resolver.ts +++ b/src/node-resolver.ts @@ -1,14 +1,16 @@ -import type { NewResolver } from "./types"; - -import { fileURLToPath, pathToFileURL } from "url"; -import fs from "fs"; -import { createRequire } from "module"; - -import type { ErrnoException, moduleResolve as $moduleResolve } from '@dual-bundle/import-meta-resolve' with { "resolution-mode": "import" }; -const importMetaResolveExports = require('@dual-bundle/import-meta-resolve'); -const moduleResolve = importMetaResolveExports.moduleResolve as typeof $moduleResolve; +import { ResolverFactory, CachedInputFileSystem } from 'enhanced-resolve'; +import fs from 'node:fs'; +import type { NewResolver } from './types'; +import { isBuiltin } from 'node:module'; +import { dirname } from 'node:path'; interface NodeResolverOptions { + /** + * The allowed extensions the resolver will attempt to find when resolving a module + * @type {string[] | undefined} + * @default ['.mjs', '.cjs', '.js', '.json', '.node'] + */ + extensions?: string[]; /** * The import conditions the resolver will used when reading the exports map from "package.json" * @type {Set | undefined} @@ -23,72 +25,45 @@ interface NodeResolverOptions { preserveSymlinks?: boolean; } -const assertErrNoException = (error: unknown): error is ErrnoException => { - return ( - typeof error === 'object' && - error !== null && - 'code' in error && - typeof error.code === 'string' - ); -} - export function createNodeResolver({ + extensions = ['.mjs', '.cjs', '.js', '.json', '.node'], conditions = new Set(['default', 'module', 'import', 'require']), preserveSymlinks = false, }: NodeResolverOptions = {}): NewResolver { + const resolver = ResolverFactory.createResolver({ + fileSystem: new CachedInputFileSystem(fs, 4 * 1000), + extensions, + conditionNames: Array.from(conditions), + symlinks: !preserveSymlinks, + useSyncFileSystemCalls: true + }); + + // shared context across all resolve calls + return { interfaceVersion: 3, name: 'eslint-plugin-import-x built-in node resolver', resolve: (modulePath, sourceFile) => { + if (isBuiltin(modulePath)) { + return { found: true, path: null }; + } + + if (modulePath.startsWith('data:')) { + return { found: true, path: null }; + } + try { - const found = moduleResolve( - modulePath, - pathToFileURL(sourceFile), - conditions, - preserveSymlinks + const path = resolver.resolveSync( + {}, + dirname(sourceFile), + modulePath ); - - if (found.protocol === 'file:') { - if (fs.existsSync(found)) { - return { - found: true, - path: fileURLToPath(found), - }; - } - } else if (found.protocol === 'node:' || found.protocol === 'data:') { - return { - found: true, - path: null - } - } - return { - found: false - } - } catch (error) { - if (assertErrNoException(error)) { - if (error.code === 'ERR_MODULE_NOT_FOUND') { - return { - found: false, - } - } - if (error.code === 'ERR_UNSUPPORTED_DIR_IMPORT') { - const $require = createRequire(sourceFile); - try { - const resolved = $require.resolve(modulePath); - return { - found: true, - path: resolved, - } - } catch { - return { - found: false, - } - } - } - } - return { - found: false, + if (path) { + return { found: true, path }; } + return { found: false }; + } catch { + return { found: false }; } } } diff --git a/yarn.lock b/yarn.lock index 3d7229297..258fe8628 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1375,11 +1375,6 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@dual-bundle/import-meta-resolve@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz#519c1549b0e147759e7825701ecffd25e5819f7b" - integrity sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg== - "@emnapi/core@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.1.0.tgz#6b552ea3d2b303965c52661c05976d3072ccb6a3" @@ -3418,7 +3413,7 @@ enhanced-resolve@^0.9.1: memory-fs "^0.2.0" tapable "^0.1.8" -enhanced-resolve@^5.12.0, enhanced-resolve@^5.16.0: +enhanced-resolve@^5.12.0: version "5.16.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz#65ec88778083056cb32487faa9aef82ed0864787" integrity sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA== @@ -3426,6 +3421,14 @@ enhanced-resolve@^5.12.0, enhanced-resolve@^5.16.0: graceful-fs "^4.2.4" tapable "^2.2.0" +enhanced-resolve@^5.17.1: + version "5.17.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" + integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + enquirer@^2.3.0: version "2.4.1" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56"