mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
fix(nuxt): compile plugin templates last (#27009)
This commit is contained in:
parent
54a9914ee6
commit
933c0aa71f
@ -20,6 +20,12 @@ export function createApp (nuxt: Nuxt, options: Partial<NuxtApp> = {}): NuxtApp
|
||||
} as unknown as NuxtApp) as NuxtApp
|
||||
}
|
||||
|
||||
const postTemplates = [
|
||||
defaultTemplates.clientPluginTemplate.filename,
|
||||
defaultTemplates.serverPluginTemplate.filename,
|
||||
defaultTemplates.pluginsDeclaration.filename,
|
||||
]
|
||||
|
||||
export async function generateApp (nuxt: Nuxt, app: NuxtApp, options: { filter?: (template: ResolvedNuxtTemplate<any>) => boolean } = {}) {
|
||||
// Resolve app
|
||||
await resolveApp(nuxt, app)
|
||||
@ -33,60 +39,74 @@ export async function generateApp (nuxt: Nuxt, app: NuxtApp, options: { filter?:
|
||||
// Normalize templates
|
||||
app.templates = app.templates.map(tmpl => normalizeTemplate(tmpl))
|
||||
|
||||
// compile plugins first as they are needed within the nuxt.vfs
|
||||
// in order to annotate templated plugins
|
||||
const filteredTemplates: Record<'pre' | 'post', Array<ResolvedNuxtTemplate<any>>> = {
|
||||
pre: [],
|
||||
post: [],
|
||||
}
|
||||
|
||||
for (const template of app.templates as Array<ResolvedNuxtTemplate<any>>) {
|
||||
if (options.filter && !options.filter(template)) { continue }
|
||||
const key = template.filename && postTemplates.includes(template.filename) ? 'post' : 'pre'
|
||||
filteredTemplates[key].push(template)
|
||||
}
|
||||
|
||||
// Compile templates into vfs
|
||||
// TODO: remove utils in v4
|
||||
const templateContext = { utils: templateUtils, nuxt, app }
|
||||
const filteredTemplates = (app.templates as Array<ResolvedNuxtTemplate<any>>)
|
||||
.filter(template => !options.filter || options.filter(template))
|
||||
|
||||
const compileTemplate = nuxt.options.experimental.compileTemplate ? _compileTemplate : futureCompileTemplate
|
||||
|
||||
const writes: Array<() => void> = []
|
||||
await Promise.allSettled(filteredTemplates
|
||||
.map(async (template) => {
|
||||
const fullPath = template.dst || resolve(nuxt.options.buildDir, template.filename!)
|
||||
const mark = performance.mark(fullPath)
|
||||
const oldContents = nuxt.vfs[fullPath]
|
||||
const contents = await compileTemplate(template, templateContext).catch((e) => {
|
||||
logger.error(`Could not compile template \`${template.filename}\`.`)
|
||||
logger.error(e)
|
||||
throw e
|
||||
const changedTemplates: Array<ResolvedNuxtTemplate<any>> = []
|
||||
|
||||
async function processTemplate (template: ResolvedNuxtTemplate) {
|
||||
const fullPath = template.dst || resolve(nuxt.options.buildDir, template.filename!)
|
||||
const mark = performance.mark(fullPath)
|
||||
const oldContents = nuxt.vfs[fullPath]
|
||||
const contents = await compileTemplate(template, templateContext).catch((e) => {
|
||||
logger.error(`Could not compile template \`${template.filename}\`.`)
|
||||
logger.error(e)
|
||||
throw e
|
||||
})
|
||||
|
||||
template.modified = oldContents !== contents
|
||||
if (template.modified) {
|
||||
nuxt.vfs[fullPath] = contents
|
||||
|
||||
const aliasPath = '#build/' + template.filename!.replace(/\.\w+$/, '')
|
||||
nuxt.vfs[aliasPath] = contents
|
||||
|
||||
// In case a non-normalized absolute path is called for on Windows
|
||||
if (process.platform === 'win32') {
|
||||
nuxt.vfs[fullPath.replace(/\//g, '\\')] = contents
|
||||
}
|
||||
|
||||
changedTemplates.push(template)
|
||||
}
|
||||
|
||||
const perf = performance.measure(fullPath, mark?.name) // TODO: remove when Node 14 reaches EOL
|
||||
const setupTime = perf ? Math.round((perf.duration * 100)) / 100 : 0 // TODO: remove when Node 14 reaches EOL
|
||||
|
||||
if (nuxt.options.debug || setupTime > 500) {
|
||||
logger.info(`Compiled \`${template.filename}\` in ${setupTime}ms`)
|
||||
}
|
||||
|
||||
if (template.modified && template.write) {
|
||||
writes.push(() => {
|
||||
mkdirSync(dirname(fullPath), { recursive: true })
|
||||
writeFileSync(fullPath, contents, 'utf8')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
template.modified = oldContents !== contents
|
||||
if (template.modified) {
|
||||
nuxt.vfs[fullPath] = contents
|
||||
|
||||
const aliasPath = '#build/' + template.filename!.replace(/\.\w+$/, '')
|
||||
nuxt.vfs[aliasPath] = contents
|
||||
|
||||
// In case a non-normalized absolute path is called for on Windows
|
||||
if (process.platform === 'win32') {
|
||||
nuxt.vfs[fullPath.replace(/\//g, '\\')] = contents
|
||||
}
|
||||
}
|
||||
|
||||
const perf = performance.measure(fullPath, mark?.name) // TODO: remove when Node 14 reaches EOL
|
||||
const setupTime = perf ? Math.round((perf.duration * 100)) / 100 : 0 // TODO: remove when Node 14 reaches EOL
|
||||
|
||||
if (nuxt.options.debug || setupTime > 500) {
|
||||
logger.info(`Compiled \`${template.filename}\` in ${setupTime}ms`)
|
||||
}
|
||||
|
||||
if (template.modified && template.write) {
|
||||
writes.push(() => {
|
||||
mkdirSync(dirname(fullPath), { recursive: true })
|
||||
writeFileSync(fullPath, contents, 'utf8')
|
||||
})
|
||||
}
|
||||
}))
|
||||
await Promise.allSettled(filteredTemplates.pre.map(processTemplate))
|
||||
await Promise.allSettled(filteredTemplates.post.map(processTemplate))
|
||||
|
||||
// Write template files in single synchronous step to avoid (possible) additional
|
||||
// runtime overhead of cascading HMRs from vite/webpack
|
||||
for (const write of writes) { write() }
|
||||
|
||||
const changedTemplates = filteredTemplates.filter(t => t.modified)
|
||||
|
||||
if (changedTemplates.length) {
|
||||
await nuxt.callHook('app:templatesGenerated', app, changedTemplates, options)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user