mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 07:05:11 +00:00
fix(nuxt): pass joinRelativeURL
+ share paths on server (#26407)
This commit is contained in:
parent
4647d2f925
commit
8c3159f4ba
@ -6,7 +6,7 @@ import { useRuntimeConfig } from '../nuxt'
|
||||
// @ts-expect-error virtual file
|
||||
import { appManifest as isAppManifestEnabled } from '#build/nuxt.config.mjs'
|
||||
// @ts-expect-error virtual file
|
||||
import { buildAssetsURL } from '#build/paths.mjs'
|
||||
import { buildAssetsURL } from '#internal/nuxt/paths'
|
||||
|
||||
export interface NuxtAppManifestMeta {
|
||||
id: string
|
||||
|
@ -1,10 +1,7 @@
|
||||
import { createApp, createSSRApp, nextTick } from 'vue'
|
||||
import type { App } from 'vue'
|
||||
|
||||
// These files must be imported first as they have side effects:
|
||||
// 1. (we set __webpack_public_path via this import, if using webpack builder)
|
||||
import '#build/paths.mjs'
|
||||
// 2. we set globalThis.$fetch via this import
|
||||
// This file must be imported first as we set globalThis.$fetch via this import
|
||||
import '#build/fetch.mjs'
|
||||
|
||||
import { applyPlugins, createNuxtApp } from './nuxt'
|
||||
|
@ -3,7 +3,7 @@ import { getAppManifest } from '../composables/manifest'
|
||||
import type { NuxtAppManifestMeta } from '../composables/manifest'
|
||||
import { onNuxtReady } from '../composables/ready'
|
||||
// @ts-expect-error virtual file
|
||||
import { buildAssetsURL } from '#build/paths.mjs'
|
||||
import { buildAssetsURL } from '#internal/nuxt/paths'
|
||||
|
||||
export default defineNuxtPlugin((nuxtApp) => {
|
||||
if (import.meta.test) { return }
|
||||
|
@ -206,7 +206,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) {
|
||||
'@vue/devtools-api': 'vue-devtools-stub',
|
||||
|
||||
// Paths
|
||||
'#paths': resolve(distDir, 'core/runtime/nitro/paths'),
|
||||
'#internal/nuxt/paths': resolve(distDir, 'core/runtime/nitro/paths'),
|
||||
|
||||
// Nuxt aliases
|
||||
...nuxt.options.alias
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { joinURL } from 'ufo'
|
||||
import { joinRelativeURL } from 'ufo'
|
||||
import { useRuntimeConfig } from '#internal/nitro'
|
||||
|
||||
export function baseURL (): string {
|
||||
@ -12,12 +12,12 @@ export function buildAssetsDir (): string {
|
||||
}
|
||||
|
||||
export function buildAssetsURL (...path: string[]): string {
|
||||
return joinURL(publicAssetsURL(), buildAssetsDir(), ...path)
|
||||
return joinRelativeURL(publicAssetsURL(), buildAssetsDir(), ...path)
|
||||
}
|
||||
|
||||
export function publicAssetsURL (...path: string[]): string {
|
||||
// TODO: support passing event to `useRuntimeConfig`
|
||||
const app = useRuntimeConfig().app
|
||||
const publicBase = app.cdnURL as string || app.baseURL
|
||||
return path.length ? joinURL(publicBase, ...path) : publicBase
|
||||
return path.length ? joinRelativeURL(publicBase, ...path) : publicBase
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ import type { NuxtPayload, NuxtSSRContext } from '#app'
|
||||
// @ts-expect-error virtual file
|
||||
import { appHead, appRootId, appRootTag, appTeleportId, appTeleportTag, componentIslands } from '#internal/nuxt.config.mjs'
|
||||
// @ts-expect-error virtual file
|
||||
import { buildAssetsURL, publicAssetsURL } from '#paths'
|
||||
import { buildAssetsURL, publicAssetsURL } from '#internal/nuxt/paths'
|
||||
|
||||
// @ts-expect-error private property consumed by vite-generated url helpers
|
||||
globalThis.__buildAssetsURL = buildAssetsURL
|
||||
|
@ -327,7 +327,7 @@ export const publicPathTemplate: NuxtTemplate = {
|
||||
filename: 'paths.mjs',
|
||||
getContents ({ nuxt }) {
|
||||
return [
|
||||
'import { joinRelativeURL as joinURL } from \'ufo\'',
|
||||
'import { joinRelativeURL } from \'ufo\'',
|
||||
!nuxt.options.dev && 'import { useRuntimeConfig } from \'#internal/nitro\'',
|
||||
|
||||
nuxt.options.dev
|
||||
@ -337,11 +337,11 @@ export const publicPathTemplate: NuxtTemplate = {
|
||||
'export const baseURL = () => appConfig.baseURL',
|
||||
'export const buildAssetsDir = () => appConfig.buildAssetsDir',
|
||||
|
||||
'export const buildAssetsURL = (...path) => joinURL(publicAssetsURL(), buildAssetsDir(), ...path)',
|
||||
'export const buildAssetsURL = (...path) => joinRelativeURL(publicAssetsURL(), buildAssetsDir(), ...path)',
|
||||
|
||||
'export const publicAssetsURL = (...path) => {',
|
||||
' const publicBase = appConfig.cdnURL || appConfig.baseURL',
|
||||
' return path.length ? joinURL(publicBase, ...path) : publicBase',
|
||||
' return path.length ? joinRelativeURL(publicBase, ...path) : publicBase',
|
||||
'}',
|
||||
|
||||
// On server these are registered directly in packages/nuxt/src/core/runtime/nitro/renderer.ts
|
||||
@ -358,7 +358,7 @@ export const dollarFetchTemplate: NuxtTemplate = {
|
||||
getContents () {
|
||||
return [
|
||||
'import { $fetch } from \'ofetch\'',
|
||||
"import { baseURL } from '#build/paths.mjs'",
|
||||
"import { baseURL } from '#internal/nuxt/paths'",
|
||||
'if (!globalThis.$fetch) {',
|
||||
' globalThis.$fetch = $fetch.create({',
|
||||
' baseURL: baseURL()',
|
||||
|
@ -68,6 +68,7 @@ export async function buildClient (ctx: ViteBuildContext) {
|
||||
alias: {
|
||||
...nodeCompat.alias,
|
||||
...ctx.config.resolve?.alias,
|
||||
'#internal/nuxt/paths': resolve(ctx.nuxt.options.buildDir, 'paths.mjs'),
|
||||
'#build/plugins': resolve(ctx.nuxt.options.buildDir, 'plugins/client'),
|
||||
'#internal/nitro': resolve(ctx.nuxt.options.buildDir, 'nitro.client.mjs')
|
||||
},
|
||||
|
@ -27,8 +27,8 @@ export function runtimePathsPlugin (options: RuntimePathsOptions): Plugin {
|
||||
|
||||
if (VITE_ASSET_RE.test(code)) {
|
||||
const s = new MagicString(code)
|
||||
// Register dependency on paths.mjs, which sets globalThis.__publicAssetsURL
|
||||
s.prepend('import "#build/paths.mjs";')
|
||||
// Register dependency on #build/paths.mjs or #internal/nuxt/paths.mjs, which sets globalThis.__publicAssetsURL
|
||||
s.prepend('import "#internal/nuxt/paths";')
|
||||
|
||||
return {
|
||||
code: s.toString(),
|
||||
|
@ -26,7 +26,7 @@ export const VitePublicDirsPlugin = createUnplugin(() => {
|
||||
enforce: 'pre',
|
||||
handler (id) {
|
||||
if (id.startsWith(PREFIX)) {
|
||||
return `import { publicAssetsURL } from '#build/paths.mjs';export default publicAssetsURL(${JSON.stringify(decodeURIComponent(id.slice(PREFIX.length)))})`
|
||||
return `import { publicAssetsURL } from '#internal/nuxt/paths';export default publicAssetsURL(${JSON.stringify(decodeURIComponent(id.slice(PREFIX.length)))})`
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -55,6 +55,7 @@ export async function buildServer (ctx: ViteBuildContext) {
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'#internal/nuxt/paths': resolve(ctx.nuxt.options.buildDir, 'paths.mjs'),
|
||||
'#build/plugins': resolve(ctx.nuxt.options.buildDir, 'plugins/server')
|
||||
}
|
||||
},
|
||||
@ -79,7 +80,7 @@ export async function buildServer (ctx: ViteBuildContext) {
|
||||
ssr: true,
|
||||
rollupOptions: {
|
||||
input: { server: entry },
|
||||
external: ['#internal/nitro'],
|
||||
external: ['#internal/nitro', '#internal/nuxt/paths'],
|
||||
output: {
|
||||
entryFileNames: '[name].mjs',
|
||||
format: 'module',
|
||||
@ -105,12 +106,14 @@ export async function buildServer (ctx: ViteBuildContext) {
|
||||
if (!ctx.nuxt.options.dev) {
|
||||
const nitroDependencies = await tryResolveModule('nitropack/package.json', ctx.nuxt.options.modulesDir)
|
||||
.then(r => import(r!)).then(r => Object.keys(r.dependencies || {})).catch(() => [])
|
||||
;(serverConfig.ssr!.external as string[])!.push(
|
||||
// explicit dependencies we use in our ssr renderer - these can be inlined (if necessary) in the nitro build
|
||||
'unhead', '@unhead/ssr', 'unctx', 'h3', 'devalue', '@nuxt/devalue', 'radix3', 'unstorage', 'hookable',
|
||||
// dependencies we might share with nitro - these can be inlined (if necessary) in the nitro build
|
||||
...nitroDependencies
|
||||
)
|
||||
if (Array.isArray(serverConfig.ssr!.external)) {
|
||||
serverConfig.ssr!.external.push(
|
||||
// explicit dependencies we use in our ssr renderer - these can be inlined (if necessary) in the nitro build
|
||||
'unhead', '@unhead/ssr', 'unctx', 'h3', 'devalue', '@nuxt/devalue', 'radix3', 'unstorage', 'hookable',
|
||||
// dependencies we might share with nitro - these can be inlined (if necessary) in the nitro build
|
||||
...nitroDependencies
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
serverConfig.customLogger = createViteLogger(serverConfig)
|
||||
|
@ -54,6 +54,9 @@ function serverStandalone (ctx: WebpackConfigContext) {
|
||||
...ctx.options.build.transpile
|
||||
]
|
||||
const external = ['#internal/nitro']
|
||||
if (!ctx.nuxt.options.dev) {
|
||||
external.push('#internal/nuxt/paths')
|
||||
}
|
||||
|
||||
if (!Array.isArray(ctx.config.externals)) { return }
|
||||
ctx.config.externals.push(({ request }, cb) => {
|
||||
|
@ -11,17 +11,17 @@ const defaults: DynamicBasePluginOptions = {
|
||||
sourcemap: true
|
||||
}
|
||||
|
||||
const ENTRY_RE = /import ["']#build\/css["'];/
|
||||
|
||||
export const DynamicBasePlugin = createUnplugin((options: DynamicBasePluginOptions = {}) => {
|
||||
options = { ...defaults, ...options }
|
||||
return {
|
||||
name: 'nuxt:dynamic-base-path',
|
||||
enforce: 'post',
|
||||
enforce: 'post' as const,
|
||||
transform (code, id) {
|
||||
if (!id.includes('paths.mjs') || !code.includes('const appConfig = ')) {
|
||||
return
|
||||
}
|
||||
if (!id.includes('entry') || !ENTRY_RE.test(code)) { return }
|
||||
const s = new MagicString(code)
|
||||
s.append(`\n${options.globalPublicPath} = buildAssetsURL();\n`)
|
||||
s.prepend(`import { buildAssetsURL } from '#internal/nuxt/paths';\n${options.globalPublicPath} = buildAssetsURL();\n`)
|
||||
return {
|
||||
code: s.toString(),
|
||||
map: options.sourcemap
|
||||
|
@ -120,6 +120,7 @@ function baseAlias (ctx: WebpackConfigContext) {
|
||||
'#app': ctx.options.appDir,
|
||||
'#build/plugins': resolve(ctx.options.buildDir, 'plugins', ctx.isClient ? 'client' : 'server'),
|
||||
'#build': ctx.options.buildDir,
|
||||
'#internal/nuxt/paths': resolve(ctx.nuxt.options.buildDir, 'paths.mjs'),
|
||||
...ctx.options.alias,
|
||||
...ctx.alias
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
||||
const serverDir = join(rootDir, '.output/server')
|
||||
|
||||
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"206k"')
|
||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"207k"')
|
||||
|
||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"1336k"')
|
||||
@ -72,7 +72,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
||||
const serverDir = join(rootDir, '.output-inline/server')
|
||||
|
||||
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"525k"')
|
||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot('"526k"')
|
||||
|
||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot('"77.8k"')
|
||||
|
@ -8,7 +8,7 @@ export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
'#build/nuxt.config.mjs': resolve('./test/mocks/nuxt-config'),
|
||||
'#build/paths.mjs': resolve('./test/mocks/paths'),
|
||||
'#internal/nuxt/paths': resolve('./test/mocks/paths'),
|
||||
'#build/app.config.mjs': resolve('./test/mocks/app-config'),
|
||||
'#app': resolve('./packages/nuxt/dist/app')
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user