mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 13:45:18 +00:00
feat(kit): add updateTemplates
utility (#8413)
This commit is contained in:
parent
708460ddc8
commit
5a88510cb7
@ -68,6 +68,7 @@ description: Nuxt Kit provides composable utilities to help interacting with Nux
|
|||||||
[source code](https://github.com/nuxt/framework/blob/main/packages/kit/src/template.ts)
|
[source code](https://github.com/nuxt/framework/blob/main/packages/kit/src/template.ts)
|
||||||
|
|
||||||
- `addTemplate(templateOptions)`
|
- `addTemplate(templateOptions)`
|
||||||
|
- `updateTemplates({ filter?: ResolvedNuxtTemplate => boolean })`
|
||||||
|
|
||||||
### Nitro
|
### Nitro
|
||||||
|
|
||||||
|
@ -71,3 +71,12 @@ export function normalizeTemplate (template: NuxtTemplate<any> | string): Resolv
|
|||||||
|
|
||||||
return template as ResolvedNuxtTemplate<any>
|
return template as ResolvedNuxtTemplate<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Trigger rebuilding Nuxt templates
|
||||||
|
*
|
||||||
|
* You can pass a filter within the options to selectively regenerate a subset of templates.
|
||||||
|
*/
|
||||||
|
export function updateTemplates (options?: { filter?: (template: ResolvedNuxtTemplate<any>) => boolean }) {
|
||||||
|
return useNuxt().hooks.callHook('builder:generateApp', options)
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { statSync } from 'node:fs'
|
import { statSync } from 'node:fs'
|
||||||
import { relative, resolve } from 'pathe'
|
import { relative, resolve } from 'pathe'
|
||||||
import { defineNuxtModule, resolveAlias, addTemplate, addPluginTemplate } from '@nuxt/kit'
|
import { defineNuxtModule, resolveAlias, addTemplate, addPluginTemplate, updateTemplates } from '@nuxt/kit'
|
||||||
import type { Component, ComponentsDir, ComponentsOptions } from '@nuxt/schema'
|
import type { Component, ComponentsDir, ComponentsOptions } from '@nuxt/schema'
|
||||||
import { distDir } from '../dirs'
|
import { distDir } from '../dirs'
|
||||||
import { componentsPluginTemplate, componentsTemplate, componentsTypeTemplate } from './templates'
|
import { componentsPluginTemplate, componentsTemplate, componentsTypeTemplate } from './templates'
|
||||||
@ -122,12 +122,12 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
|
|
||||||
nuxt.hook('vite:extendConfig', (config, { isClient }) => {
|
nuxt.hook('vite:extendConfig', (config, { isClient }) => {
|
||||||
const mode = isClient ? 'client' : 'server'
|
const mode = isClient ? 'client' : 'server'
|
||||||
;(config.resolve!.alias as any)['#components'] = resolve(nuxt.options.buildDir, `components.${mode}.mjs`)
|
; (config.resolve!.alias as any)['#components'] = resolve(nuxt.options.buildDir, `components.${mode}.mjs`)
|
||||||
})
|
})
|
||||||
nuxt.hook('webpack:config', (configs) => {
|
nuxt.hook('webpack:config', (configs) => {
|
||||||
for (const config of configs) {
|
for (const config of configs) {
|
||||||
const mode = config.name === 'server' ? 'server' : 'client'
|
const mode = config.name === 'server' ? 'server' : 'client'
|
||||||
;(config.resolve!.alias as any)['#components'] = resolve(nuxt.options.buildDir, `components.${mode}.mjs`)
|
; (config.resolve!.alias as any)['#components'] = resolve(nuxt.options.buildDir, `components.${mode}.mjs`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -173,7 +173,14 @@ export default defineNuxtModule<ComponentsOptions>({
|
|||||||
}
|
}
|
||||||
const fPath = resolve(nuxt.options.srcDir, path)
|
const fPath = resolve(nuxt.options.srcDir, path)
|
||||||
if (componentDirs.find(dir => fPath.startsWith(dir.path))) {
|
if (componentDirs.find(dir => fPath.startsWith(dir.path))) {
|
||||||
await nuxt.callHook('builder:generateApp')
|
await updateTemplates({
|
||||||
|
filter: template => [
|
||||||
|
'components.plugin.mjs',
|
||||||
|
'components.d.ts',
|
||||||
|
'components.server.mjs',
|
||||||
|
'components.client.mjs'
|
||||||
|
].includes(template.filename)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { promises as fsp } from 'node:fs'
|
import { promises as fsp } from 'node:fs'
|
||||||
import { dirname, resolve } from 'pathe'
|
import { dirname, resolve } from 'pathe'
|
||||||
import defu from 'defu'
|
import defu from 'defu'
|
||||||
import type { Nuxt, NuxtApp, NuxtPlugin, NuxtTemplate } from '@nuxt/schema'
|
import type { Nuxt, NuxtApp, NuxtPlugin, NuxtTemplate, ResolvedNuxtTemplate } from '@nuxt/schema'
|
||||||
import { findPath, resolveFiles, normalizePlugin, normalizeTemplate, compileTemplate, templateUtils, tryResolveModule, resolvePath, resolveAlias } from '@nuxt/kit'
|
import { findPath, resolveFiles, normalizePlugin, normalizeTemplate, compileTemplate, templateUtils, tryResolveModule, resolvePath, resolveAlias } from '@nuxt/kit'
|
||||||
|
|
||||||
import * as defaultTemplates from './templates'
|
import * as defaultTemplates from './templates'
|
||||||
@ -16,7 +16,7 @@ export function createApp (nuxt: Nuxt, options: Partial<NuxtApp> = {}): NuxtApp
|
|||||||
} as unknown as NuxtApp) as NuxtApp
|
} as unknown as NuxtApp) as NuxtApp
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateApp (nuxt: Nuxt, app: NuxtApp) {
|
export async function generateApp (nuxt: Nuxt, app: NuxtApp, options: { filter?: (template: ResolvedNuxtTemplate<any>) => boolean } = {}) {
|
||||||
// Resolve app
|
// Resolve app
|
||||||
await resolveApp(nuxt, app)
|
await resolveApp(nuxt, app)
|
||||||
|
|
||||||
@ -31,25 +31,27 @@ export async function generateApp (nuxt: Nuxt, app: NuxtApp) {
|
|||||||
|
|
||||||
// Compile templates into vfs
|
// Compile templates into vfs
|
||||||
const templateContext = { utils: templateUtils, nuxt, app }
|
const templateContext = { utils: templateUtils, nuxt, app }
|
||||||
await Promise.all(app.templates.map(async (template) => {
|
await Promise.all((app.templates as Array<ReturnType<typeof normalizeTemplate>>)
|
||||||
const contents = await compileTemplate(template, templateContext)
|
.filter(template => !options.filter || options.filter(template))
|
||||||
|
.map(async (template) => {
|
||||||
|
const contents = await compileTemplate(template, templateContext)
|
||||||
|
|
||||||
const fullPath = template.dst || resolve(nuxt.options.buildDir, template.filename!)
|
const fullPath = template.dst || resolve(nuxt.options.buildDir, template.filename!)
|
||||||
nuxt.vfs[fullPath] = contents
|
nuxt.vfs[fullPath] = contents
|
||||||
|
|
||||||
const aliasPath = '#build/' + template.filename!.replace(/\.\w+$/, '')
|
const aliasPath = '#build/' + template.filename!.replace(/\.\w+$/, '')
|
||||||
nuxt.vfs[aliasPath] = contents
|
nuxt.vfs[aliasPath] = contents
|
||||||
|
|
||||||
// In case a non-normalized absolute path is called for on Windows
|
// In case a non-normalized absolute path is called for on Windows
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
nuxt.vfs[fullPath.replace(/\//g, '\\')] = contents
|
nuxt.vfs[fullPath.replace(/\//g, '\\')] = contents
|
||||||
}
|
}
|
||||||
|
|
||||||
if (template.write) {
|
if (template.write) {
|
||||||
await fsp.mkdir(dirname(fullPath), { recursive: true })
|
await fsp.mkdir(dirname(fullPath), { recursive: true })
|
||||||
await fsp.writeFile(fullPath, contents, 'utf8')
|
await fsp.writeFile(fullPath, contents, 'utf8')
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
await nuxt.callHook('app:templatesGenerated', app)
|
await nuxt.callHook('app:templatesGenerated', app)
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,11 @@ export async function build (nuxt: Nuxt) {
|
|||||||
await generateApp()
|
await generateApp()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
nuxt.hook('builder:generateApp', generateApp)
|
nuxt.hook('builder:generateApp', (options) => {
|
||||||
|
// Bypass debounce if we are selectively invalidating templates
|
||||||
|
if (options) { return _generateApp(nuxt, app, options) }
|
||||||
|
return generateApp()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
await nuxt.callHook('build:before', { nuxt }, nuxt.options.build)
|
await nuxt.callHook('build:before', { nuxt }, nuxt.options.build)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { addVitePlugin, addWebpackPlugin, defineNuxtModule, addTemplate, resolveAlias, useNuxt, addPluginTemplate, logger } from '@nuxt/kit'
|
import { addVitePlugin, addWebpackPlugin, defineNuxtModule, addTemplate, resolveAlias, useNuxt, addPluginTemplate, logger, updateTemplates } from '@nuxt/kit'
|
||||||
import { isAbsolute, join, relative, resolve, normalize } from 'pathe'
|
import { isAbsolute, join, relative, resolve, normalize } from 'pathe'
|
||||||
import { createUnimport, Import, scanDirExports, toImports, Unimport } from 'unimport'
|
import { createUnimport, Import, scanDirExports, toImports, Unimport } from 'unimport'
|
||||||
import { ImportsOptions, ImportPresetWithDeprecation } from '@nuxt/schema'
|
import { ImportsOptions, ImportPresetWithDeprecation } from '@nuxt/schema'
|
||||||
@ -77,7 +77,6 @@ export default defineNuxtModule<Partial<ImportsOptions>>({
|
|||||||
nuxt.options.alias['#imports'] = join(nuxt.options.buildDir, 'imports')
|
nuxt.options.alias['#imports'] = join(nuxt.options.buildDir, 'imports')
|
||||||
|
|
||||||
// Transpile and injection
|
// Transpile and injection
|
||||||
// @ts-ignore temporary disabled due to #746
|
|
||||||
if (nuxt.options.dev && options.global) {
|
if (nuxt.options.dev && options.global) {
|
||||||
// Add all imports to globalThis in development mode
|
// Add all imports to globalThis in development mode
|
||||||
addPluginTemplate({
|
addPluginTemplate({
|
||||||
@ -117,10 +116,17 @@ export default defineNuxtModule<Partial<ImportsOptions>>({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Watch composables/ directory
|
// Watch composables/ directory
|
||||||
|
const templates = [
|
||||||
|
'types/imports.d.ts',
|
||||||
|
'imports.d.ts',
|
||||||
|
'imports.mjs'
|
||||||
|
]
|
||||||
nuxt.hook('builder:watch', async (_, path) => {
|
nuxt.hook('builder:watch', async (_, path) => {
|
||||||
const _resolved = resolve(nuxt.options.srcDir, path)
|
const _resolved = resolve(nuxt.options.srcDir, path)
|
||||||
if (composablesDirs.find(dir => _resolved.startsWith(dir))) {
|
if (composablesDirs.find(dir => _resolved.startsWith(dir))) {
|
||||||
await nuxt.callHook('builder:generateApp')
|
await updateTemplates({
|
||||||
|
filter: template => templates.includes(template.filename)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { existsSync } from 'node:fs'
|
import { existsSync } from 'node:fs'
|
||||||
import { defineNuxtModule, addTemplate, addPlugin, addVitePlugin, addWebpackPlugin, findPath, addComponent } from '@nuxt/kit'
|
import { defineNuxtModule, addTemplate, addPlugin, addVitePlugin, addWebpackPlugin, findPath, addComponent, updateTemplates } from '@nuxt/kit'
|
||||||
import { relative, resolve } from 'pathe'
|
import { relative, resolve } from 'pathe'
|
||||||
import { genString, genImport, genObjectFromRawEntries } from 'knitwork'
|
import { genString, genImport, genObjectFromRawEntries } from 'knitwork'
|
||||||
import escapeRE from 'escape-string-regexp'
|
import escapeRE from 'escape-string-regexp'
|
||||||
@ -48,7 +48,7 @@ export default defineNuxtModule({
|
|||||||
|
|
||||||
const pathPattern = new RegExp(`(^|\\/)(${dirs.map(escapeRE).join('|')})/`)
|
const pathPattern = new RegExp(`(^|\\/)(${dirs.map(escapeRE).join('|')})/`)
|
||||||
if (event !== 'change' && path.match(pathPattern)) {
|
if (event !== 'change' && path.match(pathPattern)) {
|
||||||
await nuxt.callHook('builder:generateApp')
|
await updateTemplates()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import type { InlineConfig as ViteInlineConfig, ViteDevServer } from 'vite'
|
|||||||
import type { Manifest } from 'vue-bundle-renderer'
|
import type { Manifest } from 'vue-bundle-renderer'
|
||||||
import type { EventHandler } from 'h3'
|
import type { EventHandler } from 'h3'
|
||||||
import type { ModuleContainer } from './module'
|
import type { ModuleContainer } from './module'
|
||||||
import type { NuxtTemplate, Nuxt, NuxtApp } from './nuxt'
|
import type { NuxtTemplate, Nuxt, NuxtApp, ResolvedNuxtTemplate } from './nuxt'
|
||||||
import type { Preset as ImportPreset, Import } from 'unimport'
|
import type { Preset as ImportPreset, Import } from 'unimport'
|
||||||
import type { NuxtConfig, NuxtOptions } from './config'
|
import type { NuxtConfig, NuxtOptions } from './config'
|
||||||
import type { Nitro, NitroConfig } from 'nitropack'
|
import type { Nitro, NitroConfig } from 'nitropack'
|
||||||
@ -66,6 +66,10 @@ export interface ImportPresetWithDeprecation extends ImportPreset {
|
|||||||
names?: string[]
|
names?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GenerateAppOptions {
|
||||||
|
filter?: (template: ResolvedNuxtTemplate<any>) => boolean
|
||||||
|
}
|
||||||
|
|
||||||
export interface NuxtHooks {
|
export interface NuxtHooks {
|
||||||
// Kit
|
// Kit
|
||||||
'kit:compatibility': (compatibility: NuxtCompatibility, issues: NuxtCompatibilityIssues) => HookResult
|
'kit:compatibility': (compatibility: NuxtCompatibility, issues: NuxtCompatibilityIssues) => HookResult
|
||||||
@ -74,7 +78,7 @@ export interface NuxtHooks {
|
|||||||
'app:resolve': (app: NuxtApp) => HookResult
|
'app:resolve': (app: NuxtApp) => HookResult
|
||||||
'app:templates': (app: NuxtApp) => HookResult
|
'app:templates': (app: NuxtApp) => HookResult
|
||||||
'app:templatesGenerated': (app: NuxtApp) => HookResult
|
'app:templatesGenerated': (app: NuxtApp) => HookResult
|
||||||
'builder:generateApp': () => HookResult
|
'builder:generateApp': (options?: GenerateAppOptions) => HookResult
|
||||||
'pages:extend': (pages: NuxtPage[]) => HookResult
|
'pages:extend': (pages: NuxtPage[]) => HookResult
|
||||||
'build:manifest': (manifest: Manifest) => HookResult
|
'build:manifest': (manifest: Manifest) => HookResult
|
||||||
'server:devHandler': (handler: EventHandler) => HookResult
|
'server:devHandler': (handler: EventHandler) => HookResult
|
||||||
|
Loading…
Reference in New Issue
Block a user