Nuxt/packages/nuxt3/src/core/app.ts

97 lines
2.9 KiB
TypeScript
Raw Normal View History

import { resolve } from 'pathe'
import lodashTemplate from 'lodash/template'
2020-08-19 12:38:18 +00:00
import defu from 'defu'
import { tryResolvePath, resolveFiles, Nuxt, NuxtApp, NuxtTemplate, normalizePlugin, normalizeTemplate } from '@nuxt/kit'
import { readFile, writeFile } from 'fs-extra'
import * as defaultTemplates from '../app/templates'
import * as templateUtils from './template.utils'
export function createApp (nuxt: Nuxt, options: Partial<NuxtApp> = {}): NuxtApp {
return defu(options, {
2020-08-19 13:06:27 +00:00
dir: nuxt.options.srcDir,
extensions: nuxt.options.extensions,
plugins: [],
templates: []
} as NuxtApp)
}
export async function generateApp (nuxt: Nuxt, app: NuxtApp) {
// Resolve app
await resolveApp(nuxt, app)
// User templates from options.build.templates
app.templates = Object.values(defaultTemplates).concat(nuxt.options.build.templates)
// Extend templates with hook
await nuxt.callHook('app:templates', app)
// Normalize templates
app.templates = app.templates.map(tmpl => normalizeTemplate(tmpl))
// Compile templates into vfs
const templateContext = { utils: templateUtils, nuxt, app }
await Promise.all(app.templates.map(async (template) => {
const contents = await compileTemplate(template, templateContext)
const fullPath = template.dst || resolve(nuxt.options.buildDir, template.filename)
nuxt.vfs[fullPath] = contents
const aliasPath = '#build/' + template.filename.replace(/\.\w+$/, '')
nuxt.vfs[aliasPath] = contents
2021-08-09 18:24:52 +00:00
// In case a non-normalized absolute path is called for on Windows
if (process.platform === 'win32') {
nuxt.vfs[fullPath.replace(/\//g, '\\')] = contents
}
if (template.write) {
await writeFile(fullPath, contents, 'utf8')
}
}))
await nuxt.callHook('app:templatesGenerated', app)
}
2020-08-19 12:38:18 +00:00
export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
const resolveOptions = {
base: nuxt.options.srcDir,
alias: nuxt.options.alias,
extensions: nuxt.options.extensions
}
// Resolve main (app.vue)
2020-08-19 13:06:27 +00:00
if (!app.main) {
app.main = tryResolvePath('~/App', resolveOptions) || tryResolvePath('~/app', resolveOptions)
}
if (!app.main) {
app.main = resolve(nuxt.options.appDir, 'app.tutorial.vue')
}
// Resolve plugins
app.plugins = [
...nuxt.options.plugins,
...await resolveFiles(nuxt.options.srcDir, 'plugins/**/*.{js,ts,mjs,cjs}')
].map(plugin => normalizePlugin(plugin))
// Extend app
await nuxt.callHook('app:resolve', app)
}
async function compileTemplate (template: NuxtTemplate, ctx: any) {
const data = { ...ctx, ...template.options }
if (template.src) {
try {
const srcContents = await readFile(template.src, 'utf-8')
return lodashTemplate(srcContents, {})(data)
} catch (err) {
console.error('Error compiling template: ', template)
throw err
}
2021-02-02 16:42:48 +00:00
}
if (template.getContents) {
return template.getContents(data)
}
throw new Error('Invalid template: ' + JSON.stringify(template))
}