diff --git a/packages/vite/src/node/plugins/resolve.ts b/packages/vite/src/node/plugins/resolve.ts index c610805c531ee7..7156ff05a24d0f 100644 --- a/packages/vite/src/node/plugins/resolve.ts +++ b/packages/vite/src/node/plugins/resolve.ts @@ -176,11 +176,14 @@ export function resolvePlugin(baseOptions: InternalResolveOptions): Plugin { return res } - if ((res = tryResolveBrowserMapping(id, importer, options, false))) { + if ( + !ssr && + (res = tryResolveBrowserMapping(id, importer, options, false)) + ) { return res } - if ((res = tryNodeResolve(id, importer, options, server))) { + if ((res = tryNodeResolve(id, importer, options, ssr, server))) { return res } @@ -228,7 +231,8 @@ export function resolvePlugin(baseOptions: InternalResolveOptions): Plugin { function tryFsResolve( fsPath: string, options: InternalResolveOptions, - tryIndex = true + tryIndex = true, + ssr?: boolean ): string | undefined { let file = fsPath let postfix = '' @@ -244,7 +248,14 @@ function tryFsResolve( let res: string | undefined if ( - (res = tryResolveFile(file, postfix, options, false, options.tryPrefix)) + (res = tryResolveFile( + file, + postfix, + options, + false, + ssr, + options.tryPrefix + )) ) { return res } @@ -256,6 +267,7 @@ function tryFsResolve( postfix, options, false, + ssr, options.tryPrefix )) ) { @@ -264,7 +276,14 @@ function tryFsResolve( } if ( - (res = tryResolveFile(file, postfix, options, tryIndex, options.tryPrefix)) + (res = tryResolveFile( + file, + postfix, + options, + tryIndex, + ssr, + options.tryPrefix + )) ) { return res } @@ -275,6 +294,7 @@ function tryResolveFile( postfix: string, options: InternalResolveOptions, tryIndex: boolean, + ssr?: boolean, tryPrefix?: string ): string | undefined { let isReadable = false @@ -293,7 +313,7 @@ function tryResolveFile( if (fs.existsSync(pkgPath)) { // path points to a node package const pkg = loadPackageData(pkgPath) - return resolvePackageEntry(file, pkg, options) + return resolvePackageEntry(file, pkg, options, ssr) } const index = tryFsResolve(file + '/index', options) if (index) return index + postfix @@ -301,7 +321,7 @@ function tryResolveFile( } if (tryPrefix) { const prefixed = `${path.dirname(file)}/${tryPrefix}${path.basename(file)}` - return tryResolveFile(prefixed, postfix, options, tryIndex) + return tryResolveFile(prefixed, postfix, options, tryIndex, ssr) } } @@ -311,6 +331,7 @@ export function tryNodeResolve( id: string, importer: string | undefined, options: InternalResolveOptions, + ssr?: boolean, server?: ViteDevServer ): PartialResolvedId | undefined { const { root, dedupe, isBuild } = options @@ -337,8 +358,8 @@ export function tryNodeResolve( } let resolved = deepMatch - ? resolveDeepImport(id, pkg, options) - : resolvePackageEntry(id, pkg, options) + ? resolveDeepImport(id, pkg, options, ssr) + : resolvePackageEntry(id, pkg, options, ssr) if (!resolved) { return } @@ -411,6 +432,9 @@ export interface PackageData { dir: string hasSideEffects: (id: string) => boolean resolvedImports: Record + ssrResolvedImports: Record + setResolvedCache: (key: string, entry: string, ssr?: boolean) => void + getResolvedCache: (key: string, ssr?: boolean) => string | undefined data: { [field: string]: any version: string @@ -453,11 +477,26 @@ function loadPackageData(pkgPath: string, cacheKey = pkgPath) { hasSideEffects = () => true } - const pkg = { + const pkg: PackageData = { dir: pkgDir, data, hasSideEffects, - resolvedImports: {} + resolvedImports: {}, + ssrResolvedImports: {}, + setResolvedCache(key: string, entry: string, ssr?: boolean) { + if (ssr) { + pkg.ssrResolvedImports[key] = entry + } else { + pkg.resolvedImports[key] = entry + } + }, + getResolvedCache(key: string, ssr?: boolean) { + if (ssr) { + return pkg.ssrResolvedImports[key] + } else { + return pkg.resolvedImports[key] + } + } } packageCache.set(cacheKey, pkg) return pkg @@ -465,13 +504,14 @@ function loadPackageData(pkgPath: string, cacheKey = pkgPath) { export function resolvePackageEntry( id: string, - { resolvedImports, dir, data }: PackageData, - options: InternalResolveOptions + { dir, data, setResolvedCache, getResolvedCache }: PackageData, + options: InternalResolveOptions, + ssr?: boolean ): string | undefined { - if (resolvedImports['.']) { - return resolvedImports['.'] + const cached = getResolvedCache('.', ssr) + if (cached) { + return cached } - let entryPoint: string | undefined | void // resolve exports field with highest priority @@ -484,7 +524,7 @@ export function resolvePackageEntry( // This is because .mjs files can technically import .cjs files which would // make them invalid for pure ESM environments - so if other module/browser // fields are present, prioritize those instead. - if (!entryPoint || entryPoint.endsWith('.mjs')) { + if (!ssr && (!entryPoint || entryPoint.endsWith('.mjs'))) { // check browser field // https://github.com/defunctzombie/package-browser-field-spec const browserEntry = @@ -534,7 +574,7 @@ export function resolvePackageEntry( // resolve object browser field in package.json const { browser: browserField } = data - if (isObject(browserField)) { + if (!ssr && isObject(browserField)) { entryPoint = mapWithBrowserField(entryPoint, browserField) || entryPoint } @@ -546,7 +586,7 @@ export function resolvePackageEntry( debug( `[package entry] ${chalk.cyan(id)} -> ${chalk.dim(resolvedEntryPoint)}` ) - resolvedImports['.'] = resolvedEntryPoint + setResolvedCache('.', resolvedEntryPoint, ssr) return resolvedEntryPoint } else { throw new Error( @@ -577,12 +617,20 @@ function resolveExports( function resolveDeepImport( id: string, - { resolvedImports, dir, data }: PackageData, - options: InternalResolveOptions + { + resolvedImports, + setResolvedCache, + getResolvedCache, + dir, + data + }: PackageData, + options: InternalResolveOptions, + ssr?: boolean ): string | undefined { id = '.' + id.slice(data.name.length) - if (resolvedImports[id]) { - return resolvedImports[id] + const cache = getResolvedCache(id, ssr) + if (cache) { + return cache } let relativeId: string | undefined | void = id @@ -602,7 +650,7 @@ function resolveDeepImport( `${path.join(dir, 'package.json')}.` ) } - } else if (isObject(browserField)) { + } else if (!ssr && isObject(browserField)) { const mapped = mapWithBrowserField(relativeId, browserField) if (mapped) { relativeId = mapped @@ -615,12 +663,14 @@ function resolveDeepImport( const resolved = tryFsResolve( path.join(dir, relativeId), options, - !exportsField // try index only if no exports field + !exportsField, // try index only if no exports field + ssr ) if (resolved) { isDebug && debug(`[node/deep-import] ${chalk.cyan(id)} -> ${chalk.dim(resolved)}`) - return (resolvedImports[id] = resolved) + setResolvedCache(id, resolved, ssr) + return resolved } } } diff --git a/packages/vite/src/node/ssr/ssrExternal.ts b/packages/vite/src/node/ssr/ssrExternal.ts index 197ee3b9fe6c7d..1ab0d0ec7f0769 100644 --- a/packages/vite/src/node/ssr/ssrExternal.ts +++ b/packages/vite/src/node/ssr/ssrExternal.ts @@ -48,7 +48,7 @@ export function resolveSSRExternal( let entry let requireEntry try { - entry = tryNodeResolve(id, undefined, resolveOptions)?.id + entry = tryNodeResolve(id, undefined, resolveOptions, true)?.id requireEntry = require.resolve(id, { paths: [root] }) } catch (e) { // resolve failed, assume include