Skip to content

Commit

Permalink
fix(resolve): ensure exports has precedence over mainFields (cherry p…
Browse files Browse the repository at this point in the history
…ick #11234) (#11595)
  • Loading branch information
bluwy committed Jan 5, 2023
1 parent 167753d commit 691e432
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 1 deletion.
6 changes: 5 additions & 1 deletion packages/vite/src/node/plugins/resolve.ts
Expand Up @@ -945,6 +945,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
Expand Down Expand Up @@ -994,7 +996,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') {
Expand Down
4 changes: 4 additions & 0 deletions playground/resolve/__tests__/resolve.spec.ts
Expand Up @@ -63,6 +63,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]')
})
Expand Down
2 changes: 2 additions & 0 deletions 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)'
2 changes: 2 additions & 0 deletions 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)'
10 changes: 10 additions & 0 deletions 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"
}
}
6 changes: 6 additions & 0 deletions playground/resolve/index.html
Expand Up @@ -33,6 +33,9 @@ <h2>Exports field read only from the root package.json</h2>
<h2>Exports with legacy fallback</h2>
<p class="exports-legacy-fallback">fail</p>

<h2>Exports with module</h2>
<p class="exports-with-module">fail</p>

<h2>Resolve /index.*</h2>
<p class="index">fail</p>

Expand Down Expand Up @@ -181,6 +184,9 @@ <h2>resolve package that contains # in path</h2>
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())
Expand Down
1 change: 1 addition & 0 deletions playground/resolve/package.json
Expand Up @@ -24,6 +24,7 @@
"@vitejs/test-resolve-exports-from-root": "link:./exports-from-root",
"@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:*"
}
}
5 changes: 5 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 691e432

Please sign in to comment.