Skip to content

Commit

Permalink
fix: prefer exports when resolving (#10371)
Browse files Browse the repository at this point in the history
Co-authored-by: bluwy <bjornlu.dev@gmail.com>
  • Loading branch information
benmccann and bluwy committed Oct 13, 2022
1 parent ecba3f8 commit 3259006
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 6 deletions.
34 changes: 29 additions & 5 deletions packages/vite/src/node/plugins/resolve.ts
Expand Up @@ -648,13 +648,36 @@ export function tryNodeResolve(
basedir = nestedResolveFrom(nestedRoot, basedir, preserveSymlinks)
}

// nearest package.json
let nearestPkg: PackageData | undefined
// nearest package.json that may have the `exports` field
let pkg: PackageData | undefined
const pkgId = possiblePkgIds.reverse().find((pkgId) => {
pkg = resolvePackageData(pkgId, basedir, preserveSymlinks, packageCache)!
return pkg

let pkgId = possiblePkgIds.reverse().find((pkgId) => {
nearestPkg = resolvePackageData(
pkgId,
basedir,
preserveSymlinks,
packageCache
)!
return nearestPkg
})!

if (!pkg) {
const rootPkgId = possiblePkgIds[0]
const rootPkg = resolvePackageData(
rootPkgId,
basedir,
preserveSymlinks,
packageCache
)!
if (rootPkg?.data?.exports) {
pkg = rootPkg
pkgId = rootPkgId
} else {
pkg = nearestPkg
}

if (!pkg || !nearestPkg) {
// if import can't be found, check if it's an optional peer dep.
// if so, we can resolve to a special id that errors only when imported.
if (
Expand Down Expand Up @@ -753,7 +776,8 @@ export function tryNodeResolve(
}

const ext = path.extname(resolved)
const isCJS = ext === '.cjs' || (ext === '.js' && pkg.data.type !== 'module')
const isCJS =
ext === '.cjs' || (ext === '.js' && nearestPkg.data.type !== 'module')

if (
!options.ssrOptimizeCheck &&
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/ssr/ssrModuleLoader.ts
Expand Up @@ -126,7 +126,7 @@ async function instantiateModule(
preserveSymlinks,
isBuild: true,
isProduction,
isRequire: true,
isRequire: false,
root
}

Expand Down
7 changes: 7 additions & 0 deletions playground/resolve/__tests__/resolve.spec.ts
Expand Up @@ -36,6 +36,13 @@ test('deep import with exports field + mapped dir', async () => {
)
})

// this is how Svelte 3 is packaged
test('deep import with exports and legacy fallback', async () => {
expect(await page.textContent('.exports-legacy-fallback')).toMatch(
'[success]'
)
})

test('Respect exports field env key priority', async () => {
expect(await page.textContent('.exports-env')).toMatch('[success]')
})
Expand Down
1 change: 1 addition & 0 deletions playground/resolve/exports-legacy-fallback/dir/index.js
@@ -0,0 +1 @@
export const msg = '[fail] mapped js file'
1 change: 1 addition & 0 deletions playground/resolve/exports-legacy-fallback/dir/index.mjs
@@ -0,0 +1 @@
export const msg = '[success] mapped mjs file'
4 changes: 4 additions & 0 deletions playground/resolve/exports-legacy-fallback/dir/package.json
@@ -0,0 +1,4 @@
{
"main": "index.js",
"module": "index.mjs"
}
1 change: 1 addition & 0 deletions playground/resolve/exports-legacy-fallback/index.js
@@ -0,0 +1 @@
export default 5
12 changes: 12 additions & 0 deletions playground/resolve/exports-legacy-fallback/package.json
@@ -0,0 +1,12 @@
{
"name": "resolve-exports-legacy-fallback",
"private": true,
"version": "1.0.0",
"exports": {
"./dir": {
"import": "./dir/index.mjs",
"require": "./dir/index.js"
},
".": "index.js"
}
}
6 changes: 6 additions & 0 deletions playground/resolve/index.html
Expand Up @@ -24,6 +24,9 @@ <h2>Deep import with exports field + mapped directory</h2>
<h2>Exports field env priority</h2>
<p class="exports-env">fail</p>

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

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

Expand Down Expand Up @@ -163,6 +166,9 @@ <h2>resolve package that contains # in path</h2>
import { msg as exportsEnvMsg } from 'resolve-exports-env'
text('.exports-env', exportsEnvMsg)

import { msg as exportsLegacyFallbackMsg } from 'resolve-exports-legacy-fallback/dir'
text('.exports-legacy-fallback', exportsLegacyFallbackMsg)

// implicit index resolving
import { foo } from './util'
text('.index', foo())
Expand Down
1 change: 1 addition & 0 deletions playground/resolve/package.json
Expand Up @@ -20,6 +20,7 @@
"resolve-custom-condition": "link:./custom-condition",
"resolve-custom-main-field": "link:./custom-main-field",
"resolve-exports-env": "link:./exports-env",
"resolve-exports-legacy-fallback": "link:./exports-legacy-fallback",
"resolve-exports-path": "link:./exports-path",
"resolve-linked": "workspace:*"
}
Expand Down
8 changes: 8 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 3259006

Please sign in to comment.