2021-07-15 10:18:34 +00:00
|
|
|
import { resolve, join, relative } from 'upath'
|
2021-05-20 11:42:41 +00:00
|
|
|
import globby from 'globby'
|
|
|
|
import lodashTemplate from 'lodash/template'
|
2020-08-19 12:38:18 +00:00
|
|
|
import defu from 'defu'
|
2021-07-28 11:35:24 +00:00
|
|
|
import { tryResolvePath, resolveFiles, Nuxt, NuxtApp, NuxtTemplate, normalizePlugin, normalizeTemplate } from '@nuxt/kit'
|
2021-07-15 10:18:34 +00:00
|
|
|
import { readFile } from 'fs-extra'
|
2021-05-20 11:42:41 +00:00
|
|
|
import * as templateUtils from './template.utils'
|
2021-04-02 11:47:01 +00:00
|
|
|
|
2021-05-20 11:42:41 +00:00
|
|
|
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,
|
2021-02-19 01:08:45 +00:00
|
|
|
plugins: [],
|
2021-07-28 11:35:24 +00:00
|
|
|
templates: []
|
2021-04-04 22:15:34 +00:00
|
|
|
} as NuxtApp)
|
2021-05-20 11:42:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export async function generateApp (nuxt: Nuxt, app: NuxtApp) {
|
|
|
|
// Resolve app
|
|
|
|
await resolveApp(nuxt, app)
|
|
|
|
|
2021-07-28 11:35:24 +00:00
|
|
|
// Scan app templates
|
2021-05-20 11:42:41 +00:00
|
|
|
const templatesDir = join(nuxt.options.appDir, '_templates')
|
|
|
|
const templateFiles = await globby(join(templatesDir, '/**'))
|
|
|
|
app.templates = templateFiles
|
|
|
|
.filter(src => !src.endsWith('.d.ts'))
|
2021-07-28 11:35:24 +00:00
|
|
|
.map(src => ({ src, filename: relative(templatesDir, src) } as NuxtTemplate))
|
2021-05-20 11:42:41 +00:00
|
|
|
|
2021-07-28 11:35:24 +00:00
|
|
|
// User templates from options.build.templates
|
|
|
|
app.templates = app.templates.concat(nuxt.options.build.templates)
|
2021-06-16 11:22:01 +00:00
|
|
|
|
2021-07-28 11:35:24 +00:00
|
|
|
// Extend templates with hook
|
2021-05-20 11:42:41 +00:00
|
|
|
await nuxt.callHook('app:templates', app)
|
|
|
|
|
2021-07-28 11:35:24 +00:00
|
|
|
// Normalize templates
|
|
|
|
app.templates = app.templates.map(tmpl => normalizeTemplate(tmpl))
|
|
|
|
|
2021-07-15 10:18:34 +00:00
|
|
|
// Compile templates into vfs
|
|
|
|
const templateContext = { utils: templateUtils, nuxt, app }
|
|
|
|
await Promise.all(app.templates.map(async (template) => {
|
|
|
|
const contents = await compileTemplate(template, templateContext)
|
|
|
|
|
2021-07-28 11:35:24 +00:00
|
|
|
const fullPath = template.dst || resolve(nuxt.options.buildDir, template.filename)
|
2021-07-15 10:18:34 +00:00
|
|
|
nuxt.vfs[fullPath] = contents
|
|
|
|
|
2021-07-28 11:35:24 +00:00
|
|
|
const aliasPath = '#build/' + template.filename.replace(/\.\w+$/, '')
|
2021-07-15 10:18:34 +00:00
|
|
|
nuxt.vfs[aliasPath] = contents
|
|
|
|
}))
|
2021-05-20 11:42:41 +00:00
|
|
|
|
|
|
|
await nuxt.callHook('app:templatesGenerated', app)
|
|
|
|
}
|
2020-08-19 12:38:18 +00:00
|
|
|
|
2021-05-20 11:42:41 +00:00
|
|
|
export async function resolveApp (nuxt: Nuxt, app: NuxtApp) {
|
2021-04-02 11:47:01 +00:00
|
|
|
const resolveOptions = {
|
|
|
|
base: nuxt.options.srcDir,
|
|
|
|
alias: nuxt.options.alias,
|
|
|
|
extensions: nuxt.options.extensions
|
|
|
|
}
|
|
|
|
|
2021-05-20 11:42:41 +00:00
|
|
|
// Resolve main (app.vue)
|
2020-08-19 13:06:27 +00:00
|
|
|
if (!app.main) {
|
2021-05-20 11:42:41 +00:00
|
|
|
app.main = tryResolvePath('~/App', resolveOptions) || tryResolvePath('~/app', resolveOptions)
|
2020-08-17 15:25:06 +00:00
|
|
|
}
|
2021-05-20 11:42:41 +00:00
|
|
|
if (!app.main) {
|
|
|
|
app.main = resolve(nuxt.options.appDir, 'app.tutorial.vue')
|
2021-01-18 12:22:38 +00:00
|
|
|
}
|
2021-05-20 11:42:41 +00:00
|
|
|
|
|
|
|
// Resolve plugins
|
|
|
|
app.plugins = [
|
|
|
|
...nuxt.options.plugins,
|
2021-07-28 11:35:24 +00:00
|
|
|
...await resolveFiles(nuxt.options.srcDir, 'plugins/**/*.{js,ts,mjs,cjs}')
|
|
|
|
].map(plugin => normalizePlugin(plugin))
|
2021-05-20 11:42:41 +00:00
|
|
|
|
|
|
|
// Extend app
|
|
|
|
await nuxt.callHook('app:resolve', app)
|
|
|
|
}
|
|
|
|
|
2021-07-28 11:35:24 +00:00
|
|
|
async function compileTemplate (template: NuxtTemplate, ctx: any) {
|
|
|
|
const data = { ...ctx, ...template.options }
|
|
|
|
if (template.src) {
|
2021-05-20 11:42:41 +00:00
|
|
|
try {
|
2021-07-28 11:35:24 +00:00
|
|
|
const srcContents = await readFile(template.src, 'utf-8')
|
2021-07-15 10:18:34 +00:00
|
|
|
return lodashTemplate(srcContents, {})(data)
|
2021-05-20 11:42:41 +00:00
|
|
|
} catch (err) {
|
2021-07-28 11:35:24 +00:00
|
|
|
console.error('Error compiling template: ', template)
|
2021-05-20 11:42:41 +00:00
|
|
|
throw err
|
2021-02-17 14:29:15 +00:00
|
|
|
}
|
2021-02-02 16:42:48 +00:00
|
|
|
}
|
2021-07-28 11:35:24 +00:00
|
|
|
if (template.getContents) {
|
|
|
|
return template.getContents(data)
|
2021-07-15 10:18:34 +00:00
|
|
|
}
|
2021-07-28 11:35:24 +00:00
|
|
|
throw new Error('Invalid template: ' + JSON.stringify(template))
|
2021-01-18 12:22:38 +00:00
|
|
|
}
|