diff --git a/package.json b/package.json index d98800e5..55e016be 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "postcss-value-parser": "^4.2.0", "query-string": "^7.1.0", "resolve": "^1.21.0", + "resolve.exports": "^1.1.0", "source-map-js": "^1.0.1", "tslib": "^2.3.1" }, @@ -94,7 +95,7 @@ "@typescript-eslint/parser": "^5.9.1", "autoprefixer": "^10.4.2", "babel-jest": "^27.4.6", - "eslint": "^8.6.0", + "eslint": "^8.7.0", "eslint-config-prettier": "^8.3.0", "eslint-import-resolver-node": "^0.3.6", "eslint-plugin-import": "^2.25.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6b889a70..3454ed27 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,7 +29,7 @@ specifiers: babel-jest: ^27.4.6 cosmiconfig: ^7.0.1 cssnano: ^5.0.15 - eslint: ^8.6.0 + eslint: ^8.7.0 eslint-config-prettier: ^8.3.0 eslint-import-resolver-node: ^0.3.6 eslint-plugin-import: ^2.25.4 @@ -57,6 +57,7 @@ specifiers: prettier: ^2.5.1 query-string: ^7.1.0 resolve: ^1.21.0 + resolve.exports: ^1.1.0 rollup: ^2.64.0 rollup-plugin-dts: ^4.1.0 rollup-plugin-lit-css: ^3.2.1 @@ -91,6 +92,7 @@ dependencies: postcss-value-parser: 4.2.0 query-string: 7.1.0 resolve: 1.21.0 + resolve.exports: 1.1.0 source-map-js: 1.0.1 tslib: 2.3.1 @@ -115,16 +117,16 @@ devDependencies: '@types/node': 17.0.8 '@types/resolve': 1.20.1 '@types/uglifycss': 0.0.7 - '@typescript-eslint/eslint-plugin': 5.9.1_b7b2e42b32ee097737cd3e626b10847b - '@typescript-eslint/parser': 5.9.1_eslint@8.6.0+typescript@4.5.4 + '@typescript-eslint/eslint-plugin': 5.9.1_bbe74534e31a8c21f1b3522447c55341 + '@typescript-eslint/parser': 5.9.1_eslint@8.7.0+typescript@4.5.4 autoprefixer: 10.4.2_postcss@8.4.5 babel-jest: 27.4.6_@babel+core@7.16.7 - eslint: 8.6.0 - eslint-config-prettier: 8.3.0_eslint@8.6.0 + eslint: 8.7.0 + eslint-config-prettier: 8.3.0_eslint@8.7.0 eslint-import-resolver-node: 0.3.6 - eslint-plugin-import: 2.25.4_eslint@8.6.0 - eslint-plugin-jest: 25.7.0_296d48ab5a8c24dcd54e3205c98c34b8 - eslint-plugin-unicorn: 40.0.0_eslint@8.6.0 + eslint-plugin-import: 2.25.4_eslint@8.7.0 + eslint-plugin-jest: 25.7.0_36547e7e56cb5984c70866e6ceec1df2 + eslint-plugin-unicorn: 40.0.0_eslint@8.7.0 gh-pages: 3.2.3 husky: 7.0.4 is-ci: 3.0.1 @@ -2314,7 +2316,7 @@ packages: '@types/yargs-parser': 20.2.1 dev: true - /@typescript-eslint/eslint-plugin/5.9.1_b7b2e42b32ee097737cd3e626b10847b: + /@typescript-eslint/eslint-plugin/5.9.1_bbe74534e31a8c21f1b3522447c55341: resolution: {integrity: sha512-Xv9tkFlyD4MQGpJgTo6wqDqGvHIRmRgah/2Sjz1PUnJTawjHWIwBivUE9x0QtU2WVii9baYgavo/bHjrZJkqTw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2325,12 +2327,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/experimental-utils': 5.9.1_eslint@8.6.0+typescript@4.5.4 - '@typescript-eslint/parser': 5.9.1_eslint@8.6.0+typescript@4.5.4 + '@typescript-eslint/experimental-utils': 5.9.1_eslint@8.7.0+typescript@4.5.4 + '@typescript-eslint/parser': 5.9.1_eslint@8.7.0+typescript@4.5.4 '@typescript-eslint/scope-manager': 5.9.1 - '@typescript-eslint/type-utils': 5.9.1_eslint@8.6.0+typescript@4.5.4 + '@typescript-eslint/type-utils': 5.9.1_eslint@8.7.0+typescript@4.5.4 debug: 4.3.3 - eslint: 8.6.0 + eslint: 8.7.0 functional-red-black-tree: 1.0.1 ignore: 5.2.0 regexpp: 3.2.0 @@ -2341,7 +2343,7 @@ packages: - supports-color dev: true - /@typescript-eslint/experimental-utils/5.9.1_eslint@8.6.0+typescript@4.5.4: + /@typescript-eslint/experimental-utils/5.9.1_eslint@8.7.0+typescript@4.5.4: resolution: {integrity: sha512-cb1Njyss0mLL9kLXgS/eEY53SZQ9sT519wpX3i+U457l2UXRDuo87hgKfgRazmu9/tQb0x2sr3Y0yrU+Zz0y+w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2351,15 +2353,15 @@ packages: '@typescript-eslint/scope-manager': 5.9.1 '@typescript-eslint/types': 5.9.1 '@typescript-eslint/typescript-estree': 5.9.1_typescript@4.5.4 - eslint: 8.6.0 + eslint: 8.7.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.6.0 + eslint-utils: 3.0.0_eslint@8.7.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/parser/5.9.1_eslint@8.6.0+typescript@4.5.4: + /@typescript-eslint/parser/5.9.1_eslint@8.7.0+typescript@4.5.4: resolution: {integrity: sha512-PLYO0AmwD6s6n0ZQB5kqPgfvh73p0+VqopQQLuNfi7Lm0EpfKyDalchpVwkE+81k5HeiRrTV/9w1aNHzjD7C4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2373,7 +2375,7 @@ packages: '@typescript-eslint/types': 5.9.1 '@typescript-eslint/typescript-estree': 5.9.1_typescript@4.5.4 debug: 4.3.3 - eslint: 8.6.0 + eslint: 8.7.0 typescript: 4.5.4 transitivePeerDependencies: - supports-color @@ -2387,7 +2389,7 @@ packages: '@typescript-eslint/visitor-keys': 5.9.1 dev: true - /@typescript-eslint/type-utils/5.9.1_eslint@8.6.0+typescript@4.5.4: + /@typescript-eslint/type-utils/5.9.1_eslint@8.7.0+typescript@4.5.4: resolution: {integrity: sha512-tRSpdBnPRssjlUh35rE9ug5HrUvaB9ntREy7gPXXKwmIx61TNN7+l5YKgi1hMKxo5NvqZCfYhA5FvyuJG6X6vg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2397,9 +2399,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/experimental-utils': 5.9.1_eslint@8.6.0+typescript@4.5.4 + '@typescript-eslint/experimental-utils': 5.9.1_eslint@8.7.0+typescript@4.5.4 debug: 4.3.3 - eslint: 8.6.0 + eslint: 8.7.0 tsutils: 3.21.0_typescript@4.5.4 typescript: 4.5.4 transitivePeerDependencies: @@ -2534,11 +2536,6 @@ packages: resolution: {integrity: sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=} dev: false - /ansi-colors/4.1.1: - resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} - engines: {node: '>=6'} - dev: true - /ansi-escapes/3.2.0: resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} engines: {node: '>=4'} @@ -3728,13 +3725,6 @@ packages: dev: true optional: true - /enquirer/2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} - engines: {node: '>=8.6'} - dependencies: - ansi-colors: 4.1.1 - dev: true - /entities/2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} dev: false @@ -3837,13 +3827,13 @@ packages: source-map: 0.6.1 dev: true - /eslint-config-prettier/8.3.0_eslint@8.6.0: + /eslint-config-prettier/8.3.0_eslint@8.7.0: resolution: {integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.6.0 + eslint: 8.7.0 dev: true /eslint-import-resolver-node/0.3.6: @@ -3861,7 +3851,7 @@ packages: find-up: 2.1.0 dev: true - /eslint-plugin-import/2.25.4_eslint@8.6.0: + /eslint-plugin-import/2.25.4_eslint@8.7.0: resolution: {integrity: sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==} engines: {node: '>=4'} peerDependencies: @@ -3871,7 +3861,7 @@ packages: array.prototype.flat: 1.2.5 debug: 2.6.9 doctrine: 2.1.0 - eslint: 8.6.0 + eslint: 8.7.0 eslint-import-resolver-node: 0.3.6 eslint-module-utils: 2.7.2 has: 1.0.3 @@ -3883,7 +3873,7 @@ packages: tsconfig-paths: 3.12.0 dev: true - /eslint-plugin-jest/25.7.0_296d48ab5a8c24dcd54e3205c98c34b8: + /eslint-plugin-jest/25.7.0_36547e7e56cb5984c70866e6ceec1df2: resolution: {integrity: sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} peerDependencies: @@ -3896,16 +3886,16 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 5.9.1_b7b2e42b32ee097737cd3e626b10847b - '@typescript-eslint/experimental-utils': 5.9.1_eslint@8.6.0+typescript@4.5.4 - eslint: 8.6.0 + '@typescript-eslint/eslint-plugin': 5.9.1_bbe74534e31a8c21f1b3522447c55341 + '@typescript-eslint/experimental-utils': 5.9.1_eslint@8.7.0+typescript@4.5.4 + eslint: 8.7.0 jest: 27.4.7 transitivePeerDependencies: - supports-color - typescript dev: true - /eslint-plugin-unicorn/40.0.0_eslint@8.6.0: + /eslint-plugin-unicorn/40.0.0_eslint@8.7.0: resolution: {integrity: sha512-5GRXISfBk8jMmYk1eeNDw8zSRnWTxBjWkzx2Prre6E2/yLu2twozZ3EomLWCBu9nWms/ZE361BItyMQwfnG1qA==} engines: {node: '>=12'} peerDependencies: @@ -3914,8 +3904,8 @@ packages: '@babel/helper-validator-identifier': 7.16.7 ci-info: 3.3.0 clean-regexp: 1.0.0 - eslint: 8.6.0 - eslint-utils: 3.0.0_eslint@8.6.0 + eslint: 8.7.0 + eslint-utils: 3.0.0_eslint@8.7.0 esquery: 1.4.0 indent-string: 4.0.0 is-builtin-module: 3.1.0 @@ -3944,13 +3934,13 @@ packages: estraverse: 5.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.6.0: + /eslint-utils/3.0.0_eslint@8.7.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.6.0 + eslint: 8.7.0 eslint-visitor-keys: 2.1.0 dev: true @@ -3964,8 +3954,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.6.0: - resolution: {integrity: sha512-UvxdOJ7mXFlw7iuHZA4jmzPaUqIw54mZrv+XPYKNbKdLR0et4rf60lIZUU9kiNtnzzMzGWxMV+tQ7uG7JG8DPw==} + /eslint/8.7.0: + resolution: {integrity: sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: @@ -3976,10 +3966,9 @@ packages: cross-spawn: 7.0.3 debug: 4.3.3 doctrine: 3.0.0 - enquirer: 2.3.6 escape-string-regexp: 4.0.0 eslint-scope: 7.1.0 - eslint-utils: 3.0.0_eslint@8.6.0 + eslint-utils: 3.0.0_eslint@8.7.0 eslint-visitor-keys: 3.2.0 espree: 9.3.0 esquery: 1.4.0 @@ -3989,7 +3978,7 @@ packages: functional-red-black-tree: 1.0.1 glob-parent: 6.0.2 globals: 13.12.0 - ignore: 4.0.6 + ignore: 5.2.0 import-fresh: 3.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 @@ -4000,9 +3989,7 @@ packages: minimatch: 3.0.4 natural-compare: 1.4.0 optionator: 0.9.1 - progress: 2.0.3 regexpp: 3.2.0 - semver: 7.3.5 strip-ansi: 6.0.1 strip-json-comments: 3.1.1 text-table: 0.2.0 @@ -7228,11 +7215,6 @@ packages: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: true - /progress/2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - dev: true - /promise-inflight/1.0.1: resolution: {integrity: sha1-mEcocL8igTL8vdhoEputEsPAKeM=} dev: true @@ -7503,7 +7485,6 @@ packages: /resolve.exports/1.1.0: resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==} engines: {node: '>=10'} - dev: true /resolve/1.21.0: resolution: {integrity: sha512-3wCbTpk5WJlyE4mSOtDLhqQmGFi0/TD9VPwmiolnk8U0wRgMEktqCXd3vy5buTO3tljvalNvKrjHEfrd2WpEKA==} diff --git a/src/utils/resolve.ts b/src/utils/resolve.ts index 60e4cfa8..0437368d 100644 --- a/src/utils/resolve.ts +++ b/src/utils/resolve.ts @@ -1,6 +1,10 @@ import resolver, { sync, AsyncOpts, SyncOpts } from "resolve"; +import { resolve as resolveExports, legacy as resolveFields } from "resolve.exports"; import arrayFmt from "./array-fmt"; +type Package = { main: string; [field: string]: unknown }; +type PackageFilterFn = (pkg: Package, pkgfile: string) => Package; + export interface ResolveOpts { /** name of the caller for error message (default to `Resolver`) */ caller?: string; @@ -11,7 +15,7 @@ export interface ResolveOpts { /** don't resolve `basedirs` to real path before resolving. (defaults to `true`) */ preserveSymlinks?: boolean; /** transform the parsed `package.json` contents before looking at the "main" field */ - packageFilter?: (pkg: Package, pkgfile: string) => Package; + packageFilter?: PackageFilterFn; } interface ResolveDefaultOpts { @@ -19,25 +23,52 @@ interface ResolveDefaultOpts { basedirs: ReadonlyArray; extensions: ReadonlyArray; preserveSymlinks: boolean; - packageFilter: (pkg: Package, pkgfile: string) => Package; + packageFilter: PackageFilterFn; } -interface Package { - main: string; - module?: string; - style?: string; +interface PackageFilterBuilderOpts { + fields?: string[]; + conditions?: string[]; } +type PackageFilterBuilderFn = (opts?: PackageFilterBuilderOpts) => PackageFilterFn; + +export const packageFilterBuiler: PackageFilterBuilderFn = (opts = {}) => { + const conditions = opts.conditions ?? ["style", "import", "require"]; + const fields = opts.fields ?? ["style", "module", "main"]; + return pkg => { + // Check `exports` fields + try { + const resolvedExport = resolveExports(pkg, ".", { conditions, unsafe: true }); + if (typeof resolvedExport === "string") { + pkg.main = resolvedExport; + return pkg; + } + } catch { + /* noop */ + } + + // Check independent fields + try { + const resolvedField = resolveFields(pkg, { fields, browser: false }); + if (typeof resolvedField === "string") { + pkg.main = resolvedField; + return pkg; + } + } catch { + /* noop */ + } + + return pkg; + }; +}; + const defaultOpts: ResolveDefaultOpts = { caller: "Resolver", basedirs: [__dirname], extensions: [".mjs", ".js", ".cjs", ".json"], preserveSymlinks: true, - packageFilter(pkg) { - if (pkg.module) pkg.main = pkg.module; - if (pkg.style) pkg.main = pkg.style; - return pkg; - }, + packageFilter: packageFilterBuiler(), }; const resolverAsync = async (id: string, options: AsyncOpts = {}): Promise =>