mirror of
https://github.com/nuxt/nuxt.git
synced 2025-01-31 07:40:33 +00:00
feat: use async localStorage instead
This commit is contained in:
parent
38bec27bf6
commit
693642ff20
@ -39,7 +39,6 @@
|
||||
"klona": "^2.0.6",
|
||||
"mlly": "^1.7.3",
|
||||
"ohash": "^1.1.4",
|
||||
"on-change": "^5.0.1",
|
||||
"pathe": "^2.0.1",
|
||||
"pkg-types": "^1.3.0",
|
||||
"scule": "^1.3.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { existsSync, promises as fsp, lstatSync } from 'node:fs'
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url'
|
||||
import type { ModuleMeta, Nuxt, NuxtConfig, NuxtDebugModuleMutationRecord, NuxtModule } from '@nuxt/schema'
|
||||
import type { ModuleMeta, Nuxt, NuxtConfig, NuxtModule } from '@nuxt/schema'
|
||||
import { dirname, isAbsolute, join, resolve } from 'pathe'
|
||||
import { defu } from 'defu'
|
||||
import { createJiti } from 'jiti'
|
||||
@ -27,44 +27,11 @@ export async function installModule<
|
||||
}
|
||||
}
|
||||
|
||||
let _nuxt = nuxt
|
||||
if (nuxt.options.debug) {
|
||||
const onChange = await import('on-change').then(r => r.default)
|
||||
const moduleName = (await nuxtModule.getMeta?.())?.name || buildTimeModuleMeta?.name || resolvedModulePath
|
||||
|
||||
// Unwrap onChange proxy if already wrapped
|
||||
nuxt = onChange.target(nuxt)
|
||||
|
||||
nuxt._debug ||= {}
|
||||
nuxt._debug.moduleMutationRecords ||= []
|
||||
|
||||
_nuxt = onChange(
|
||||
nuxt,
|
||||
(keys, value, _, applyData) => {
|
||||
// We only listen to changes in the `options` object
|
||||
if (keys[0] !== 'options') {
|
||||
return
|
||||
}
|
||||
const record: NuxtDebugModuleMutationRecord = {
|
||||
module: moduleName,
|
||||
keys: keys.slice(1),
|
||||
value,
|
||||
timestamp: Date.now(),
|
||||
}
|
||||
if (applyData?.name) {
|
||||
record.method = applyData.name
|
||||
}
|
||||
nuxt._debug!.moduleMutationRecords!.push(record)
|
||||
}, {
|
||||
ignoreUnderscores: true,
|
||||
ignoreSymbols: true,
|
||||
pathAsArray: true,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Call module
|
||||
const res = await nuxtModule(inlineOptions || {}, _nuxt) ?? {}
|
||||
const res = await nuxt._asyncLocalStorageModule.run(
|
||||
nuxtModule,
|
||||
() => nuxtModule(inlineOptions || {}, nuxt),
|
||||
) ?? {}
|
||||
if (res === false /* setup aborted */) {
|
||||
return
|
||||
}
|
||||
@ -89,6 +56,7 @@ export async function installModule<
|
||||
|
||||
nuxt.options._installedModules.push({
|
||||
meta: defu(await nuxtModule.getMeta?.(), buildTimeModuleMeta),
|
||||
module: nuxtModule,
|
||||
timings: res.timings,
|
||||
entryPath,
|
||||
})
|
||||
|
@ -92,6 +92,7 @@
|
||||
"globby": "^14.0.2",
|
||||
"h3": "npm:h3-nightly@2.0.0-1718872656.6765a6e",
|
||||
"hookable": "^5.5.3",
|
||||
"on-change": "^5.0.1",
|
||||
"ignore": "^7.0.0",
|
||||
"impound": "^0.2.0",
|
||||
"jiti": "^2.4.2",
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { existsSync } from 'node:fs'
|
||||
import { rm } from 'node:fs/promises'
|
||||
import { AsyncLocalStorage } from 'node:async_hooks'
|
||||
import { join, normalize, relative, resolve } from 'pathe'
|
||||
import { createDebugger, createHooks } from 'hookable'
|
||||
import ignore from 'ignore'
|
||||
@ -10,6 +11,7 @@ import type { PackageJson } from 'pkg-types'
|
||||
import { readPackageJSON } from 'pkg-types'
|
||||
import { hash } from 'ohash'
|
||||
import consola from 'consola'
|
||||
import onChange from 'on-change'
|
||||
import { colorize } from 'consola/utils'
|
||||
import { updateConfig } from 'c12/update'
|
||||
import { formatDate, resolveCompatibilityDatesFromEnv } from 'compatx'
|
||||
@ -51,9 +53,11 @@ import { VirtualFSPlugin } from './plugins/virtual'
|
||||
export function createNuxt (options: NuxtOptions): Nuxt {
|
||||
const hooks = createHooks<NuxtHooks>()
|
||||
|
||||
const proxiedOptions = new WeakMap<NuxtModule, NuxtOptions>()
|
||||
|
||||
const nuxt: Nuxt = {
|
||||
_version: version,
|
||||
options,
|
||||
_asyncLocalStorageModule: new AsyncLocalStorage(),
|
||||
hooks,
|
||||
callHook: hooks.callHook,
|
||||
addHooks: hooks.addHooks,
|
||||
@ -62,6 +66,50 @@ export function createNuxt (options: NuxtOptions): Nuxt {
|
||||
close: () => hooks.callHook('close', nuxt),
|
||||
vfs: {},
|
||||
apps: {},
|
||||
options,
|
||||
}
|
||||
|
||||
if (options.experimental.debugModuleMutation) {
|
||||
Object.defineProperty(nuxt, 'options', {
|
||||
get () {
|
||||
const currentModule = nuxt._asyncLocalStorageModule.getStore()
|
||||
if (!currentModule) {
|
||||
return options
|
||||
}
|
||||
|
||||
if (proxiedOptions.has(currentModule)) {
|
||||
return proxiedOptions.get(currentModule)!
|
||||
}
|
||||
|
||||
nuxt._debug ||= {}
|
||||
nuxt._debug.moduleMutationRecords ||= []
|
||||
|
||||
const proxied = onChange(
|
||||
options,
|
||||
(keys, value, previousValue, applyData) => {
|
||||
if (value === previousValue && !applyData) {
|
||||
return
|
||||
}
|
||||
nuxt._debug!.moduleMutationRecords!.push({
|
||||
module: currentModule,
|
||||
keys,
|
||||
target: 'nuxt.options',
|
||||
value: applyData?.args ?? value,
|
||||
timestamp: Date.now(),
|
||||
method: applyData?.name,
|
||||
})
|
||||
}, {
|
||||
ignoreUnderscores: true,
|
||||
ignoreSymbols: true,
|
||||
pathAsArray: true,
|
||||
},
|
||||
)
|
||||
|
||||
proxiedOptions.set(currentModule, proxied)
|
||||
return proxied
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
hooks.hookOnce('close', () => { hooks.removeAllHooks() })
|
||||
|
@ -437,5 +437,14 @@ export default defineUntypedSchema({
|
||||
browserDevtoolsTiming: {
|
||||
$resolve: async (val, get) => val ?? await get('dev'),
|
||||
},
|
||||
|
||||
/**
|
||||
* Record mutations to `nuxt.options` in module context
|
||||
*/
|
||||
debugModuleMutation: {
|
||||
$resolve: async (val, get) => {
|
||||
return val ?? await get('debug')
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -25,7 +25,7 @@ export default defineUntypedSchema({
|
||||
appDir: '',
|
||||
/**
|
||||
* @private
|
||||
* @type {Array<{ meta: ModuleMeta; timings?: Record<string, number | undefined>; entryPath?: string }>}
|
||||
* @type {Array<{ meta: ModuleMeta; module: NuxtModule, timings?: Record<string, number | undefined>; entryPath?: string }>}
|
||||
*/
|
||||
_installedModules: [],
|
||||
/** @private */
|
||||
|
@ -1,3 +1,5 @@
|
||||
import type { NuxtModule } from './module'
|
||||
|
||||
export interface NuxtDebugContext {
|
||||
/**
|
||||
* Module mutation records to the `nuxt` instance.
|
||||
@ -6,8 +8,9 @@ export interface NuxtDebugContext {
|
||||
}
|
||||
|
||||
export interface NuxtDebugModuleMutationRecord {
|
||||
module: string | undefined
|
||||
module: NuxtModule
|
||||
keys: (string | symbol)[]
|
||||
target: 'nuxt.options'
|
||||
value: any
|
||||
method?: string
|
||||
timestamp: number
|
||||
|
@ -1,5 +1,7 @@
|
||||
import type { AsyncLocalStorage } from 'node:async_hooks'
|
||||
import type { Hookable } from 'hookable'
|
||||
import type { Ignore } from 'ignore'
|
||||
import type { NuxtModule } from './module'
|
||||
import type { NuxtHooks, NuxtLayout, NuxtMiddleware, NuxtPage } from './hooks'
|
||||
import type { Component } from './components'
|
||||
import type { NuxtOptions } from './config'
|
||||
@ -85,6 +87,8 @@ export interface Nuxt {
|
||||
_ignore?: Ignore
|
||||
_dependencies?: Set<string>
|
||||
_debug?: NuxtDebugContext
|
||||
/** Async local storage for current running Nuxt module instance. */
|
||||
_asyncLocalStorageModule: AsyncLocalStorage<NuxtModule>
|
||||
|
||||
/** The resolved Nuxt configuration. */
|
||||
options: NuxtOptions
|
||||
|
@ -230,9 +230,6 @@ importers:
|
||||
ohash:
|
||||
specifier: 1.1.4
|
||||
version: 1.1.4
|
||||
on-change:
|
||||
specifier: ^5.0.1
|
||||
version: 5.0.1
|
||||
pathe:
|
||||
specifier: ^2.0.1
|
||||
version: 2.0.1
|
||||
@ -405,6 +402,9 @@ importers:
|
||||
ohash:
|
||||
specifier: 1.1.4
|
||||
version: 1.1.4
|
||||
on-change:
|
||||
specifier: ^5.0.1
|
||||
version: 5.0.1
|
||||
pathe:
|
||||
specifier: ^2.0.1
|
||||
version: 2.0.1
|
||||
|
Loading…
Reference in New Issue
Block a user