fix(vite): improve external handling (#729)

This commit is contained in:
pooya parsa 2021-10-12 03:38:30 +02:00 committed by GitHub
parent 95779c3d5f
commit e531b65a32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 13 deletions

View File

@ -24,6 +24,7 @@
"debounce": "^1.2.1", "debounce": "^1.2.1",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"magic-string": "^0.25.7", "magic-string": "^0.25.7",
"p-debounce": "^4.0.0",
"pathe": "^0.2.0", "pathe": "^0.2.0",
"ufo": "^0.7.9", "ufo": "^0.7.9",
"vite": "^2.6.7", "vite": "^2.6.7",

View File

@ -1,22 +1,45 @@
import { builtinModules } from 'module' import { builtinModules } from 'module'
import { join } from 'pathe'
import * as vite from 'vite' import * as vite from 'vite'
import { hashId, uniq } from './utils' import { hashId, uniq } from './utils'
interface TransformChunk { export interface TransformChunk {
id: string, id: string,
code: string, code: string,
deps: string[], deps: string[],
parents: string[] parents: string[]
} }
interface SSRTransformResult { export interface SSRTransformResult {
code: string, code: string,
map: object, map: object,
deps: string[] deps: string[]
dynamicDeps: string[] dynamicDeps: string[]
} }
async function transformRequest (viteServer: vite.ViteDevServer, id) { export interface TransformOptions {
viteServer: vite.ViteDevServer
}
function isExternal (opts: TransformOptions, id: string) {
if (builtinModules.includes(id)) {
return true
}
const ssrConfig = (opts.viteServer.config as any).ssr
if (ssrConfig.noExternal.find(ext => id.includes(ext))) {
return false
}
if (ssrConfig.external.find(ext => id.includes(ext))) {
return true
}
return id.includes('node_modules')
}
async function transformRequest (opts: TransformOptions, id: string) {
// Virtual modules start with `\0` // Virtual modules start with `\0`
if (id && id.startsWith('/@id/__x00__')) { if (id && id.startsWith('/@id/__x00__')) {
id = '\0' + id.slice('/@id/__x00__'.length) id = '\0' + id.slice('/@id/__x00__'.length)
@ -24,18 +47,24 @@ async function transformRequest (viteServer: vite.ViteDevServer, id) {
if (id && id.startsWith('/@id/')) { if (id && id.startsWith('/@id/')) {
id = id.slice('/@id/'.length) id = id.slice('/@id/'.length)
} }
if (id && id.startsWith('/@fs/')) {
id = id.slice('/@fs'.length)
}
if (id.startsWith('/node_modules')) {
id = join(opts.viteServer.config.root, id)
}
// Externals // Externals
if (builtinModules.includes(id) || id.includes('node_modules')) { if (isExternal(opts, id)) {
return { return {
code: `(global, exports, importMeta, ssrImport, ssrDynamicImport, ssrExportAll) => import('${id.replace(/^\/@fs/, '')}').then(r => { ssrExportAll(r) })`, code: `(global, exports, importMeta, ssrImport, ssrDynamicImport, ssrExportAll) => import('${id}').then(r => { ssrExportAll(r) })`,
deps: [], deps: [],
dynamicDeps: [] dynamicDeps: []
} }
} }
// Transform // Transform
const res: SSRTransformResult = await viteServer.transformRequest(id, { ssr: true }).catch((err) => { const res: SSRTransformResult = await opts.viteServer.transformRequest(id, { ssr: true }).catch((err) => {
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.warn(`[SSR] Error transforming ${id}: ${err}`) console.warn(`[SSR] Error transforming ${id}: ${err}`)
// console.error(err) // console.error(err)
@ -48,12 +77,12 @@ ${res.code || '/* empty */'};
return { code, deps: res.deps || [], dynamicDeps: res.dynamicDeps || [] } return { code, deps: res.deps || [], dynamicDeps: res.dynamicDeps || [] }
} }
async function transformRequestRecursive (viteServer: vite.ViteDevServer, id, parent = '<entry>', chunks: Record<string, TransformChunk> = {}) { async function transformRequestRecursive (opts: TransformOptions, id, parent = '<entry>', chunks: Record<string, TransformChunk> = {}) {
if (chunks[id]) { if (chunks[id]) {
chunks[id].parents.push(parent) chunks[id].parents.push(parent)
return return
} }
const res = await transformRequest(viteServer, id) const res = await transformRequest(opts, id)
const deps = uniq([...res.deps, ...res.dynamicDeps]) const deps = uniq([...res.deps, ...res.dynamicDeps])
chunks[id] = { chunks[id] = {
@ -63,13 +92,13 @@ async function transformRequestRecursive (viteServer: vite.ViteDevServer, id, pa
parents: [parent] parents: [parent]
} as TransformChunk } as TransformChunk
for (const dep of deps) { for (const dep of deps) {
await transformRequestRecursive(viteServer, dep, id, chunks) await transformRequestRecursive(opts, dep, id, chunks)
} }
return Object.values(chunks) return Object.values(chunks)
} }
export async function bundleRequest (viteServer: vite.ViteDevServer, entryURL: string) { export async function bundleRequest (opts: TransformOptions, entryURL: string) {
const chunks = await transformRequestRecursive(viteServer, entryURL) const chunks = await transformRequestRecursive(opts, entryURL)
const listIds = (ids: string[]) => ids.map(id => `// - ${id} (${hashId(id)})`).join('\n') const listIds = (ids: string[]) => ids.map(id => `// - ${id} (${hashId(id)})`).join('\n')
const chunksCode = chunks.map(chunk => ` const chunksCode = chunks.map(chunk => `

View File

@ -38,7 +38,11 @@ export async function buildServer (ctx: ViteBuildContext) {
], ],
noExternal: [ noExternal: [
...ctx.nuxt.options.build.transpile.filter(i => typeof i === 'string'), ...ctx.nuxt.options.build.transpile.filter(i => typeof i === 'string'),
'#app' '.vue',
'plugin-vue:',
'#app',
'nuxt3',
'@nuxt/nitro'
] ]
}, },
build: { build: {
@ -94,7 +98,7 @@ export async function buildServer (ctx: ViteBuildContext) {
// Build and watch // Build and watch
const _doBuild = async () => { const _doBuild = async () => {
const start = Date.now() const start = Date.now()
const { code } = await bundleRequest(viteServer, resolve(ctx.nuxt.options.appDir, 'entry')) const { code } = await bundleRequest({ viteServer }, resolve(ctx.nuxt.options.appDir, 'entry'))
await fse.writeFile(resolve(ctx.nuxt.options.buildDir, 'dist/server/server.mjs'), code, 'utf-8') await fse.writeFile(resolve(ctx.nuxt.options.buildDir, 'dist/server/server.mjs'), code, 'utf-8')
const time = (Date.now() - start) const time = (Date.now() - start)
consola.success(`Vite server built in ${time}ms`) consola.success(`Vite server built in ${time}ms`)

View File

@ -2791,6 +2791,7 @@ __metadata:
debounce: ^1.2.1 debounce: ^1.2.1
fs-extra: ^10.0.0 fs-extra: ^10.0.0
magic-string: ^0.25.7 magic-string: ^0.25.7
p-debounce: ^4.0.0
pathe: ^0.2.0 pathe: ^0.2.0
ufo: ^0.7.9 ufo: ^0.7.9
unbuild: latest unbuild: latest