From 011a93aaca57ef266844e16bdcd01fe9a779f7ff Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Wed, 2 Jul 2025 12:32:42 +0100 Subject: [PATCH 1/3] perf(dev): use `exsolve` to resolve + import legacy loading template --- packages/nuxi/src/commands/dev.ts | 24 ++++++++---------------- packages/nuxi/src/commands/info.ts | 2 +- packages/nuxi/src/dev/utils.ts | 25 ++++++++++++++----------- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/packages/nuxi/src/commands/dev.ts b/packages/nuxi/src/commands/dev.ts index 3dfed828e..50fab8717 100644 --- a/packages/nuxi/src/commands/dev.ts +++ b/packages/nuxi/src/commands/dev.ts @@ -20,6 +20,7 @@ import { isBun, isTest } from 'std-env' import { initialize } from '../dev' import { renderError } from '../dev/error' import { isSocketURL, parseSocketURL } from '../dev/socket' +import { resolveLoadingTemplate } from '../dev/utils' import { showVersions } from '../utils/banner' import { overrideEnv } from '../utils/env' import { loadKit } from '../utils/kit' @@ -128,7 +129,7 @@ const command = defineCommand({ } // Start proxy Listener - const devProxy = await createDevProxy(nuxtOptions, listenOptions) + const devProxy = await createDevProxy(cwd, nuxtOptions, listenOptions) const useSocket = nuxtOptions._majorVersion === 4 || !!process.env.NUXT_SOCKET @@ -182,7 +183,7 @@ type ArgsT = Exclude< type DevProxy = Awaited> -async function createDevProxy(nuxtOptions: NuxtOptions, listenOptions: Partial) { +async function createDevProxy(cwd: string, nuxtOptions: NuxtOptions, listenOptions: Partial) { let loadingMessage = 'Nuxt dev server is starting...' let error: Error | undefined let address: string | undefined @@ -218,26 +219,17 @@ async function createDevProxy(nuxtOptions: NuxtOptions, listenOptions: Partial string }>('@nuxt/ui-templates', { - parentURL: url, - try: true, - }) - if (r) { - loadingTemplate = r.loading - res.end(r.loading({ loading: loadingMessage })) - break - } - } + loadingTemplate = await resolveLoadingTemplate(cwd) + res.end(loadingTemplate({ loading: loadingMessage })) } return resolveLoadingMessage() } diff --git a/packages/nuxi/src/commands/info.ts b/packages/nuxi/src/commands/info.ts index 86cfb6d12..604dc9e5d 100644 --- a/packages/nuxi/src/commands/info.ts +++ b/packages/nuxi/src/commands/info.ts @@ -6,7 +6,6 @@ import process from 'node:process' import { defineCommand } from 'citty' import clipboardy from 'clipboardy' -import { createJiti } from 'jiti' import { detectPackageManager } from 'nypm' import { resolve } from 'pathe' import { readPackageJSON } from 'pkg-types' @@ -168,6 +167,7 @@ function normalizeConfigModule( async function getNuxtConfig(rootDir: string) { try { + const { createJiti } = await import('jiti') const jiti = createJiti(rootDir, { interopDefault: true, // allow using `~` and `@` in `nuxt.config` diff --git a/packages/nuxi/src/dev/utils.ts b/packages/nuxi/src/dev/utils.ts index 861673446..cf2e09a5d 100644 --- a/packages/nuxi/src/dev/utils.ts +++ b/packages/nuxi/src/dev/utils.ts @@ -9,16 +9,18 @@ import type { AddressInfo } from 'node:net' import EventEmitter from 'node:events' import { existsSync, watch } from 'node:fs' import { mkdir } from 'node:fs/promises' - import process from 'node:process' +import { pathToFileURL } from 'node:url' + import defu from 'defu' +import { resolveModulePath } from 'exsolve' import { toNodeListener } from 'h3' import { listen } from 'listhen' import { resolve } from 'pathe' import { debounce } from 'perfect-debounce' import { provider } from 'std-env' - import { joinURL } from 'ufo' + import { clearBuildDir } from '../utils/fs' import { loadKit } from '../utils/kit' @@ -162,20 +164,12 @@ export class NuxtDevServer extends EventEmitter { renderError(req, res, this._loadingError) } - async resolveLoadingTemplate() { - const { createJiti } = await import('jiti') - const jiti = createJiti(this.cwd) - const loading = await jiti.import<{ loading: () => string }>('@nuxt/ui-templates').then(r => r.loading).catch(() => {}) - - return loading || ((params: { loading: string }) => `

${params.loading}

`) - } - async _renderLoadingScreen(req: IncomingMessage, res: ServerResponse) { res.statusCode = 503 res.setHeader('Content-Type', 'text/html') const loadingTemplate = this.options.loadingTemplate || this._currentNuxt?.options.devServer.loadingTemplate - || await this.resolveLoadingTemplate() + || await resolveLoadingTemplate(this.cwd) res.end( loadingTemplate({ loading: this._loadingMessage || 'Loading...', @@ -434,3 +428,12 @@ function createConfigDirWatcher(cwd: string, onReload: (file: string) => void) { return () => configDirWatcher.close() } + +// Nuxt <3.7 did not have the loading template defined in the schema +export async function resolveLoadingTemplate(cwd: string) { + const nuxtPath = resolveModulePath('nuxt', { from: cwd, try: true }) + const uiTemplatesPath = resolveModulePath('@nuxt/ui-templates', { from: nuxtPath || cwd }) + const r: { loading: (opts?: { loading?: string }) => string } = await import(pathToFileURL(uiTemplatesPath).href) + + return r.loading || ((params: { loading: string }) => `

${params.loading}

`) +} From a730fd426c6b53829db90c3487363169970c3554 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Wed, 2 Jul 2025 12:36:36 +0100 Subject: [PATCH 2/3] chore: remove refresh header --- packages/nuxi/src/commands/dev.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/nuxi/src/commands/dev.ts b/packages/nuxi/src/commands/dev.ts index 50fab8717..beebf2857 100644 --- a/packages/nuxi/src/commands/dev.ts +++ b/packages/nuxi/src/commands/dev.ts @@ -220,7 +220,6 @@ async function createDevProxy(cwd: string, nuxtOptions: NuxtOptions, listenOptio res.statusCode = 503 res.setHeader('Content-Type', 'text/html') res.setHeader('Cache-Control', 'no-store') - res.setHeader('Refresh', '3') if (loadingTemplate) { res.end(loadingTemplate({ loading: loadingMessage })) return From 9ce7c691cd1c4de6e5a30c1dba60e1aba0bc01a7 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Wed, 2 Jul 2025 12:40:39 +0100 Subject: [PATCH 3/3] chore: update comment --- packages/nuxi/src/commands/dev.ts | 2 +- packages/nuxi/src/dev/utils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nuxi/src/commands/dev.ts b/packages/nuxi/src/commands/dev.ts index beebf2857..b518bb82d 100644 --- a/packages/nuxi/src/commands/dev.ts +++ b/packages/nuxi/src/commands/dev.ts @@ -225,7 +225,7 @@ async function createDevProxy(cwd: string, nuxtOptions: NuxtOptions, listenOptio return } - // Nuxt <3.7 did not have the loading template defined in the schema + // Nuxt <3.6 did not have the loading template defined in the schema async function resolveLoadingMessage() { loadingTemplate = await resolveLoadingTemplate(cwd) res.end(loadingTemplate({ loading: loadingMessage })) diff --git a/packages/nuxi/src/dev/utils.ts b/packages/nuxi/src/dev/utils.ts index cf2e09a5d..1eb61d98f 100644 --- a/packages/nuxi/src/dev/utils.ts +++ b/packages/nuxi/src/dev/utils.ts @@ -429,7 +429,7 @@ function createConfigDirWatcher(cwd: string, onReload: (file: string) => void) { return () => configDirWatcher.close() } -// Nuxt <3.7 did not have the loading template defined in the schema +// Nuxt <3.6 did not have the loading template defined in the schema export async function resolveLoadingTemplate(cwd: string) { const nuxtPath = resolveModulePath('nuxt', { from: cwd, try: true }) const uiTemplatesPath = resolveModulePath('@nuxt/ui-templates', { from: nuxtPath || cwd })