Skip to content

Commit c669c52

Browse files
authored
feat(ssr): resolve externalized packages with resolve.externalConditions and add module-sync to default external condition (vitejs#20409)
1 parent 557f797 commit c669c52

File tree

9 files changed

+66
-14
lines changed

9 files changed

+66
-14
lines changed

packages/vite/src/node/constants.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,10 @@ export const DEFAULT_SERVER_CONDITIONS = Object.freeze(
6464
DEFAULT_CONDITIONS.filter((c) => c !== 'browser'),
6565
)
6666

67-
export const DEFAULT_EXTERNAL_CONDITIONS = Object.freeze(['node'])
67+
export const DEFAULT_EXTERNAL_CONDITIONS = Object.freeze([
68+
'node',
69+
'module-sync',
70+
])
6871

6972
/**
7073
* The browser versions that are included in the Baseline Widely Available on 2025-05-01.

packages/vite/src/node/plugins/resolve.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ export function tryNodeResolve(
765765
const resolveId = deepMatch ? resolveDeepImport : resolvePackageEntry
766766
const unresolvedId = deepMatch ? '.' + id.slice(pkgId.length) : id
767767

768-
let resolved = resolveId(unresolvedId, pkg, options)
768+
let resolved = resolveId(unresolvedId, pkg, options, externalize)
769769
if (!resolved) {
770770
return
771771
}
@@ -905,6 +905,7 @@ export function resolvePackageEntry(
905905
id: string,
906906
{ dir, data, setResolvedCache, getResolvedCache }: PackageData,
907907
options: InternalResolveOptions,
908+
externalize?: boolean,
908909
): string | undefined {
909910
const { file: idWithoutPostfix, postfix } = splitFileAndPostfix(id)
910911

@@ -919,7 +920,13 @@ export function resolvePackageEntry(
919920
// resolve exports field with highest priority
920921
// using https://github.com/lukeed/resolve.exports
921922
if (data.exports) {
922-
entryPoint = resolveExportsOrImports(data, '.', options, 'exports')
923+
entryPoint = resolveExportsOrImports(
924+
data,
925+
'.',
926+
options,
927+
'exports',
928+
externalize,
929+
)
923930
}
924931

925932
// fallback to mainFields if still not resolved
@@ -999,8 +1006,12 @@ function resolveExportsOrImports(
9991006
key: string,
10001007
options: InternalResolveOptions,
10011008
type: 'imports' | 'exports',
1009+
externalize?: boolean,
10021010
) {
1003-
const conditions = options.conditions.map((condition) => {
1011+
const rawConditions = externalize
1012+
? options.externalConditions
1013+
: options.conditions
1014+
const conditions = rawConditions.map((condition) => {
10041015
if (condition === DEV_PROD_CONDITION) {
10051016
return options.isProduction ? 'production' : 'development'
10061017
}
@@ -1022,6 +1033,7 @@ function resolveDeepImport(
10221033
id: string,
10231034
{ setResolvedCache, getResolvedCache, dir, data }: PackageData,
10241035
options: InternalResolveOptions,
1036+
externalize?: boolean,
10251037
): string | undefined {
10261038
const cache = getResolvedCache(id, options)
10271039
if (cache) {
@@ -1036,7 +1048,13 @@ function resolveDeepImport(
10361048
if (isObject(exportsField) && !Array.isArray(exportsField)) {
10371049
// resolve without postfix (see #7098)
10381050
const { file, postfix } = splitFileAndPostfix(relativeId)
1039-
const exportsId = resolveExportsOrImports(data, file, options, 'exports')
1051+
const exportsId = resolveExportsOrImports(
1052+
data,
1053+
file,
1054+
options,
1055+
'exports',
1056+
externalize,
1057+
)
10401058
if (exportsId !== undefined) {
10411059
relativeId = exportsId + postfix
10421060
} else {

packages/vite/src/node/ssr/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export interface SSROptions {
4040
/**
4141
* Conditions that are used during ssr import (including `ssrLoadModule`) of externalized dependencies.
4242
*
43-
* @default ['node']
43+
* @default ['node', 'module-sync']
4444
*/
4545
externalConditions?: string[]
4646

playground/ssr-resolve/__tests__/ssr-resolve.spec.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
import { execFile } from 'node:child_process'
2+
import { promisify } from 'node:util'
13
import { expect, test } from 'vitest'
24
import { isBuild, readFile, testDir } from '~utils'
35

6+
const execFileAsync = promisify(execFile)
7+
48
test.runIf(isBuild)('correctly resolve entrypoints', async () => {
59
const contents = readFile('dist/main.mjs')
610

@@ -19,11 +23,13 @@ test.runIf(isBuild)('correctly resolve entrypoints', async () => {
1923
new RegExp(`from ${_}@vitejs/test-deep-import/foo/index.js${_}`),
2024
)
2125

22-
expect(contents).toMatch(
23-
new RegExp(`from ${_}@vitejs/test-deep-import/bar${_}`),
24-
)
26+
// expect(contents).toMatch(
27+
// new RegExp(`from ${_}@vitejs/test-deep-import/utils/bar.js${_}`),
28+
// )
29+
30+
expect(contents).toMatch(new RegExp(`from ${_}@vitejs/test-module-sync${_}`))
2531

26-
await expect(import(`${testDir}/dist/main.mjs`)).resolves.toBeTruthy()
32+
await execFileAsync('node', [`${testDir}/dist/main.mjs`])
2733
})
2834

2935
test.runIf(isBuild)(

playground/ssr-resolve/main.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@ import fileEntry from '@vitejs/test-entries/file'
55
// has `exports` key, should resolve to pkg-exports/entry
66
import pkgExportsEntry from '@vitejs/test-resolve-pkg-exports/entry'
77
import deepFoo from '@vitejs/test-deep-import/foo'
8-
import deepBar from '@vitejs/test-deep-import/bar'
8+
// import deepBar from '@vitejs/test-deep-import/bar'
9+
import moduleSync from '@vitejs/test-module-sync'
910
import { used } from './util'
1011

1112
export default `
1213
entries/dir: ${dirEntry}
1314
entries/file: ${fileEntry}
1415
pkg-exports/entry: ${pkgExportsEntry}
1516
deep-import/foo: ${deepFoo}
16-
deep-import/bar: ${deepBar}
17+
${/* `deep-import/bar: ${deepBar}` */ ''}
18+
module-sync: ${moduleSync}
1719
util: ${used(['[success]'])}
1820
`

playground/ssr-resolve/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
"debug": "node --inspect-brk ../../packages/vite/bin/vite build"
99
},
1010
"dependencies": {
11+
"@vitejs/test-deep-import": "file:./deep-import",
1112
"@vitejs/test-entries": "file:./entries",
12-
"@vitejs/test-resolve-pkg-exports": "file:./pkg-exports",
13-
"@vitejs/test-deep-import": "file:./deep-import"
13+
"@vitejs/test-module-sync": "file:./pkg-module-sync",
14+
"@vitejs/test-resolve-pkg-exports": "file:./pkg-exports"
1415
}
1516
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default 'module-sync'
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"name": "@vitejs/test-module-sync",
3+
"type": "module",
4+
"private": true,
5+
"version": "0.0.0",
6+
"exports": {
7+
".": {
8+
"module-sync": "./index.js"
9+
}
10+
}
11+
}

pnpm-lock.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)