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 @@
fail
+fail
+fail
@@ -169,6 +172,9 @@