mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-21 21:25:11 +00:00
fix(nuxt, vite): do not use cjs utils to resolve/alias vue (#21837)
This commit is contained in:
parent
1cc22aa4aa
commit
e023c06353
1
.gitignore
vendored
1
.gitignore
vendored
@ -23,6 +23,7 @@ dist
|
||||
.vercel
|
||||
.netlify
|
||||
.output
|
||||
.output-*
|
||||
.gen
|
||||
|
||||
# Junit reports
|
||||
|
@ -2,7 +2,7 @@ import { existsSync, promises as fsp, readFileSync } from 'node:fs'
|
||||
import { join, relative, resolve } from 'pathe'
|
||||
import { build, copyPublicAssets, createDevServer, createNitro, prepare, prerender, scanHandlers, writeTypes } from 'nitropack'
|
||||
import type { Nitro, NitroConfig } from 'nitropack'
|
||||
import { logger, resolvePath } from '@nuxt/kit'
|
||||
import { logger } from '@nuxt/kit'
|
||||
import escapeRE from 'escape-string-regexp'
|
||||
import { defu } from 'defu'
|
||||
import fsExtra from 'fs-extra'
|
||||
@ -165,13 +165,6 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
|
||||
]
|
||||
},
|
||||
alias: {
|
||||
...nuxt.options.experimental.externalVue
|
||||
? {}
|
||||
: {
|
||||
'vue/compiler-sfc': 'vue/compiler-sfc',
|
||||
'vue/server-renderer': 'vue/server-renderer',
|
||||
vue: await resolvePath(`vue/dist/vue.cjs${nuxt.options.dev ? '' : '.prod'}.js`)
|
||||
},
|
||||
// Vue 3 mocks
|
||||
...nuxt.options.vue.runtimeCompiler || nuxt.options.experimental.externalVue
|
||||
? {}
|
||||
|
@ -58,7 +58,6 @@ export async function buildClient (ctx: ViteBuildContext) {
|
||||
// runtime compiler
|
||||
'@vue/compiler-sfc', '@vue/compiler-dom', '@vue/compiler-core', '@vue/compiler-ssr'
|
||||
]
|
||||
|
||||
},
|
||||
cacheDir: resolve(ctx.nuxt.options.rootDir, 'node_modules/.cache/vite', 'client'),
|
||||
build: {
|
||||
|
@ -2,7 +2,7 @@ import { resolve } from 'pathe'
|
||||
import * as vite from 'vite'
|
||||
import vuePlugin from '@vitejs/plugin-vue'
|
||||
import viteJsxPlugin from '@vitejs/plugin-vue-jsx'
|
||||
import { logger, resolveModule, resolvePath } from '@nuxt/kit'
|
||||
import { logger, resolvePath } from '@nuxt/kit'
|
||||
import { joinURL, withTrailingSlash, withoutLeadingSlash } from 'ufo'
|
||||
import type { ViteConfig } from '@nuxt/schema'
|
||||
import type { ViteBuildContext } from './vite'
|
||||
@ -13,7 +13,6 @@ import { writeManifest } from './manifest'
|
||||
import { transpile } from './utils/transpile'
|
||||
|
||||
export async function buildServer (ctx: ViteBuildContext) {
|
||||
const _resolve = (id: string) => resolveModule(id, { paths: ctx.nuxt.options.modulesDir })
|
||||
const helper = ctx.nuxt.options.nitro.imports !== false ? '' : 'globalThis.'
|
||||
const entry = ctx.nuxt.options.ssr ? ctx.entry : await resolvePath(resolve(ctx.nuxt.options.appDir, 'entry-spa'))
|
||||
const serverConfig: ViteConfig = vite.mergeConfig(ctx.config, {
|
||||
@ -53,23 +52,11 @@ export async function buildServer (ctx: ViteBuildContext) {
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'#build/plugins': resolve(ctx.nuxt.options.buildDir, 'plugins/server'),
|
||||
...ctx.nuxt.options.experimental.externalVue || ctx.nuxt.options.dev
|
||||
? {}
|
||||
: {
|
||||
'@vue/reactivity': _resolve(`@vue/reactivity/dist/reactivity.cjs${ctx.nuxt.options.dev ? '' : '.prod'}.js`),
|
||||
'@vue/shared': _resolve(`@vue/shared/dist/shared.cjs${ctx.nuxt.options.dev ? '' : '.prod'}.js`),
|
||||
'vue-router': _resolve(`vue-router/dist/vue-router.cjs${ctx.nuxt.options.dev ? '' : '.prod'}.js`),
|
||||
'vue/server-renderer': _resolve('vue/server-renderer'),
|
||||
'vue/compiler-sfc': _resolve('vue/compiler-sfc'),
|
||||
vue: _resolve(`vue/dist/vue.cjs${ctx.nuxt.options.dev ? '' : '.prod'}.js`)
|
||||
}
|
||||
'#build/plugins': resolve(ctx.nuxt.options.buildDir, 'plugins/server')
|
||||
}
|
||||
},
|
||||
ssr: {
|
||||
external: ctx.nuxt.options.experimental.externalVue
|
||||
? ['#internal/nitro', '#internal/nitro/utils', 'vue', 'vue-router']
|
||||
: ['#internal/nitro', '#internal/nitro/utils'],
|
||||
external: ['#internal/nitro', '#internal/nitro/utils'],
|
||||
noExternal: [
|
||||
...transpile({ isServer: true, isDev: ctx.nuxt.options.dev }),
|
||||
// TODO: Use externality for production (rollup) build
|
||||
@ -88,7 +75,7 @@ export async function buildServer (ctx: ViteBuildContext) {
|
||||
ssr: true,
|
||||
rollupOptions: {
|
||||
input: { server: entry },
|
||||
external: ['#internal/nitro', ...ctx.nuxt.options.experimental.externalVue ? ['vue', 'vue-router'] : []],
|
||||
external: ['#internal/nitro'],
|
||||
output: {
|
||||
entryFileNames: '[name].mjs',
|
||||
format: 'module',
|
||||
|
@ -1,41 +1,38 @@
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import fsp from 'node:fs/promises'
|
||||
import { afterAll, beforeAll, describe, expect, it } from 'vitest'
|
||||
import { beforeAll, describe, expect, it } from 'vitest'
|
||||
import { execaCommand } from 'execa'
|
||||
import { globby } from 'globby'
|
||||
import { join } from 'pathe'
|
||||
|
||||
describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM_CI)('minimal nuxt application', () => {
|
||||
const rootDir = fileURLToPath(new URL('./fixtures/minimal', import.meta.url))
|
||||
const publicDir = join(rootDir, '.output/public')
|
||||
const serverDir = join(rootDir, '.output/server')
|
||||
|
||||
const stats = {
|
||||
client: { totalBytes: 0, files: [] as string[] },
|
||||
server: { totalBytes: 0, files: [] as string[] }
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
await execaCommand(`pnpm nuxi build ${rootDir}`)
|
||||
await Promise.all([
|
||||
execaCommand(`pnpm nuxi build ${rootDir}`, { env: { EXTERNAL_VUE: 'false' } }),
|
||||
execaCommand(`pnpm nuxi build ${rootDir}`, { env: { EXTERNAL_VUE: 'true' } })
|
||||
])
|
||||
}, 120 * 1000)
|
||||
|
||||
afterAll(async () => {
|
||||
await fsp.writeFile(join(rootDir, '.output/test-stats.json'), JSON.stringify(stats, null, 2))
|
||||
})
|
||||
|
||||
it('default client bundle size', async () => {
|
||||
stats.client = await analyzeSizes('**/*.js', publicDir)
|
||||
expect.soft(roundToKilobytes(stats.client.totalBytes)).toMatchInlineSnapshot('"97.2k"')
|
||||
expect(stats.client.files.map(f => f.replace(/\..*\.js/, '.js'))).toMatchInlineSnapshot(`
|
||||
[
|
||||
"_nuxt/entry.js",
|
||||
]
|
||||
`)
|
||||
})
|
||||
// Identical behaviour between inline/external vue options as this should only affect the server build
|
||||
for (const outputDir of ['.output', '.output-inline']) {
|
||||
it('default client bundle size', async () => {
|
||||
const clientStats = await analyzeSizes('**/*.js', join(rootDir, outputDir, 'public'))
|
||||
expect.soft(roundToKilobytes(clientStats.totalBytes)).toMatchInlineSnapshot('"97.2k"')
|
||||
expect(clientStats.files.map(f => f.replace(/\..*\.js/, '.js'))).toMatchInlineSnapshot(`
|
||||
[
|
||||
"_nuxt/entry.js",
|
||||
]
|
||||
`)
|
||||
})
|
||||
}
|
||||
|
||||
it('default server bundle size', async () => {
|
||||
stats.server = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||
expect.soft(roundToKilobytes(stats.server.totalBytes)).toMatchInlineSnapshot('"63.9k"')
|
||||
const serverDir = join(rootDir, '.output/server')
|
||||
|
||||
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"63.9k"')
|
||||
|
||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"2329k"')
|
||||
@ -90,6 +87,53 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
||||
]
|
||||
`)
|
||||
})
|
||||
|
||||
it('default server bundle size (inlined vue modules)', async () => {
|
||||
const serverDir = join(rootDir, '.output-inline/server')
|
||||
|
||||
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"370k"')
|
||||
|
||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"590k"')
|
||||
|
||||
const packages = modules.files
|
||||
.filter(m => m.endsWith('package.json'))
|
||||
.map(m => m.replace('/package.json', '').replace('node_modules/', ''))
|
||||
.sort()
|
||||
expect(packages).toMatchInlineSnapshot(`
|
||||
[
|
||||
"@unhead/dom",
|
||||
"@unhead/shared",
|
||||
"@unhead/ssr",
|
||||
"cookie-es",
|
||||
"debug",
|
||||
"defu",
|
||||
"destr",
|
||||
"devalue",
|
||||
"h3",
|
||||
"has-flag",
|
||||
"hookable",
|
||||
"http-graceful-shutdown",
|
||||
"iron-webcrypto",
|
||||
"klona",
|
||||
"ms",
|
||||
"node-fetch-native",
|
||||
"ofetch",
|
||||
"ohash",
|
||||
"pathe",
|
||||
"radix3",
|
||||
"scule",
|
||||
"supports-color",
|
||||
"ufo",
|
||||
"uncrypto",
|
||||
"unctx",
|
||||
"unenv",
|
||||
"unhead",
|
||||
"unstorage",
|
||||
]
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
async function analyzeSizes (pattern: string | string[], rootDir: string) {
|
||||
|
11
test/fixtures/minimal/nuxt.config.ts
vendored
11
test/fixtures/minimal/nuxt.config.ts
vendored
@ -1,3 +1,14 @@
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const testWithInlineVue = process.env.EXTERNAL_VUE === 'false'
|
||||
|
||||
export default defineNuxtConfig({
|
||||
experimental: {
|
||||
externalVue: !testWithInlineVue
|
||||
},
|
||||
buildDir: testWithInlineVue ? '.nuxt-inline' : '.nuxt',
|
||||
nitro: {
|
||||
output: { dir: fileURLToPath(new URL(testWithInlineVue ? './.output-inline' : './.output', import.meta.url)) }
|
||||
},
|
||||
sourcemap: false
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user