From d7946f92ac6fc51d10d07db59825e4907e9a09e5 Mon Sep 17 00:00:00 2001 From: Julien Huang Date: Wed, 8 Jan 2025 16:22:31 +0100 Subject: [PATCH] feat: provide name and allow multiple Nuxt App within the same process --- packages/kit/src/context.ts | 7 ++++--- packages/kit/src/index.ts | 1 + packages/kit/src/utils.ts | 4 ++++ packages/nuxt/src/core/nitro.ts | 2 +- packages/nuxt/src/core/nuxt.ts | 13 +++++++------ packages/schema/src/types/nuxt.ts | 5 +++++ 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/kit/src/context.ts b/packages/kit/src/context.ts index d132b81c6c..873b388b26 100644 --- a/packages/kit/src/context.ts +++ b/packages/kit/src/context.ts @@ -1,8 +1,9 @@ import { getContext } from 'unctx' import type { Nuxt } from '@nuxt/schema' +import { asyncNameStorage } from './utils' /** Direct access to the Nuxt context - see https://github.com/unjs/unctx. */ -export const nuxtCtx = getContext('nuxt') +export const nuxtCtx = () => getContext(asyncNameStorage.getStore()!) // TODO: Use use/tryUse from unctx. https://github.com/unjs/unctx/issues/6 @@ -16,7 +17,7 @@ export const nuxtCtx = getContext('nuxt') * ``` */ export function useNuxt (): Nuxt { - const instance = nuxtCtx.tryUse() + const instance = nuxtCtx().tryUse() if (!instance) { throw new Error('Nuxt instance is unavailable!') } @@ -36,5 +37,5 @@ export function useNuxt (): Nuxt { * ``` */ export function tryUseNuxt (): Nuxt | null { - return nuxtCtx.tryUse() + return nuxtCtx().tryUse() } diff --git a/packages/kit/src/index.ts b/packages/kit/src/index.ts index 04056b2784..011b437dc0 100644 --- a/packages/kit/src/index.ts +++ b/packages/kit/src/index.ts @@ -34,3 +34,4 @@ export { logger, useLogger } from './logger' // Internal Utils export { resolveModule, tryResolveModule, importModule, tryImportModule, requireModule, tryRequireModule } from './internal/esm' export type { ImportModuleOptions, ResolveModuleOptions } from './internal/esm' +export { asyncNameStorage } from './utils' \ No newline at end of file diff --git a/packages/kit/src/utils.ts b/packages/kit/src/utils.ts index 89fa591c50..fa3f522514 100644 --- a/packages/kit/src/utils.ts +++ b/packages/kit/src/utils.ts @@ -1,6 +1,10 @@ +import { AsyncLocalStorage } from "node:async_hooks" + /** @since 3.9.0 */ export function toArray (value: T | T[]): T[] { return Array.isArray(value) ? value : [value] } export const MODE_RE = /\.(server|client)(\.\w+)*$/ + +export const asyncNameStorage = new AsyncLocalStorage() \ No newline at end of file diff --git a/packages/nuxt/src/core/nitro.ts b/packages/nuxt/src/core/nitro.ts index 698cb04b3a..4d6c87c203 100644 --- a/packages/nuxt/src/core/nitro.ts +++ b/packages/nuxt/src/core/nitro.ts @@ -429,7 +429,7 @@ export async function initNitro (nuxt: Nuxt & { _nitro?: Nitro }) { tsConfig.compilerOptions.paths[alias] = [absolutePath.replace(EXTENSION_RE, '')] /* remove extension */ } } - + // Init nitro const nitro = await createNitro(nitroConfig, { compatibilityDate: nuxt.options.compatibilityDate, diff --git a/packages/nuxt/src/core/nuxt.ts b/packages/nuxt/src/core/nuxt.ts index 957da98314..0c109300f0 100644 --- a/packages/nuxt/src/core/nuxt.ts +++ b/packages/nuxt/src/core/nuxt.ts @@ -4,7 +4,7 @@ import { join, normalize, relative, resolve } from 'pathe' import { createDebugger, createHooks } from 'hookable' import ignore from 'ignore' import type { LoadNuxtOptions } from '@nuxt/kit' -import { addBuildPlugin, addComponent, addPlugin, addPluginTemplate, addRouteMiddleware, addServerPlugin, addTypeTemplate, addVitePlugin, addWebpackPlugin, installModule, loadNuxtConfig, nuxtCtx, resolveAlias, resolveFiles, resolveIgnorePatterns, resolvePath, tryResolveModule, useNitro } from '@nuxt/kit' +import { addBuildPlugin, addComponent, addPlugin, addPluginTemplate, addRouteMiddleware, addServerPlugin, addTypeTemplate, addVitePlugin, addWebpackPlugin, installModule, loadNuxtConfig, nuxtCtx, resolveAlias, resolveFiles, resolveIgnorePatterns, resolvePath, tryResolveModule, useNitro, asyncNameStorage } from '@nuxt/kit' import type { Nuxt, NuxtHooks, NuxtModule, NuxtOptions } from 'nuxt/schema' import type { PackageJson } from 'pkg-types' import { readPackageJSON } from 'pkg-types' @@ -47,10 +47,11 @@ import { ComposableKeysPlugin } from './plugins/composable-keys' import { resolveDeepImportsPlugin } from './plugins/resolve-deep-imports' import { PrehydrateTransformPlugin } from './plugins/prehydrate' import { VirtualFSPlugin } from './plugins/virtual' +import { randomUUID } from 'node:crypto' export function createNuxt (options: NuxtOptions): Nuxt { const hooks = createHooks() - + const name = randomUUID() const nuxt: Nuxt = { _version: version, options, @@ -58,7 +59,7 @@ export function createNuxt (options: NuxtOptions): Nuxt { callHook: hooks.callHook, addHooks: hooks.addHooks, hook: hooks.hook, - ready: () => initNuxt(nuxt), + ready: () => asyncNameStorage.run(name, () => initNuxt(nuxt)) , close: () => hooks.callHook('close', nuxt), vfs: {}, apps: {}, @@ -175,8 +176,8 @@ async function initNuxt (nuxt: Nuxt) { }) // Set nuxt instance for useNuxt - nuxtCtx.set(nuxt) - nuxt.hook('close', () => nuxtCtx.unset()) + nuxtCtx().set(nuxt) + nuxt.hook('close', () => nuxtCtx().unset()) const coreTypePackages = nuxt.options.typescript.hoist || [] @@ -694,7 +695,7 @@ export default defineNuxtPlugin({ nuxt.options.build.transpile = nuxt.options.build.transpile.map(t => typeof t === 'string' ? normalize(t) : t) addModuleTranspiles() - + // Init nitro await initNitro(nuxt) diff --git a/packages/schema/src/types/nuxt.ts b/packages/schema/src/types/nuxt.ts index ab9d1a2eeb..a17e6354cf 100644 --- a/packages/schema/src/types/nuxt.ts +++ b/packages/schema/src/types/nuxt.ts @@ -79,6 +79,11 @@ export interface NuxtApp { } export interface Nuxt { + /** + * The name of the Nuxt project, this can be useful for build time debugging and mono-repos. + * Defaults to a randomUUID + */ + name?: string // Private fields. _version: string _ignore?: Ignore