Skip to content

Commit

Permalink
fix: ensure SSR sup-dependencies are correctly externalized if not re…
Browse files Browse the repository at this point in the history
…solvable from root
  • Loading branch information
rtsao committed Jan 19, 2023
1 parent c56b954 commit d0be74c
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 17 deletions.
2 changes: 1 addition & 1 deletion packages/vite/src/node/plugins/importAnalysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ export function importAnalysisPlugin(config: ResolvedConfig): Plugin {
if (cjsShouldExternalizeForSSR(specifier, server._ssrExternals)) {
continue
}
} else if (shouldExternalizeForSSR(specifier, config)) {
} else if (shouldExternalizeForSSR(specifier, importer, config)) {
continue
}
if (isBuiltin(specifier)) {
Expand Down
4 changes: 2 additions & 2 deletions packages/vite/src/node/plugins/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ export async function resolvePlugins(
getDepsOptimizer: (ssr: boolean) => getDepsOptimizer(config, ssr),
shouldExternalize:
isBuild && config.build.ssr && config.ssr?.format !== 'cjs'
? (id) => shouldExternalizeForSSR(id, config)
: undefined,
? (id, importer) => shouldExternalizeForSSR(id, importer, config)
: undefined
}),
htmlInlineProxyPlugin(config),
cssPlugin(config),
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/node/plugins/preAlias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export function preAliasPlugin(config: ResolvedConfig): Plugin {
(resolvedId.includes('node_modules') ||
optimizeDeps.include?.includes(id)) &&
isOptimizable(resolvedId, optimizeDeps) &&
!(isBuild && ssr && isConfiguredAsExternal(id)) &&
!(isBuild && ssr && isConfiguredAsExternal(id, importer)) &&
(!ssr || optimizeAliasReplacementForSSR(resolvedId, optimizeDeps))
) {
// aliased dep has not yet been optimized
Expand Down
4 changes: 2 additions & 2 deletions packages/vite/src/node/plugins/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export interface InternalResolveOptions extends Required<ResolveOptions> {
ssrOptimizeCheck?: boolean
// Resolve using esbuild deps optimization
getDepsOptimizer?: (ssr: boolean) => DepsOptimizer | undefined
shouldExternalize?: (id: string) => boolean | undefined
shouldExternalize?: (id: string, importer?: string) => boolean | undefined
}

export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin {
Expand Down Expand Up @@ -303,7 +303,7 @@ export function resolvePlugin(resolveOptions: InternalResolveOptions): Plugin {

// bare package imports, perform node resolve
if (bareImportRE.test(id)) {
const external = options.shouldExternalize?.(id)
const external = options.shouldExternalize?.(id, importer)
if (
!external &&
asSrc &&
Expand Down
24 changes: 13 additions & 11 deletions packages/vite/src/node/ssr/ssrExternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,24 +90,25 @@ const _require = createRequire(import.meta.url)

const isSsrExternalCache = new WeakMap<
ResolvedConfig,
(id: string) => boolean | undefined
(id: string, importer?: string) => boolean | undefined
>()

export function shouldExternalizeForSSR(
id: string,
importer: string | undefined,
config: ResolvedConfig,
): boolean | undefined {
let isSsrExternal = isSsrExternalCache.get(config)
if (!isSsrExternal) {
isSsrExternal = createIsSsrExternal(config)
isSsrExternalCache.set(config, isSsrExternal)
}
return isSsrExternal(id)
return isSsrExternal(id, importer)
}

export function createIsConfiguredAsSsrExternal(
config: ResolvedConfig,
): (id: string) => boolean {
): (id: string, importer?: string) => boolean {
const { ssr, root } = config
const noExternal = ssr?.noExternal
const noExternalFilter =
Expand All @@ -124,6 +125,7 @@ export function createIsConfiguredAsSsrExternal(

const isExternalizable = (
id: string,
importer?: string,
configuredAsExternal?: boolean,
): boolean => {
if (!bareImportRE.test(id) || id.includes('\0')) {
Expand All @@ -132,7 +134,7 @@ export function createIsConfiguredAsSsrExternal(
try {
return !!tryNodeResolve(
id,
undefined,
importer,
resolveOptions,
ssr?.target === 'webworker',
undefined,
Expand All @@ -155,7 +157,7 @@ export function createIsConfiguredAsSsrExternal(

// Returns true if it is configured as external, false if it is filtered
// by noExternal and undefined if it isn't affected by the explicit config
return (id: string) => {
return (id: string, importer?: string) => {
const { ssr } = config
if (ssr) {
if (
Expand All @@ -167,14 +169,14 @@ export function createIsConfiguredAsSsrExternal(
}
const pkgName = getNpmPackageName(id)
if (!pkgName) {
return isExternalizable(id)
return isExternalizable(id, importer)
}
if (
// A package name in ssr.external externalizes every
// externalizable package entry
ssr.external?.includes(pkgName)
) {
return isExternalizable(id, true)
return isExternalizable(id, importer, true)
}
if (typeof noExternal === 'boolean') {
return !noExternal
Expand All @@ -183,24 +185,24 @@ export function createIsConfiguredAsSsrExternal(
return false
}
}
return isExternalizable(id)
return isExternalizable(id, importer)
}
}

function createIsSsrExternal(
config: ResolvedConfig,
): (id: string) => boolean | undefined {
): (id: string, importer?: string) => boolean | undefined {
const processedIds = new Map<string, boolean | undefined>()

const isConfiguredAsExternal = createIsConfiguredAsSsrExternal(config)

return (id: string) => {
return (id: string, importer?: string) => {
if (processedIds.has(id)) {
return processedIds.get(id)
}
let external = false
if (!id.startsWith('.') && !path.isAbsolute(id)) {
external = isBuiltin(id) || isConfiguredAsExternal(id)
external = isBuiltin(id) || isConfiguredAsExternal(id, importer)
}
processedIds.set(id, external)
return external
Expand Down

0 comments on commit d0be74c

Please sign in to comment.