From d6eb4f24a463777200506c03fd55d8fa4e1ea394 Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Wed, 7 Dec 2022 21:34:51 +0800 Subject: [PATCH] fix(resolve): ensure exports has precedence over mainFields (#11234) --- packages/vite/src/node/plugins/resolve.ts | 6 +++++- playground/resolve/__tests__/resolve.spec.ts | 4 ++++ playground/resolve/exports-with-module/import.mjs | 2 ++ playground/resolve/exports-with-module/module.mjs | 2 ++ playground/resolve/exports-with-module/package.json | 10 ++++++++++ playground/resolve/index.html | 6 ++++++ playground/resolve/package.json | 1 + pnpm-lock.yaml | 5 +++++ 8 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 playground/resolve/exports-with-module/import.mjs create mode 100644 playground/resolve/exports-with-module/module.mjs create mode 100644 playground/resolve/exports-with-module/package.json diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index 2c45771c46e101..58ced293e89103 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -931,6 +931,8 @@ export function resolvePackageEntry( entryPoint = resolveExports(data, '.', options, targetWeb) } + const resolvedFromExports = !!entryPoint + // if exports resolved to .mjs, still resolve other fields. // This is because .mjs files can technically import .cjs files which would // make them invalid for pure ESM environments - so if other module/browser @@ -980,7 +982,9 @@ export function resolvePackageEntry( } } - if (!entryPoint || entryPoint.endsWith('.mjs')) { + // fallback to mainFields if still not resolved + // TODO: review if `.mjs` check is still needed + if (!resolvedFromExports && (!entryPoint || entryPoint.endsWith('.mjs'))) { for (const field of options.mainFields) { if (field === 'browser') continue // already checked above if (typeof data[field] === 'string') { diff --git a/playground/resolve/__tests__/resolve.spec.ts b/playground/resolve/__tests__/resolve.spec.ts index 2181f6d3c8433e..2371c55759728e 100644 --- a/playground/resolve/__tests__/resolve.spec.ts +++ b/playground/resolve/__tests__/resolve.spec.ts @@ -53,6 +53,10 @@ test('Respect production/development conditionals', async () => { ) }) +test('Respect exports to take precedence over mainFields', async () => { + expect(await page.textContent('.exports-with-module')).toMatch('[success]') +}) + test('implicit dir/index.js', async () => { expect(await page.textContent('.index')).toMatch('[success]') }) diff --git a/playground/resolve/exports-with-module/import.mjs b/playground/resolve/exports-with-module/import.mjs new file mode 100644 index 00000000000000..d97c695169a575 --- /dev/null +++ b/playground/resolve/exports-with-module/import.mjs @@ -0,0 +1,2 @@ +// import.mjs should take precedence +export const msg = '[success] exports with module (import.mjs)' diff --git a/playground/resolve/exports-with-module/module.mjs b/playground/resolve/exports-with-module/module.mjs new file mode 100644 index 00000000000000..f9392192058822 --- /dev/null +++ b/playground/resolve/exports-with-module/module.mjs @@ -0,0 +1,2 @@ +// import.mjs should take precedence +export const msg = '[fail] exports with module (module.mjs)' diff --git a/playground/resolve/exports-with-module/package.json b/playground/resolve/exports-with-module/package.json new file mode 100644 index 00000000000000..b3d9f7e999ca75 --- /dev/null +++ b/playground/resolve/exports-with-module/package.json @@ -0,0 +1,10 @@ +{ + "name": "@vitejs/test-resolve-exports-with-module", + "private": true, + "version": "1.0.0", + "type": "commonjs", + "module": "./module.mjs", + "exports": { + "import": "./import.mjs" + } +} diff --git a/playground/resolve/index.html b/playground/resolve/index.html index 9aa1261f98c980..3a6ba0cc930024 100644 --- a/playground/resolve/index.html +++ b/playground/resolve/index.html @@ -27,6 +27,9 @@

Exports field env priority

Exports with legacy fallback

fail

+

Exports with module

+

fail

+

Resolve /index.*

fail

@@ -169,6 +172,9 @@

resolve package that contains # in path

import { msg as exportsLegacyFallbackMsg } from '@vitejs/test-resolve-exports-legacy-fallback/dir' text('.exports-legacy-fallback', exportsLegacyFallbackMsg) + import { msg as exportsWithModule } from '@vitejs/test-resolve-exports-with-module' + text('.exports-with-module', exportsWithModule) + // implicit index resolving import { foo } from './util' text('.index', foo()) diff --git a/playground/resolve/package.json b/playground/resolve/package.json index d7e5f07b17f845..bccde4be65bb1f 100644 --- a/playground/resolve/package.json +++ b/playground/resolve/package.json @@ -22,6 +22,7 @@ "@vitejs/test-resolve-exports-env": "link:./exports-env", "@vitejs/test-resolve-exports-legacy-fallback": "link:./exports-legacy-fallback", "@vitejs/test-resolve-exports-path": "link:./exports-path", + "@vitejs/test-resolve-exports-with-module": "link:./exports-with-module", "@vitejs/test-resolve-linked": "workspace:*" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a59098cb33ccdb..23cf6f4d637c8d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -801,6 +801,7 @@ importers: '@vitejs/test-resolve-exports-env': link:./exports-env '@vitejs/test-resolve-exports-legacy-fallback': link:./exports-legacy-fallback '@vitejs/test-resolve-exports-path': link:./exports-path + '@vitejs/test-resolve-exports-with-module': link:./exports-with-module '@vitejs/test-resolve-linked': workspace:* es5-ext: 0.10.62 normalize.css: ^8.0.1 @@ -816,6 +817,7 @@ importers: '@vitejs/test-resolve-exports-env': link:exports-env '@vitejs/test-resolve-exports-legacy-fallback': link:exports-legacy-fallback '@vitejs/test-resolve-exports-path': link:exports-path + '@vitejs/test-resolve-exports-with-module': link:exports-with-module '@vitejs/test-resolve-linked': link:../resolve-linked es5-ext: 0.10.62 normalize.css: 8.0.1 @@ -856,6 +858,9 @@ importers: playground/resolve/exports-path: specifiers: {} + playground/resolve/exports-with-module: + specifiers: {} + playground/resolve/inline-package: specifiers: {}