diff --git a/packages/bridge/package.json b/packages/bridge/package.json index 1c9280b0dc..5c6dd87256 100644 --- a/packages/bridge/package.json +++ b/packages/bridge/package.json @@ -44,7 +44,7 @@ "magic-string": "^0.26.1", "mlly": "^0.5.1", "murmurhash-es": "^0.1.1", - "nitropack": "^0.1.2", + "nitropack": "^0.2.1", "node-fetch": "^3.2.3", "nuxi": "3.0.0", "ohash": "^0.1.0", diff --git a/packages/bridge/src/nitro.ts b/packages/bridge/src/nitro.ts index edc1cf3d5a..14ff640f13 100644 --- a/packages/bridge/src/nitro.ts +++ b/packages/bridge/src/nitro.ts @@ -3,7 +3,7 @@ import fetch from 'node-fetch' import fsExtra from 'fs-extra' import { addPluginTemplate, resolvePath, useNuxt } from '@nuxt/kit' import { joinURL, stringifyQuery, withoutTrailingSlash } from 'ufo' -import { resolve, join } from 'pathe' +import { resolve, join, dirname } from 'pathe' import { createNitro, createDevServer, build, writeTypes, prepare, copyPublicAssets, prerender } from 'nitropack' import { dynamicEventHandler, toEventHandler } from 'h3' import type { Nitro, NitroEventHandler, NitroDevEventHandler, NitroConfig } from 'nitropack' @@ -86,12 +86,9 @@ export async function setupNitroBridge () { crawlLinks: nuxt.options.generate.crawler, routes: nuxt.options.generate.routes }, - output: { - dir: nuxt.options.dev ? join(nuxt.options.buildDir, 'nitro') : resolve(nuxt.options.rootDir, '.output') - }, externals: { inline: [ - ...(nuxt.options.dev ? [] : [nuxt.options.buildDir]), + ...(nuxt.options.dev ? [] : ['vue', '@vue/', '@nuxt/', nuxt.options.buildDir]), '@nuxt/bridge/dist', '@nuxt/bridge-edge/dist' ] @@ -113,10 +110,16 @@ export async function setupNitroBridge () { '#nitro/error': resolve(distDir, 'runtime/nitro/error'), // Paths - '#paths': resolve(distDir, 'runtime/nitro/paths') + '#paths': resolve(distDir, 'runtime/nitro/paths'), + + // Nuxt aliases + ...nuxt.options.alias } }) + // Let nitro handle #build for windows path normalization + delete nitroConfig.alias['#build'] + // Extend nitro config with hook await nuxt.callHook('nitro:config', nitroConfig) @@ -131,15 +134,6 @@ export async function setupNitroBridge () { // Connect hooks nuxt.hook('close', () => nitro.hooks.callHook('close')) - nitro.hooks.hook('nitro:document', template => nuxt.callHook('nitro:document', template)) - - // Use custom document template if provided - if (nuxt.options.appTemplatePath) { - nuxt.hook('nitro:document', async (template) => { - template.src = nuxt.options.appTemplatePath - template.contents = await fsp.readFile(nuxt.options.appTemplatePath, 'utf-8') - }) - } async function updateViteBase () { const clientDist = resolve(nuxt.options.buildDir, 'dist/client') @@ -168,7 +162,6 @@ export async function setupNitroBridge () { } } } - nuxt.hook('nitro:generate', updateViteBase) nuxt.hook('generate:before', updateViteBase) // .ts is supported for serverMiddleware @@ -267,6 +260,7 @@ export async function setupNitroBridge () { const waitUntilCompile = new Promise(resolve => nitro.hooks.hook('nitro:compiled', () => resolve())) nuxt.hook('build:done', async () => { if (nuxt.options._prepare) { return } + await writeDocumentTemplate(nuxt) if (nuxt.options.dev) { await build(nitro) await waitUntilCompile @@ -274,13 +268,10 @@ export async function setupNitroBridge () { } else { await prepare(nitro) await copyPublicAssets(nitro) - if (nuxt.options.target === 'static') { + if (nuxt.options._generate || nuxt.options.target === 'static') { await prerender(nitro) } await build(nitro) - if (nuxt.options._generate) { - await prerender(nitro) - } } }) @@ -383,3 +374,17 @@ async function resolveHandlers (nuxt: Nuxt) { devHandlers } } + +async function writeDocumentTemplate (nuxt: Nuxt) { + // Compile html template + const src = nuxt.options.appTemplatePath || resolve(nuxt.options.buildDir, 'views/app.template.html') + const dst = src.replace(/.html$/, '.mjs').replace('app.template.mjs', 'document.template.mjs') + const contents = nuxt.vfs[src] || await fsp.readFile(src, 'utf-8').catch(() => '') + if (contents) { + const compiled = 'export default ' + + // eslint-disable-next-line no-template-curly-in-string + `(params) => \`${contents.replace(/{{ (\w+) }}/g, '${params.$1}')}\`` + await fsp.mkdir(dirname(dst), { recursive: true }) + await fsp.writeFile(dst, compiled, 'utf8') + } +} diff --git a/packages/nuxt3/package.json b/packages/nuxt3/package.json index 446cc1c543..dc57178496 100644 --- a/packages/nuxt3/package.json +++ b/packages/nuxt3/package.json @@ -50,7 +50,7 @@ "knitwork": "^0.1.1", "magic-string": "^0.26.1", "mlly": "^0.5.1", - "nitropack": "^0.1.2", + "nitropack": "^0.2.1", "nuxi": "3.0.0", "ohash": "^0.1.0", "ohmyfetch": "^0.4.15", diff --git a/packages/nuxt3/src/core/nitro.ts b/packages/nuxt3/src/core/nitro.ts index cd28fa0f9f..861d442e6b 100644 --- a/packages/nuxt3/src/core/nitro.ts +++ b/packages/nuxt3/src/core/nitro.ts @@ -1,4 +1,5 @@ -import { existsSync } from 'fs' +import { existsSync, promises as fsp } from 'fs' +import { dirname } from 'path' import { resolve, join } from 'pathe' import { createNitro, createDevServer, build, prepare, copyPublicAssets, writeTypes, scanHandlers, prerender } from 'nitropack' import type { NitroEventHandler, NitroDevEventHandler, NitroConfig } from 'nitropack' @@ -56,12 +57,9 @@ export async function initNitro (nuxt: Nuxt) { crawlLinks: nuxt.options.generate.crawler, routes: nuxt.options.generate.routes }, - output: { - dir: nuxt.options.dev ? join(nuxt.options.buildDir, 'nitro') : resolve(nuxt.options.rootDir, '.output') - }, externals: { inline: [ - ...(nuxt.options.dev ? [] : [nuxt.options.buildDir]), + ...(nuxt.options.dev ? [] : ['vue', '@vue/', '@nuxt/', nuxt.options.buildDir]), 'nuxt/dist', 'nuxt3/dist' ] @@ -87,7 +85,10 @@ export async function initNitro (nuxt: Nuxt) { '#nitro/error': resolve(distDir, 'core/runtime/nitro/error'), // Paths - '#paths': resolve(distDir, 'core/runtime/nitro/paths') + '#paths': resolve(distDir, 'core/runtime/nitro/paths'), + + // Nuxt aliases + ...nuxt.options.alias }, replace: { 'process.env.NUXT_NO_SSR': nuxt.options.ssr === false ? true : undefined @@ -108,7 +109,6 @@ export async function initNitro (nuxt: Nuxt) { // Connect hooks nuxt.hook('close', () => nitro.hooks.callHook('close')) - nitro.hooks.hook('nitro:document', template => nuxt.callHook('nitro:document', template)) // Register nuxt3 protection patterns nitro.hooks.hook('nitro:rollup:before', (nitro) => { @@ -146,15 +146,16 @@ export async function initNitro (nuxt: Nuxt) { // nuxt build/dev nuxt.hook('build:done', async () => { + await writeDocumentTemplate(nuxt) if (nuxt.options.dev) { await build(nitro) } else { await prepare(nitro) await copyPublicAssets(nitro) - await build(nitro) - if (nuxt.options._generate) { + if (nuxt.options._generate || nuxt.options.target === 'static') { await prerender(nitro) } + await build(nitro) } }) @@ -199,3 +200,17 @@ async function resolveHandlers (nuxt: Nuxt) { devHandlers } } + +async function writeDocumentTemplate (nuxt: Nuxt) { + // Compile html template + const src = resolve(nuxt.options.buildDir, 'views/app.template.html') + const dst = src.replace(/.html$/, '.mjs').replace('app.template.mjs', 'document.template.mjs') + const contents = nuxt.vfs[src] || await fsp.readFile(src, 'utf-8').catch(() => '') + if (contents) { + const compiled = 'export default ' + + // eslint-disable-next-line no-template-curly-in-string + `(params) => \`${contents.replace(/{{ (\w+) }}/g, '${params.$1}')}\`` + await fsp.mkdir(dirname(dst), { recursive: true }) + await fsp.writeFile(dst, compiled, 'utf8') + } +} diff --git a/packages/schema/src/types/hooks.ts b/packages/schema/src/types/hooks.ts index b2364b65ba..00d141ac45 100644 --- a/packages/schema/src/types/hooks.ts +++ b/packages/schema/src/types/hooks.ts @@ -101,8 +101,6 @@ export interface NuxtHooks { // nitropack 'nitro:config': (nitroConfig: NitroConfig) => HookResult 'nitro:init': (nitro: Nitro) => HookResult - 'nitro:document': (template: { src: string, contents: string }) => HookResult - 'nitro:generate': (context: any) => HookResult // @nuxt/cli 'generate:cache:ignore': (ignore: string[]) => HookResult diff --git a/packages/vite/src/server.ts b/packages/vite/src/server.ts index 8ee090b62a..18ae909345 100644 --- a/packages/vite/src/server.ts +++ b/packages/vite/src/server.ts @@ -82,7 +82,8 @@ export async function buildServer (ctx: ViteBuildContext) { await ctx.nuxt.callHook('vite:extendConfig', serverConfig, { isClient: false, isServer: true }) - ctx.nuxt.hook('nitro:generate', async () => { + // TODO: Do we still need this? + ctx.nuxt.hook('build:done', async () => { const clientDist = resolve(ctx.nuxt.options.buildDir, 'dist/client') // Remove public files that have been duplicated into buildAssetsDir diff --git a/yarn.lock b/yarn.lock index 5a6b279c8b..6c04e0ff4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2619,7 +2619,7 @@ __metadata: magic-string: ^0.26.1 mlly: ^0.5.1 murmurhash-es: ^0.1.1 - nitropack: ^0.1.2 + nitropack: ^0.2.1 node-fetch: ^3.2.3 nuxi: 3.0.0 nuxt: ^2 @@ -14658,9 +14658,9 @@ __metadata: languageName: node linkType: hard -"nitropack@npm:^0.1.2": - version: 0.1.2 - resolution: "nitropack@npm:0.1.2" +"nitropack@npm:^0.2.1": + version: 0.2.1 + resolution: "nitropack@npm:0.2.1" dependencies: "@cloudflare/kv-asset-handler": ^0.2.0 "@netlify/functions": ^1.0.0 @@ -14726,7 +14726,7 @@ __metadata: bin: nitro: dist/cli.mjs nitropack: dist/cli.mjs - checksum: 81836ce9a4b04c78e21f799e92eaec99c4c609dca2a541859d6d444f3123f3866ae684e4ac34849260108eb961b5aa76bf9db96a36f1a7c6930f40d07c4f7704 + checksum: 995a4a3dc7bb311417a95549aed42b2a1e47b686713b5500971985aede751e6f597203d7246b412208e84280339debf17d6f883f1e19fe17b74a98e9f3153baf languageName: node linkType: hard @@ -15409,7 +15409,7 @@ __metadata: knitwork: ^0.1.1 magic-string: ^0.26.1 mlly: ^0.5.1 - nitropack: ^0.1.2 + nitropack: ^0.2.1 nuxi: 3.0.0 ohash: ^0.1.0 ohmyfetch: ^0.4.15