2020-08-18 12:27:51 +00:00
|
|
|
import { join, relative } from 'path'
|
2020-08-17 18:02:10 +00:00
|
|
|
import fsExtra from 'fs-extra'
|
2020-08-17 19:12:34 +00:00
|
|
|
import consola from 'consola'
|
2020-08-18 12:27:51 +00:00
|
|
|
import { debounce } from 'lodash'
|
2020-08-04 10:06:44 +00:00
|
|
|
import { BundleBuilder } from 'src/webpack'
|
2020-08-17 15:25:06 +00:00
|
|
|
import { Nuxt } from '../core'
|
2020-08-18 12:27:51 +00:00
|
|
|
import {
|
|
|
|
templateData,
|
|
|
|
compileTemplates,
|
|
|
|
scanTemplates,
|
|
|
|
NuxtTemplate
|
|
|
|
} from './template'
|
2020-08-17 18:02:10 +00:00
|
|
|
import { createWatcher } from './watch'
|
2020-08-17 15:25:06 +00:00
|
|
|
import { resolveApp, NuxtApp } from './app'
|
2020-08-18 12:27:51 +00:00
|
|
|
import Ignore from './ignore'
|
2020-07-02 13:02:35 +00:00
|
|
|
|
2020-08-17 15:25:06 +00:00
|
|
|
export class Builder {
|
2020-07-30 23:40:16 +00:00
|
|
|
nuxt: Nuxt
|
2020-08-17 15:25:06 +00:00
|
|
|
app: NuxtApp
|
2020-08-17 18:02:10 +00:00
|
|
|
templates: NuxtTemplate[]
|
2020-08-04 10:26:22 +00:00
|
|
|
|
2020-08-17 15:25:06 +00:00
|
|
|
constructor (nuxt) {
|
2020-07-02 13:02:35 +00:00
|
|
|
this.nuxt = nuxt
|
|
|
|
}
|
|
|
|
|
2020-08-17 15:25:06 +00:00
|
|
|
build () {
|
|
|
|
return build(this)
|
2020-07-02 13:02:35 +00:00
|
|
|
}
|
2020-08-17 15:25:06 +00:00
|
|
|
}
|
2020-07-02 13:02:35 +00:00
|
|
|
|
2020-08-17 15:25:06 +00:00
|
|
|
// Extends VueRouter
|
2020-08-17 18:45:32 +00:00
|
|
|
async function build (builder: Builder) {
|
2020-08-17 15:25:06 +00:00
|
|
|
const { nuxt } = builder
|
2020-07-02 13:02:35 +00:00
|
|
|
|
2020-08-17 18:02:10 +00:00
|
|
|
await generate(builder)
|
|
|
|
|
|
|
|
if (nuxt.options.dev) {
|
|
|
|
watch(builder)
|
|
|
|
}
|
2020-07-02 13:02:35 +00:00
|
|
|
|
2020-08-17 15:25:06 +00:00
|
|
|
await bundle(builder)
|
2020-07-02 13:02:35 +00:00
|
|
|
}
|
|
|
|
|
2020-08-17 18:45:32 +00:00
|
|
|
function watch (builder: Builder) {
|
2020-08-17 18:02:10 +00:00
|
|
|
const { nuxt } = builder
|
2020-08-18 12:27:51 +00:00
|
|
|
const ignore = new Ignore({
|
|
|
|
rootDir: nuxt.options.srcDir,
|
|
|
|
ignoreArray: nuxt.options.ignore.concat(
|
|
|
|
relative(nuxt.options.rootDir, nuxt.options.buildDir)
|
|
|
|
)
|
|
|
|
})
|
2020-08-17 18:02:10 +00:00
|
|
|
|
|
|
|
// Watch internal templates
|
2020-08-18 12:27:51 +00:00
|
|
|
const options = nuxt.options.watchers.chokidar
|
|
|
|
const nuxtAppWatcher = createWatcher(nuxt.options.appDir, options, ignore)
|
2020-08-17 18:02:10 +00:00
|
|
|
nuxtAppWatcher.watchAll(async () => {
|
2020-08-17 19:12:34 +00:00
|
|
|
consola.log('Re-generate templates')
|
2020-08-17 18:02:10 +00:00
|
|
|
await compileTemplates(builder.templates, nuxt.options.buildDir)
|
|
|
|
})
|
|
|
|
|
|
|
|
// Watch user app
|
2020-08-18 12:27:51 +00:00
|
|
|
const appWatcher = createWatcher(builder.app.srcDir, options, ignore)
|
|
|
|
// Watch for App.vue creation
|
|
|
|
// appWatcher.debug('srcDir')
|
|
|
|
appWatcher.watch(
|
|
|
|
/^(A|a)pp\.[a-z]{2,3}/,
|
|
|
|
debounce(({ event }) => {
|
|
|
|
if (['add', 'unlink'].includes(event)) {
|
|
|
|
generate(builder)
|
|
|
|
}
|
|
|
|
}, 50)
|
|
|
|
)
|
|
|
|
// Watch for page changes
|
2020-08-17 18:02:10 +00:00
|
|
|
appWatcher.watch('pages/', async () => {
|
2020-08-17 19:12:34 +00:00
|
|
|
consola.log('Re-generate routes')
|
2020-08-17 18:02:10 +00:00
|
|
|
await compileTemplates(builder.templates, nuxt.options.buildDir)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-08-17 18:45:32 +00:00
|
|
|
export async function generate (builder: Builder) {
|
2020-08-17 18:02:10 +00:00
|
|
|
const { nuxt } = builder
|
|
|
|
|
|
|
|
await fsExtra.mkdirp(nuxt.options.buildDir)
|
|
|
|
builder.app = resolveApp(nuxt, nuxt.options.srcDir)
|
|
|
|
|
|
|
|
const templatesDir = join(builder.nuxt.options.appDir, '_templates')
|
2020-08-18 12:27:51 +00:00
|
|
|
const appTemplates = await scanTemplates(templatesDir, templateData(builder))
|
2020-08-17 18:02:10 +00:00
|
|
|
|
2020-08-18 12:27:51 +00:00
|
|
|
builder.templates = [...appTemplates]
|
2020-08-17 18:02:10 +00:00
|
|
|
|
|
|
|
await compileTemplates(builder.templates, nuxt.options.buildDir)
|
|
|
|
}
|
|
|
|
|
2020-08-17 15:25:06 +00:00
|
|
|
async function bundle ({ nuxt }: Builder) {
|
|
|
|
// TODO: get rid of this context and directly pass nuxt to BundleBuilder
|
|
|
|
const bundleBuilder = new BundleBuilder({
|
|
|
|
nuxt,
|
|
|
|
options: nuxt.options,
|
|
|
|
buildOptions: nuxt.options.build,
|
|
|
|
target: nuxt.options.target,
|
|
|
|
plugins: []
|
|
|
|
})
|
|
|
|
await bundleBuilder.build()
|
|
|
|
}
|