diff --git a/lib/internal/Parser.js b/lib/internal/Parser.js index 41ad0e9..8111186 100644 --- a/lib/internal/Parser.js +++ b/lib/internal/Parser.js @@ -1,11 +1,11 @@ "use strict"; -const fs = require("fs"); -const assert = require("assert"); -const path = require("path"); -const Dependency = require("./Dependency"); -const resolveModule = require("../utils/resolveModule"); -const memoize = require("../utils/memoize"); +const fs = require("node:fs"); +const assert = require("node:assert"); +const path = require("node:path"); +const Dependency = require("./Dependency.js"); +const resolveModule = require("../utils/resolveModule.js"); +const memoize = require("../utils/memoize.js"); class Parser { /** @readonly */ @@ -29,7 +29,7 @@ class Parser { return ast.program.body; }); /** - * @type {(input: [id: string, basedir?: string]) => string} + * @type {(input: [id: string, directory?: string]) => string} * @readonly */ #resolveModule = memoize(([id, basedir]) => resolveModule(id, basedir), { diff --git a/lib/internal/Transformer.js b/lib/internal/Transformer.js index 4e9c17a..98c1f1e 100644 --- a/lib/internal/Transformer.js +++ b/lib/internal/Transformer.js @@ -1,6 +1,6 @@ "use strict"; -const memoize = require("../utils/memoize"); +const memoize = require("../utils/memoize.js"); /** * @param {string} localName diff --git a/lib/plugin.js b/lib/plugin.js index 72aa1de..d90a3a3 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -1,9 +1,9 @@ "use strict"; -const Transformer = require("./internal/Transformer"); -const parseOptions = require("./utils/parseOptions"); -const Parser = require("./internal/Parser"); -const memoize = require("./utils/memoize"); +const Transformer = require("./internal/Transformer.js"); +const parseOptions = require("./utils/parseOptions.js"); +const Parser = require("./internal/Parser.js"); +const memoize = require("./utils/memoize.js"); /** * @typedef {object} BabelAPI diff --git a/lib/utils/parseOptions.js b/lib/utils/parseOptions.js index f6429c2..bd69f4e 100644 --- a/lib/utils/parseOptions.js +++ b/lib/utils/parseOptions.js @@ -1,6 +1,6 @@ "use strict"; -const assert = require("assert"); +const assert = require("node:assert"); /** * @param {object} options diff --git a/lib/utils/resolveModule.js b/lib/utils/resolveModule.js index 645f414..20fb84b 100644 --- a/lib/utils/resolveModule.js +++ b/lib/utils/resolveModule.js @@ -1,31 +1,24 @@ "use strict"; -const resolve = require("resolve"); +const fs = require("node:fs"); +const { CachedInputFileSystem, ResolverFactory } = require("enhanced-resolve"); -const MAIN_FIELDS = ["module", "esnext", "jsnext:main"]; - -/** - * @param {resolve.PackageJSON} pkg - * @returns {resolve.PackageJSON} - */ -function packageFilter(pkg) { - for (const key of MAIN_FIELDS) { - /* istanbul ignore else */ - const main = pkg[key]; - /* istanbul ignore else */ - if (typeof main === "string" && main) { - return { ...pkg, main }; - } - } - /* istanbul ignore next */ - return pkg; -} +const resolver = ResolverFactory.createResolver({ + useSyncFileSystemCalls: true, + extensions: [".mjs", ".js", ".json"], + mainFields: ["module", "esnext", "jsnext:main"], + fileSystem: new CachedInputFileSystem(fs, 4_000), +}); /** * @param {string} id - * @param {string} [basedir] + * @param {string} [directory] * @returns {string} */ -module.exports = function resolveModule(id, basedir) { - return resolve.sync(id, { basedir, packageFilter }); +module.exports = function resolveModule(id, directory = __dirname) { + const result = resolver.resolveSync({}, directory, id); + if (!result) { + throw new Error(`Can't resolve '${id}' in '${directory}'`); + } + return result; }; diff --git a/lib/utils/resolveModule.spec.js b/lib/utils/resolveModule.spec.js index aa0e6e5..5a5717c 100644 --- a/lib/utils/resolveModule.spec.js +++ b/lib/utils/resolveModule.spec.js @@ -7,19 +7,18 @@ test("basic", () => { expect(resolveModule("@mui/material")).toMatchInlineSnapshot( `"/node_modules/@mui/material/index.js"` ); +}); + +test("deep module", () => { expect(resolveModule("@mui/material/Button")).toMatchInlineSnapshot( `"/node_modules/@mui/material/Button/index.js"` ); +}); + +test("invalid module", () => { expect(() => resolveModule("@mui/core/Button") ).toThrowErrorMatchingInlineSnapshot( - `"Cannot find module '@mui/core/Button' from '/lib/utils'"` + `"Can't resolve '@mui/core/Button' in '/lib/utils'"` ); - - expect(() => - resolveModule( - // @ts-expect-error - null - ) - ).toThrowErrorMatchingInlineSnapshot(`"Path must be a string."`); }); diff --git a/package-lock.json b/package-lock.json index d88594c..f534369 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "resolve": "^1.22.1" + "enhanced-resolve": "^5.12.0" }, "devDependencies": { "@babel/core": "7.21.0", @@ -25,7 +25,6 @@ "@mui/system": "5.11.11", "@types/babel__core": "7.20.0", "@types/node": "18.14.4", - "@types/resolve": "1.20.2", "@umidbekk/configs": "0.2.0", "@vitest/coverage-c8": "^0.29.2", "eslint": "8.35.0", @@ -1709,12 +1708,6 @@ "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", "dev": true }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true - }, "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", @@ -2452,6 +2445,18 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/enhanced-resolve": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/esbuild": { "version": "0.16.17", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", @@ -3018,7 +3023,8 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "node_modules/gensync": { "version": "1.0.0-beta.2", @@ -3152,6 +3158,11 @@ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", "dev": true }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, "node_modules/grapheme-splitter": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", @@ -3162,6 +3173,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -3283,6 +3295,7 @@ "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, "dependencies": { "has": "^1.0.3" }, @@ -4837,7 +4850,8 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-type": { "version": "4.0.0", @@ -5141,6 +5155,7 @@ "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, "dependencies": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", @@ -5523,6 +5538,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -5546,6 +5562,14 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -7191,12 +7215,6 @@ "@types/react": "*" } }, - "@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", - "dev": true - }, "@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", @@ -7758,6 +7776,15 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "enhanced-resolve": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, "esbuild": { "version": "0.16.17", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", @@ -8173,7 +8200,8 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "gensync": { "version": "1.0.0-beta.2", @@ -8267,6 +8295,11 @@ "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", "dev": true }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, "grapheme-splitter": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", @@ -8277,6 +8310,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -8370,6 +8404,7 @@ "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, "requires": { "has": "^1.0.3" } @@ -9418,7 +9453,8 @@ "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "path-type": { "version": "4.0.0", @@ -9618,6 +9654,7 @@ "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, "requires": { "is-core-module": "^2.9.0", "path-parse": "^1.0.7", @@ -9887,7 +9924,8 @@ "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true }, "synckit": { "version": "0.8.5", @@ -9899,6 +9937,11 @@ "tslib": "^2.5.0" } }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", diff --git a/package.json b/package.json index 9e4d7f8..718bcc2 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ ] }, "dependencies": { - "resolve": "^1.22.1" + "enhanced-resolve": "^5.12.0" }, "devDependencies": { "@babel/core": "7.21.0", @@ -82,7 +82,6 @@ "@mui/system": "5.11.11", "@types/babel__core": "7.20.0", "@types/node": "18.14.4", - "@types/resolve": "1.20.2", "@umidbekk/configs": "0.2.0", "@vitest/coverage-c8": "^0.29.2", "eslint": "8.35.0",