Skip to content

Commit d420f01

Browse files
authoredJul 22, 2022
fix: entries in ssr.external (#9286)
1 parent acc4406 commit d420f01

File tree

11 files changed

+104
-6
lines changed

11 files changed

+104
-6
lines changed
 

‎packages/vite/src/node/ssr/ssrExternal.ts

+16-3
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,22 @@ export function createIsConfiguredAsSsrExternal(
124124
if (!pkgName) {
125125
return undefined
126126
}
127-
if (ssr.external?.includes(pkgName)) {
127+
if (
128+
// If this id is defined as external, force it as external
129+
// Note that individual package entries are allowed in ssr.external
130+
ssr.external?.includes(id)
131+
) {
128132
return true
129133
}
134+
if (
135+
// A package name in ssr.external externalizes every entry
136+
ssr.external?.includes(pkgName)
137+
) {
138+
// Return undefined here to avoid short-circuiting the isExternalizable check,
139+
// that will filter this id out if it is not externalizable (e.g. a CSS file)
140+
// We return here to make ssr.external take precedence over noExternal
141+
return undefined
142+
}
130143
if (typeof noExternal === 'boolean') {
131144
return !noExternal
132145
}
@@ -154,7 +167,7 @@ function createIsSsrExternal(
154167
isBuild: true
155168
}
156169

157-
const isValidPackageEntry = (id: string) => {
170+
const isExternalizable = (id: string) => {
158171
if (!bareImportRE.test(id) || id.includes('\0')) {
159172
return false
160173
}
@@ -176,7 +189,7 @@ function createIsSsrExternal(
176189
let external = false
177190
if (!id.startsWith('.') && !path.isAbsolute(id)) {
178191
external =
179-
isBuiltin(id) || (isConfiguredAsExternal(id) ?? isValidPackageEntry(id))
192+
isBuiltin(id) || (isConfiguredAsExternal(id) ?? isExternalizable(id))
180193
}
181194
processedIds.set(id, external)
182195
return external

‎playground/ssr-deps/__tests__/ssr-deps.spec.ts

+7
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,10 @@ test('msg from optimized cjs with nested external', async () => {
9191
'Hello World!'
9292
)
9393
})
94+
95+
test('msg from external using external entry', async () => {
96+
await page.goto(url)
97+
expect(await page.textContent('.external-using-external-entry')).toMatch(
98+
'Hello World!'
99+
)
100+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Module with state, to check that it is properly externalized and
2+
// not bundled in the optimized deps
3+
let msg
4+
export function setMessage(externalMsg) {
5+
msg = externalMsg
6+
}
7+
export default function getMessage() {
8+
return msg
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default undefined
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "external-entry",
3+
"private": true,
4+
"version": "0.0.0",
5+
"exports": {
6+
".": "./index.js",
7+
"./entry": "./entry.js"
8+
},
9+
"type": "module"
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import getMessage from 'external-entry/entry'
2+
3+
export default {
4+
hello() {
5+
return getMessage()
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "external-using-external-entry",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"main": "index.js",
7+
"dependencies": {
8+
"external-entry": "file:../external-entry"
9+
}
10+
}

‎playground/ssr-deps/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
"no-external-css": "file:./no-external-css",
2525
"non-optimized-with-nested-external": "file:./non-optimized-with-nested-external",
2626
"optimized-with-nested-external": "file:./optimized-with-nested-external",
27-
"optimized-cjs-with-nested-external": "file:./optimized-with-nested-external"
27+
"optimized-cjs-with-nested-external": "file:./optimized-with-nested-external",
28+
"external-using-external-entry": "file:./external-using-external-entry",
29+
"external-entry": "file:./external-entry"
2830
},
2931
"devDependencies": {
3032
"cross-env": "^7.0.3",

‎playground/ssr-deps/server.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,13 @@ export async function createServer(root = process.cwd(), hmrPort) {
3535
},
3636
appType: 'custom',
3737
ssr: {
38-
noExternal: ['no-external-cjs', 'import-builtin-cjs', 'no-external-css'],
39-
external: ['nested-external'],
38+
noExternal: [
39+
'no-external-cjs',
40+
'import-builtin-cjs',
41+
'no-external-css',
42+
'external-entry'
43+
],
44+
external: ['nested-external', 'external-entry/entry'],
4045
optimizeDeps: {
4146
disabled: 'build'
4247
}

‎playground/ssr-deps/src/app.js

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ import 'non-optimized-with-nested-external'
2020
import optimizedWithNestedExternal from 'optimized-with-nested-external'
2121
import optimizedCjsWithNestedExternal from 'optimized-cjs-with-nested-external'
2222

23+
import { setMessage } from 'external-entry/entry'
24+
setMessage('Hello World!')
25+
import externalUsingExternalEntry from 'external-using-external-entry'
26+
2327
export async function render(url, rootDir) {
2428
let html = ''
2529

@@ -68,5 +72,8 @@ export async function render(url, rootDir) {
6872
optimizedCjsWithNestedExternal.hello()
6973
html += `\n<p class="optimized-cjs-with-nested-external">message from optimized-cjs-with-nested-external: ${optimizedCjsWithNestedExternalMessage}</p>`
7074

75+
const externalUsingExternalEntryMessage = externalUsingExternalEntry.hello()
76+
html += `\n<p class="external-using-external-entry">message from external-using-external-entry: ${externalUsingExternalEntryMessage}</p>`
77+
7178
return html + '\n'
7279
}

‎pnpm-lock.yaml

+27
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.