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-05-20 11:42:41 +00:00
|
|
|
import { tryResolvePath, resolveFiles, Nuxt, NuxtApp, NuxtTemplate, NuxtPlugin } 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-05-20 11:42:41 +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)
|
|
|
|
|
|
|
|
// Scan templates
|
|
|
|
const templatesDir = join(nuxt.options.appDir, '_templates')
|
|
|
|
const templateFiles = await globby(join(templatesDir, '/**'))
|
|
|
|
app.templates = templateFiles
|
|
|
|
.filter(src => !src.endsWith('.d.ts'))
|
|
|
|
.map(src => ({
|
|
|
|
src,
|
|
|
|
path: relative(templatesDir, src),
|
|
|
|
data: {}
|
|
|
|
} as NuxtTemplate))
|
|
|
|
|
2021-06-16 11:22:01 +00:00
|
|
|
// Custom templates (created with addTemplate)
|
|
|
|
const customTemplates = nuxt.options.build.templates.map(t => ({
|
|
|
|
path: t.dst,
|
|
|
|
src: t.src,
|
|
|
|
data: {
|
|
|
|
options: t.options
|
|
|
|
}
|
|
|
|
}))
|
|
|
|
app.templates = app.templates.concat(customTemplates)
|
|
|
|
|
2021-05-20 11:42:41 +00:00
|
|
|
// Extend templates
|
|
|
|
await nuxt.callHook('app:templates', app)
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
const fullPath = resolve(nuxt.options.buildDir, template.path)
|
|
|
|
nuxt.vfs[fullPath] = contents
|
|
|
|
|
|
|
|
const aliasPath = '#build/' + template.path.replace(/\.\w+$/, '')
|
|
|
|
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,
|
|
|
|
...await resolvePlugins(nuxt)
|
|
|
|
]
|
|
|
|
|
|
|
|
// Extend app
|
|
|
|
await nuxt.callHook('app:resolve', app)
|
|
|
|
}
|
|
|
|
|
2021-07-15 10:18:34 +00:00
|
|
|
async function compileTemplate (tmpl: NuxtTemplate, ctx: any) {
|
2021-05-20 11:42:41 +00:00
|
|
|
const data = { ...ctx, ...tmpl.data }
|
|
|
|
if (tmpl.src) {
|
|
|
|
try {
|
|
|
|
const srcContents = await readFile(tmpl.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) {
|
|
|
|
console.error('Error compiling template: ', tmpl)
|
|
|
|
throw err
|
2021-02-17 14:29:15 +00:00
|
|
|
}
|
2021-02-02 16:42:48 +00:00
|
|
|
}
|
2021-07-15 10:18:34 +00:00
|
|
|
if (tmpl.compile) {
|
|
|
|
return tmpl.compile(data)
|
|
|
|
}
|
|
|
|
throw new Error('Invalid template:' + tmpl)
|
2021-05-20 11:42:41 +00:00
|
|
|
}
|
2020-08-18 17:08:06 +00:00
|
|
|
|
2021-05-20 11:42:41 +00:00
|
|
|
async function resolvePlugins (nuxt: Nuxt) {
|
|
|
|
const plugins = await resolveFiles(nuxt.options.srcDir, 'plugins/**/*.{js,ts}')
|
2020-08-19 15:28:04 +00:00
|
|
|
|
2021-05-20 11:42:41 +00:00
|
|
|
return plugins.map(src => ({
|
|
|
|
src,
|
|
|
|
mode: getPluginMode(src)
|
|
|
|
})
|
|
|
|
)
|
|
|
|
}
|
2021-01-18 12:22:38 +00:00
|
|
|
|
2021-05-20 11:42:41 +00:00
|
|
|
function getPluginMode (src: string) {
|
|
|
|
const [, mode = 'all'] = src.match(/\.(server|client)(\.\w+)*$/) || []
|
|
|
|
return mode as NuxtPlugin['mode']
|
2021-01-18 12:22:38 +00:00
|
|
|
}
|