From e531b65a32048ddcc76c3c8e2b26b8f285d70e35 Mon Sep 17 00:00:00 2001 From: pooya parsa Date: Tue, 12 Oct 2021 03:38:30 +0200 Subject: [PATCH] fix(vite): improve external handling (#729) --- packages/vite/package.json | 1 + packages/vite/src/dev-bundler.ts | 51 +++++++++++++++++++++++++------- packages/vite/src/server.ts | 8 +++-- yarn.lock | 1 + 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/packages/vite/package.json b/packages/vite/package.json index 736cb8103a..45b3cdc528 100644 --- a/packages/vite/package.json +++ b/packages/vite/package.json @@ -24,6 +24,7 @@ "debounce": "^1.2.1", "fs-extra": "^10.0.0", "magic-string": "^0.25.7", + "p-debounce": "^4.0.0", "pathe": "^0.2.0", "ufo": "^0.7.9", "vite": "^2.6.7", diff --git a/packages/vite/src/dev-bundler.ts b/packages/vite/src/dev-bundler.ts index 0a6c63b9c1..93e0cd4f8b 100644 --- a/packages/vite/src/dev-bundler.ts +++ b/packages/vite/src/dev-bundler.ts @@ -1,22 +1,45 @@ import { builtinModules } from 'module' +import { join } from 'pathe' import * as vite from 'vite' import { hashId, uniq } from './utils' -interface TransformChunk { +export interface TransformChunk { id: string, code: string, deps: string[], parents: string[] } -interface SSRTransformResult { +export interface SSRTransformResult { code: string, map: object, deps: 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` if (id && id.startsWith('/@id/__x00__')) { id = '\0' + id.slice('/@id/__x00__'.length) @@ -24,18 +47,24 @@ async function transformRequest (viteServer: vite.ViteDevServer, id) { if (id && id.startsWith('/@id/')) { 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 - if (builtinModules.includes(id) || id.includes('node_modules')) { + if (isExternal(opts, id)) { 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: [], dynamicDeps: [] } } // 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 console.warn(`[SSR] Error transforming ${id}: ${err}`) // console.error(err) @@ -48,12 +77,12 @@ ${res.code || '/* empty */'}; return { code, deps: res.deps || [], dynamicDeps: res.dynamicDeps || [] } } -async function transformRequestRecursive (viteServer: vite.ViteDevServer, id, parent = '', chunks: Record = {}) { +async function transformRequestRecursive (opts: TransformOptions, id, parent = '', chunks: Record = {}) { if (chunks[id]) { chunks[id].parents.push(parent) return } - const res = await transformRequest(viteServer, id) + const res = await transformRequest(opts, id) const deps = uniq([...res.deps, ...res.dynamicDeps]) chunks[id] = { @@ -63,13 +92,13 @@ async function transformRequestRecursive (viteServer: vite.ViteDevServer, id, pa parents: [parent] } as TransformChunk for (const dep of deps) { - await transformRequestRecursive(viteServer, dep, id, chunks) + await transformRequestRecursive(opts, dep, id, chunks) } return Object.values(chunks) } -export async function bundleRequest (viteServer: vite.ViteDevServer, entryURL: string) { - const chunks = await transformRequestRecursive(viteServer, entryURL) +export async function bundleRequest (opts: TransformOptions, entryURL: string) { + const chunks = await transformRequestRecursive(opts, entryURL) const listIds = (ids: string[]) => ids.map(id => `// - ${id} (${hashId(id)})`).join('\n') const chunksCode = chunks.map(chunk => ` diff --git a/packages/vite/src/server.ts b/packages/vite/src/server.ts index 9ddc4ba029..c77b093de6 100644 --- a/packages/vite/src/server.ts +++ b/packages/vite/src/server.ts @@ -38,7 +38,11 @@ export async function buildServer (ctx: ViteBuildContext) { ], noExternal: [ ...ctx.nuxt.options.build.transpile.filter(i => typeof i === 'string'), - '#app' + '.vue', + 'plugin-vue:', + '#app', + 'nuxt3', + '@nuxt/nitro' ] }, build: { @@ -94,7 +98,7 @@ export async function buildServer (ctx: ViteBuildContext) { // Build and watch const _doBuild = async () => { 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') const time = (Date.now() - start) consola.success(`Vite server built in ${time}ms`) diff --git a/yarn.lock b/yarn.lock index 44e794adb7..4924ddbd32 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2791,6 +2791,7 @@ __metadata: debounce: ^1.2.1 fs-extra: ^10.0.0 magic-string: ^0.25.7 + p-debounce: ^4.0.0 pathe: ^0.2.0 ufo: ^0.7.9 unbuild: latest