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