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

79 lines
1.7 KiB
TypeScript
Raw Normal View History

import { resolve } from 'path'
2020-08-19 12:38:18 +00:00
import defu from 'defu'
2020-08-18 17:08:06 +00:00
import { Builder } from './builder'
2020-08-18 18:34:08 +00:00
import { NuxtRoute, resolvePagesRoutes } from './pages'
export interface NuxtApp {
2020-08-19 13:06:27 +00:00
main: string
routes: NuxtRoute[]
2020-08-19 13:06:27 +00:00
dir: string
extensions: string[]
templates: Record<string, string>
2020-08-19 13:06:27 +00:00
pages?: {
dir: string
}
2020-08-19 12:38:18 +00:00
}
// Scan project structure
export async function createApp (
builder: Builder,
options: Partial<NuxtApp> = {}
): Promise<NuxtApp> {
2020-08-18 17:08:06 +00:00
const { nuxt } = builder
2020-08-19 13:06:27 +00:00
// Create base app object
const app: NuxtApp = defu(options, {
dir: nuxt.options.srcDir,
extensions: nuxt.options.extensions,
routes: [],
templates: {},
2020-08-19 13:06:27 +00:00
pages: {
dir: 'pages'
}
2020-08-19 12:38:18 +00:00
})
2020-08-19 13:06:27 +00:00
// Resolve app.main
if (!app.main) {
app.main =
nuxt.resolver.tryResolvePath('~/App') ||
2020-08-19 15:28:04 +00:00
nuxt.resolver.tryResolvePath('~/app')
}
2020-08-18 17:08:06 +00:00
2020-08-18 18:34:08 +00:00
// Resolve pages/
2020-08-19 13:06:27 +00:00
if (app.pages) {
app.routes.push(...(await resolvePagesRoutes(builder, app)))
}
// TODO: Hook to extend routes
if (app.routes.length) {
app.templates.routes = serializeRoutes(app.routes)
2020-08-19 13:06:27 +00:00
}
2020-08-18 17:08:06 +00:00
2020-08-19 15:28:04 +00:00
// Fallback app.main
if (!app.main && app.routes.length) {
app.main = resolve(nuxt.options.appDir, 'app.pages.vue')
} else if (!app.main) {
app.main = resolve(nuxt.options.appDir, 'app.tutorial.vue')
}
2020-08-18 18:34:08 +00:00
return app
2020-08-18 17:08:06 +00:00
}
function serializeRoutes (routes: NuxtRoute[]) {
return JSON.stringify(
routes.map(formatRoute),
null,
2
).replace(/"{(.+)}"/g, '$1')
}
function formatRoute (route: NuxtRoute) {
return {
name: route.name,
path: route.path,
children: route.children.map(formatRoute),
// TODO: avoid exposing to prod
__file: route.file,
component: `{() => import('${route.file}' /* webpackChunkName: '${route.name}' */)}`
}
}