mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-22 11:22:43 +00:00
fix: correctly set context when creating nuxt and provide an internal run fn and wrap callhooks
This commit is contained in:
parent
37fd4ab37c
commit
78649f6662
@ -1,6 +1,7 @@
|
||||
import { existsSync } from 'node:fs'
|
||||
import { rm } from 'node:fs/promises'
|
||||
import { randomUUID } from 'node:crypto'
|
||||
import { AsyncLocalStorage, AsyncResource } from 'node:async_hooks'
|
||||
import { join, normalize, relative, resolve } from 'pathe'
|
||||
import { createDebugger, createHooks } from 'hookable'
|
||||
import ignore from 'ignore'
|
||||
@ -52,6 +53,12 @@ import { VirtualFSPlugin } from './plugins/virtual'
|
||||
export function createNuxt (options: NuxtOptions): Nuxt {
|
||||
const hooks = createHooks<NuxtHooks>()
|
||||
const name = randomUUID()
|
||||
|
||||
const { callHook, callHookParallel, callHookWith } = hooks
|
||||
hooks.callHook = (...args) => asyncNameStorage.run(name, () => callHook(...args))
|
||||
hooks.callHookParallel = (...args) => asyncNameStorage.run(name, () => callHookParallel(...args))
|
||||
hooks.callHookWith = (...args) => asyncNameStorage.run(name, () => callHookWith(...args))
|
||||
|
||||
const nuxt: Nuxt = {
|
||||
_version: version,
|
||||
options,
|
||||
@ -64,8 +71,24 @@ export function createNuxt (options: NuxtOptions): Nuxt {
|
||||
vfs: {},
|
||||
apps: {},
|
||||
__name: name,
|
||||
run: fn => asyncNameStorage.run(name, fn),
|
||||
}
|
||||
|
||||
if (!nuxtCtx.tryUse()) {
|
||||
// backward compatibility with 3.x
|
||||
nuxtCtx.set(nuxt)
|
||||
nuxt.hook('close', () => {
|
||||
nuxtCtx.unset()
|
||||
})
|
||||
}
|
||||
nuxt.run(() => {
|
||||
// Set nuxt instance for useNuxt
|
||||
getNuxtCtx().set(nuxt)
|
||||
nuxt.hook('close', () => {
|
||||
getNuxtCtx().unset()
|
||||
})
|
||||
})
|
||||
|
||||
hooks.hookOnce('close', () => { hooks.removeAllHooks() })
|
||||
|
||||
return nuxt
|
||||
@ -175,19 +198,6 @@ async function initNuxt (nuxt: Nuxt) {
|
||||
}
|
||||
}
|
||||
})
|
||||
if (!nuxtCtx.tryUse()) {
|
||||
// backward compatibility with 3.x
|
||||
nuxtCtx.set(nuxt)
|
||||
nuxt.hook('close', () => {
|
||||
nuxtCtx.unset()
|
||||
})
|
||||
}
|
||||
// Set nuxt instance for useNuxt
|
||||
getNuxtCtx().set(nuxt)
|
||||
nuxt.hook('close', () => {
|
||||
getNuxtCtx().unset()
|
||||
})
|
||||
|
||||
const coreTypePackages = nuxt.options.typescript.hoist || []
|
||||
|
||||
// Disable environment types entirely if `typescript.builder` is false
|
||||
@ -812,6 +822,7 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
||||
|
||||
const nuxt = createNuxt(options)
|
||||
|
||||
nuxt.run(() => {
|
||||
for (const dep of keyDependencies) {
|
||||
checkDependencyVersion(dep, nuxt._version)
|
||||
}
|
||||
@ -824,6 +835,7 @@ export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
||||
if (nuxt.options.debug) {
|
||||
createDebugger(nuxt.hooks, { tag: 'nuxt' })
|
||||
}
|
||||
})
|
||||
|
||||
if (opts.ready !== false) {
|
||||
await nuxt.ready()
|
||||
|
@ -4,9 +4,11 @@ import { normalize } from 'pathe'
|
||||
import { withoutTrailingSlash } from 'ufo'
|
||||
import { readPackageJSON } from 'pkg-types'
|
||||
import { inc } from 'semver'
|
||||
import { asyncNameStorage, useNuxt } from '@nuxt/kit'
|
||||
import { loadNuxt } from '../src'
|
||||
import { version } from '../package.json'
|
||||
|
||||
import { logger } from '@nuxt/kit'
|
||||
import { beforeEach } from 'node:test'
|
||||
const repoRoot = withoutTrailingSlash(normalize(fileURLToPath(new URL('../../../', import.meta.url))))
|
||||
|
||||
vi.stubGlobal('console', {
|
||||
@ -15,6 +17,7 @@ vi.stubGlobal('console', {
|
||||
warn: vi.fn(console.warn),
|
||||
})
|
||||
|
||||
const loggerWarn = vi.spyOn(logger, 'warn')
|
||||
vi.mock('pkg-types', async (og) => {
|
||||
const originalPkgTypes = (await og<typeof import('pkg-types')>())
|
||||
return {
|
||||
@ -23,6 +26,9 @@ vi.mock('pkg-types', async (og) => {
|
||||
}
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
loggerWarn.mockClear()
|
||||
})
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
@ -53,7 +59,24 @@ describe('loadNuxt', () => {
|
||||
cwd: repoRoot,
|
||||
}),
|
||||
])
|
||||
expect(console.warn).not.toHaveBeenCalled()
|
||||
expect(loggerWarn).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('expect hooks to get the correct context outside of initNuxt', async () => {
|
||||
const nuxt = await loadNuxt({
|
||||
cwd: repoRoot,
|
||||
})
|
||||
|
||||
// @ts-expect-error - random hook
|
||||
await nuxt.hook('test', () => {
|
||||
const nuxt = useNuxt()
|
||||
expect(asyncNameStorage.getStore()).toBe(nuxt.__name)
|
||||
})
|
||||
|
||||
// @ts-expect-error - random hook
|
||||
await nuxt.callHook('test')
|
||||
|
||||
expect(loggerWarn).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -87,6 +87,10 @@ export interface Nuxt {
|
||||
_version: string
|
||||
_ignore?: Ignore
|
||||
_dependencies?: Set<string>
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
run: <T extends (...args: any[]) => any>(fn: T) => ReturnType<T>
|
||||
|
||||
/** The resolved Nuxt configuration. */
|
||||
options: NuxtOptions
|
||||
|
Loading…
Reference in New Issue
Block a user