mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 07:05:11 +00:00
perf(kit): various performance improvements (#27600)
Co-authored-by: Michael Brevard <yonshi29@gmail.com>
This commit is contained in:
parent
d929cd4ef6
commit
7dfc85623b
@ -61,7 +61,7 @@ function getRequireCacheItem (id: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getModulePaths (paths?: string[] | string) {
|
export function getNodeModulesPaths (paths?: string[] | string) {
|
||||||
return ([] as Array<string | undefined>).concat(
|
return ([] as Array<string | undefined>).concat(
|
||||||
global.__NUXT_PREPATHS__,
|
global.__NUXT_PREPATHS__,
|
||||||
paths || [],
|
paths || [],
|
||||||
@ -73,7 +73,7 @@ export function getModulePaths (paths?: string[] | string) {
|
|||||||
/** @deprecated Do not use CJS utils */
|
/** @deprecated Do not use CJS utils */
|
||||||
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
||||||
return normalize(_require.resolve(id, {
|
return normalize(_require.resolve(id, {
|
||||||
paths: getModulePaths(opts.paths),
|
paths: getNodeModulesPaths(opts.paths),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,10 +32,11 @@ const serialize = (data: any) => JSON.stringify(data, null, 2).replace(/"\{(.+)\
|
|||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
const importSources = (sources: string | string[], { lazy = false } = {}) => {
|
const importSources = (sources: string | string[], { lazy = false } = {}) => {
|
||||||
return toArray(sources).map((src) => {
|
return toArray(sources).map((src) => {
|
||||||
|
const safeVariableName = genSafeVariableName(src)
|
||||||
if (lazy) {
|
if (lazy) {
|
||||||
return `const ${genSafeVariableName(src)} = ${genDynamicImport(src, { comment: `webpackChunkName: ${JSON.stringify(src)}` })}`
|
return `const ${safeVariableName} = ${genDynamicImport(src, { comment: `webpackChunkName: ${JSON.stringify(src)}` })}`
|
||||||
}
|
}
|
||||||
return genImport(src, genSafeVariableName(src))
|
return genImport(src, safeVariableName)
|
||||||
}).join('\n')
|
}).join('\n')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,12 @@ export interface LoadNuxtConfigOptions extends Omit<LoadConfigOptions<NuxtConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
const layerSchemaKeys = ['future', 'srcDir', 'rootDir', 'dir']
|
const layerSchemaKeys = ['future', 'srcDir', 'rootDir', 'dir']
|
||||||
const layerSchema = Object.fromEntries(Object.entries(NuxtConfigSchema).filter(([key]) => layerSchemaKeys.includes(key)))
|
const layerSchema = Object.create(null)
|
||||||
|
for (const key of layerSchemaKeys) {
|
||||||
|
if (key in NuxtConfigSchema) {
|
||||||
|
layerSchema[key] = NuxtConfigSchema[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<NuxtOptions> {
|
export async function loadNuxtConfig (opts: LoadNuxtConfigOptions): Promise<NuxtOptions> {
|
||||||
// Automatically detect and import layers from `~~/layers/` directory
|
// Automatically detect and import layers from `~~/layers/` directory
|
||||||
|
@ -51,11 +51,10 @@ export async function getNuxtModuleVersion (module: string | NuxtModule, nuxt: N
|
|||||||
// need a name from here
|
// need a name from here
|
||||||
if (!moduleMeta.name) { return false }
|
if (!moduleMeta.name) { return false }
|
||||||
// maybe the version got attached within the installed module instance?
|
// maybe the version got attached within the installed module instance?
|
||||||
const version = nuxt.options._installedModules
|
for (const m of nuxt.options._installedModules) {
|
||||||
// @ts-expect-error _installedModules is not typed
|
if (m.meta.name === moduleMeta.name && m.meta.version) {
|
||||||
.filter(m => m.meta.name === moduleMeta.name).map(m => m.meta.version)?.[0]
|
return m.meta.version
|
||||||
if (version) {
|
}
|
||||||
return version
|
|
||||||
}
|
}
|
||||||
// it's possible that the module will be installed, it just hasn't been done yet, preemptively load the instance
|
// it's possible that the module will be installed, it just hasn't been done yet, preemptively load the instance
|
||||||
if (hasNuxtModule(moduleMeta.name)) {
|
if (hasNuxtModule(moduleMeta.name)) {
|
||||||
|
@ -51,11 +51,12 @@ export function addRouteMiddleware (input: NuxtMiddleware | NuxtMiddleware[], op
|
|||||||
for (const middleware of middlewares) {
|
for (const middleware of middlewares) {
|
||||||
const find = app.middleware.findIndex(item => item.name === middleware.name)
|
const find = app.middleware.findIndex(item => item.name === middleware.name)
|
||||||
if (find >= 0) {
|
if (find >= 0) {
|
||||||
if (app.middleware[find].path === middleware.path) { continue }
|
const foundPath = app.middleware[find].path
|
||||||
|
if (foundPath === middleware.path) { continue }
|
||||||
if (options.override === true) {
|
if (options.override === true) {
|
||||||
app.middleware[find] = { ...middleware }
|
app.middleware[find] = { ...middleware }
|
||||||
} else {
|
} else {
|
||||||
logger.warn(`'${middleware.name}' middleware already exists at '${app.middleware[find].path}'. You can set \`override: true\` to replace it.`)
|
logger.warn(`'${middleware.name}' middleware already exists at '${foundPath}'. You can set \`override: true\` to replace it.`)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
app.middleware.push({ ...middleware })
|
app.middleware.push({ ...middleware })
|
||||||
|
@ -168,8 +168,8 @@ export function createResolver (base: string | URL): Resolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function resolveNuxtModule (base: string, paths: string[]) {
|
export async function resolveNuxtModule (base: string, paths: string[]): Promise<string[]> {
|
||||||
const resolved = []
|
const resolved: string[] = []
|
||||||
const resolver = createResolver(base)
|
const resolver = createResolver(base)
|
||||||
|
|
||||||
for (const path of paths) {
|
for (const path of paths) {
|
||||||
@ -209,6 +209,12 @@ function existsInVFS (path: string, nuxt = tryUseNuxt()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function resolveFiles (path: string, pattern: string | string[], opts: { followSymbolicLinks?: boolean } = {}) {
|
export async function resolveFiles (path: string, pattern: string | string[], opts: { followSymbolicLinks?: boolean } = {}) {
|
||||||
const files = await globby(pattern, { cwd: path, followSymbolicLinks: opts.followSymbolicLinks ?? true })
|
const files: string[] = []
|
||||||
return files.map(p => resolve(path, p)).filter(p => !isIgnored(p)).sort()
|
for (const file of await globby(pattern, { cwd: path, followSymbolicLinks: opts.followSymbolicLinks ?? true })) {
|
||||||
|
const p = resolve(path, file)
|
||||||
|
if (!isIgnored(p)) {
|
||||||
|
files.push(p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return files.sort()
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import { readPackageJSON } from 'pkg-types'
|
|||||||
import { tryResolveModule } from './internal/esm'
|
import { tryResolveModule } from './internal/esm'
|
||||||
import { getDirectory } from './module/install'
|
import { getDirectory } from './module/install'
|
||||||
import { tryUseNuxt, useNuxt } from './context'
|
import { tryUseNuxt, useNuxt } from './context'
|
||||||
import { getModulePaths } from './internal/cjs'
|
import { getNodeModulesPaths } from './internal/cjs'
|
||||||
import { resolveNuxtModule } from './resolve'
|
import { resolveNuxtModule } from './resolve'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,18 +113,55 @@ export async function updateTemplates (options?: { filter?: (template: ResolvedN
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function _generateTypes (nuxt: Nuxt) {
|
export async function _generateTypes (nuxt: Nuxt) {
|
||||||
const nodeModulePaths = getModulePaths(nuxt.options.modulesDir)
|
|
||||||
|
|
||||||
const rootDirWithSlash = withTrailingSlash(nuxt.options.rootDir)
|
const rootDirWithSlash = withTrailingSlash(nuxt.options.rootDir)
|
||||||
|
const relativeRootDir = relativeWithDot(nuxt.options.buildDir, nuxt.options.rootDir)
|
||||||
|
|
||||||
const modulePaths = await resolveNuxtModule(rootDirWithSlash,
|
const include = new Set<string>([
|
||||||
nuxt.options._installedModules
|
'./nuxt.d.ts',
|
||||||
.filter(m => m.entryPath)
|
join(relativeRootDir, '.config/nuxt.*'),
|
||||||
.map(m => getDirectory(m.entryPath!)),
|
join(relativeRootDir, '**/*'),
|
||||||
)
|
])
|
||||||
|
|
||||||
|
if (nuxt.options.srcDir !== nuxt.options.rootDir) {
|
||||||
|
include.add(join(relative(nuxt.options.buildDir, nuxt.options.srcDir), '**/*'))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nuxt.options.typescript.includeWorkspace && nuxt.options.workspaceDir !== nuxt.options.rootDir) {
|
||||||
|
include.add(join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), '**/*'))
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const layer of nuxt.options._layers) {
|
||||||
|
const srcOrCwd = layer.config.srcDir ?? layer.cwd
|
||||||
|
if (!srcOrCwd.startsWith(rootDirWithSlash) || srcOrCwd.includes('node_modules')) {
|
||||||
|
include.add(join(relative(nuxt.options.buildDir, srcOrCwd), '**/*'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const exclude = new Set<string>([
|
||||||
|
// nitro generate output: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/nitro.ts#L186
|
||||||
|
relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, 'dist')),
|
||||||
|
])
|
||||||
|
|
||||||
|
for (const dir of nuxt.options.modulesDir) {
|
||||||
|
exclude.add(relativeWithDot(nuxt.options.buildDir, dir))
|
||||||
|
}
|
||||||
|
|
||||||
|
const moduleEntryPaths: string[] = []
|
||||||
|
for (const m of nuxt.options._installedModules) {
|
||||||
|
if (m.entryPath) {
|
||||||
|
moduleEntryPaths.push(getDirectory(m.entryPath))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const modulePaths = await resolveNuxtModule(rootDirWithSlash, moduleEntryPaths)
|
||||||
|
|
||||||
|
for (const path of modulePaths) {
|
||||||
|
const relative = relativeWithDot(nuxt.options.buildDir, path)
|
||||||
|
include.add(join(relative, 'runtime'))
|
||||||
|
exclude.add(join(relative, 'runtime/server'))
|
||||||
|
}
|
||||||
|
|
||||||
const isV4 = nuxt.options.future?.compatibilityVersion === 4
|
const isV4 = nuxt.options.future?.compatibilityVersion === 4
|
||||||
|
|
||||||
const hasTypescriptVersionWithModulePreserve = await readPackageJSON('typescript', { url: nuxt.options.modulesDir })
|
const hasTypescriptVersionWithModulePreserve = await readPackageJSON('typescript', { url: nuxt.options.modulesDir })
|
||||||
.then(r => r?.version && gte(r.version, '5.4.0'))
|
.then(r => r?.version && gte(r.version, '5.4.0'))
|
||||||
.catch(() => isV4)
|
.catch(() => isV4)
|
||||||
@ -168,23 +205,8 @@ export async function _generateTypes (nuxt: Nuxt) {
|
|||||||
noImplicitThis: true, /* enabled with `strict` */
|
noImplicitThis: true, /* enabled with `strict` */
|
||||||
allowSyntheticDefaultImports: true,
|
allowSyntheticDefaultImports: true,
|
||||||
},
|
},
|
||||||
include: [
|
include: [...include],
|
||||||
'./nuxt.d.ts',
|
exclude: [...exclude],
|
||||||
join(relativeWithDot(nuxt.options.buildDir, nuxt.options.rootDir), '.config/nuxt.*'),
|
|
||||||
join(relativeWithDot(nuxt.options.buildDir, nuxt.options.rootDir), '**/*'),
|
|
||||||
...nuxt.options.srcDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.srcDir), '**/*')] : [],
|
|
||||||
...nuxt.options._layers.map(layer => layer.config.srcDir ?? layer.cwd)
|
|
||||||
.filter(srcOrCwd => !srcOrCwd.startsWith(rootDirWithSlash) || srcOrCwd.includes('node_modules'))
|
|
||||||
.map(srcOrCwd => join(relative(nuxt.options.buildDir, srcOrCwd), '**/*')),
|
|
||||||
...nuxt.options.typescript.includeWorkspace && nuxt.options.workspaceDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), '**/*')] : [],
|
|
||||||
...modulePaths.map(m => join(relativeWithDot(nuxt.options.buildDir, m), 'runtime')),
|
|
||||||
],
|
|
||||||
exclude: [
|
|
||||||
...nuxt.options.modulesDir.map(m => relativeWithDot(nuxt.options.buildDir, m)),
|
|
||||||
...modulePaths.map(m => join(relativeWithDot(nuxt.options.buildDir, m), 'runtime/server')),
|
|
||||||
// nitro generate output: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/nitro.ts#L186
|
|
||||||
relativeWithDot(nuxt.options.buildDir, resolve(nuxt.options.rootDir, 'dist')),
|
|
||||||
],
|
|
||||||
} satisfies TSConfig)
|
} satisfies TSConfig)
|
||||||
|
|
||||||
const aliases: Record<string, string> = {
|
const aliases: Record<string, string> = {
|
||||||
@ -195,7 +217,9 @@ export async function _generateTypes (nuxt: Nuxt) {
|
|||||||
// Exclude bridge alias types to support Volar
|
// Exclude bridge alias types to support Volar
|
||||||
const excludedAlias = [/^@vue\/.*$/]
|
const excludedAlias = [/^@vue\/.*$/]
|
||||||
|
|
||||||
const basePath = tsConfig.compilerOptions!.baseUrl ? resolve(nuxt.options.buildDir, tsConfig.compilerOptions!.baseUrl) : nuxt.options.buildDir
|
const basePath = tsConfig.compilerOptions!.baseUrl
|
||||||
|
? resolve(nuxt.options.buildDir, tsConfig.compilerOptions!.baseUrl)
|
||||||
|
: nuxt.options.buildDir
|
||||||
|
|
||||||
tsConfig.compilerOptions = tsConfig.compilerOptions || {}
|
tsConfig.compilerOptions = tsConfig.compilerOptions || {}
|
||||||
tsConfig.include = tsConfig.include || []
|
tsConfig.include = tsConfig.include || []
|
||||||
@ -237,12 +261,13 @@ export async function _generateTypes (nuxt: Nuxt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const references: TSReference[] = await Promise.all([
|
const references: TSReference[] = []
|
||||||
...nuxt.options.modules,
|
await Promise.all([...nuxt.options.modules, ...nuxt.options._modules].map(async (id) => {
|
||||||
...nuxt.options._modules,
|
if (typeof id !== 'string') { return }
|
||||||
]
|
|
||||||
.filter(f => typeof f === 'string')
|
const pkg = await readPackageJSON(id, { url: getNodeModulesPaths(nuxt.options.modulesDir) }).catch(() => null)
|
||||||
.map(async id => ({ types: (await readPackageJSON(id, { url: nodeModulePaths }).catch(() => null))?.name || id })))
|
references.push(({ types: pkg?.name || id }))
|
||||||
|
}))
|
||||||
|
|
||||||
const declarations: string[] = []
|
const declarations: string[] = []
|
||||||
|
|
||||||
@ -302,7 +327,11 @@ export async function writeTypes (nuxt: Nuxt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderAttrs (obj: Record<string, string>) {
|
function renderAttrs (obj: Record<string, string>) {
|
||||||
return Object.entries(obj).map(e => renderAttr(e[0], e[1])).join(' ')
|
const attrs: string[] = []
|
||||||
|
for (const key in obj) {
|
||||||
|
attrs.push(renderAttr(key, obj[key]))
|
||||||
|
}
|
||||||
|
return attrs.join(' ')
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderAttr (key: string, value: string) {
|
function renderAttr (key: string, value: string) {
|
||||||
|
@ -53,12 +53,12 @@ describe('tsConfig generation', () => {
|
|||||||
}))
|
}))
|
||||||
expect(tsConfig.exclude).toMatchInlineSnapshot(`
|
expect(tsConfig.exclude).toMatchInlineSnapshot(`
|
||||||
[
|
[
|
||||||
|
"../dist",
|
||||||
"../modules/test/node_modules",
|
"../modules/test/node_modules",
|
||||||
"../modules/node_modules",
|
"../modules/node_modules",
|
||||||
"../node_modules/@some/module/node_modules",
|
"../node_modules/@some/module/node_modules",
|
||||||
"../node_modules",
|
"../node_modules",
|
||||||
"../../node_modules",
|
"../../node_modules",
|
||||||
"../dist",
|
|
||||||
]
|
]
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user