Skip to content

Commit

Permalink
fix: externalize dependencies by default during SSR
Browse files Browse the repository at this point in the history
  • Loading branch information
benmccann committed Mar 16, 2022
1 parent 560fc4d commit 9c8451e
Showing 1 changed file with 2 additions and 45 deletions.
47 changes: 2 additions & 45 deletions packages/vite/src/node/ssr/ssrExternal.ts
@@ -1,14 +1,7 @@
import fs from 'fs'
import path from 'path'
import type { InternalResolveOptions } from '../plugins/resolve'
import { tryNodeResolve } from '../plugins/resolve'
import {
createDebugger,
isDefined,
lookupFile,
normalizePath,
resolveFrom
} from '../utils'
import { createDebugger, isDefined, lookupFile, resolveFrom } from '../utils'
import type { Logger, ResolvedConfig } from '..'
import { createFilter } from '@rollup/pluginutils'

Expand Down Expand Up @@ -79,9 +72,6 @@ export function resolveSSRExternal(
return externals
}

const CJS_CONTENT_RE =
/\bmodule\.exports\b|\bexports[.\[]|\brequire\s*\(|\bObject\.(defineProperty|defineProperties|assign)\s*\(\s*exports\b/

// do we need to do this ahead of time or could we do it lazily?
function collectExternals(
root: string,
Expand Down Expand Up @@ -115,7 +105,6 @@ function collectExternals(
seen.add(id)

let esmEntry: string | undefined
let requireEntry: string
try {
esmEntry = tryNodeResolve(
id,
Expand All @@ -125,9 +114,6 @@ function collectExternals(
undefined,
true
)?.id
// normalizePath required for windows. tryNodeResolve uses normalizePath
// which returns with '/', require.resolve returns with '\\'
requireEntry = normalizePath(require.resolve(id, { paths: [root] }))
} catch (e) {
try {
// no main entry, but deep imports may be allowed
Expand All @@ -152,38 +138,9 @@ function collectExternals(
else if (!esmEntry.includes('node_modules')) {
const pkgPath = resolveFrom(`${id}/package.json`, root)
depsToTrace.add(path.dirname(pkgPath))
}
// has separate esm/require entry, assume require entry is cjs
else if (esmEntry !== requireEntry) {
} else {
ssrExternals.add(id)
}
// if we're externalizing ESM and CJS should basically just always do it?
// or are there others like SystemJS / AMD that we'd need to handle?
// for now, we'll just leave this as is
else if (/\.m?js$/.test(esmEntry)) {
const pkgPath = resolveFrom(`${id}/package.json`, root)
const pkgContent = fs.readFileSync(pkgPath, 'utf-8')

if (!pkgContent) {
continue
}
const pkg = JSON.parse(pkgContent)

if (pkg.type === 'module' || esmEntry.endsWith('.mjs')) {
ssrExternals.add(id)
continue
}
// check if the entry is cjs
const content = fs.readFileSync(esmEntry, 'utf-8')
if (CJS_CONTENT_RE.test(content)) {
ssrExternals.add(id)
continue
}

logger.warn(
`${id} doesn't appear to be written in CJS, but also doesn't appear to be a valid ES module (i.e. it doesn't have "type": "module" or an .mjs extension for the entry point). Please contact the package author to fix.`
)
}
}

for (const depRoot of depsToTrace) {
Expand Down

0 comments on commit 9c8451e

Please sign in to comment.