fix(ssr): skip resolving browser field for SSR build, fix #3036 (#3039)

This commit is contained in:
underfin 2021-04-21 13:03:24 +08:00 committed by GitHub
parent d34fd88e46
commit 61ea320560
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 27 deletions

View File

@ -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<string, string | undefined>
ssrResolvedImports: Record<string, string | undefined>
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
}
}
}

View File

@ -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