Nuxt/packages/nuxt3/src/builder.ts

118 lines
3.3 KiB
TypeScript
Raw Normal View History

import { join, relative, resolve } from 'upath'
2020-08-17 18:02:10 +00:00
import fsExtra from 'fs-extra'
import { debounce } from 'lodash'
import { Nuxt } from '@nuxt/kit'
import {
templateData,
compileTemplates,
scanTemplates,
NuxtTemplate
} from './template'
import { createWatcher, WatchCallback } from './watch'
2020-08-19 13:11:52 +00:00
import { createApp, NuxtApp } from './app'
2021-03-29 09:33:38 +00:00
import Ignore from './utils/ignore'
2020-07-02 13:02:35 +00:00
export class Builder {
2020-07-30 23:40:16 +00:00
nuxt: Nuxt
globals: any
2020-08-18 17:08:06 +00:00
ignore: Ignore
2020-08-17 18:02:10 +00:00
templates: NuxtTemplate[]
2020-10-01 10:11:15 +00:00
app: NuxtApp
2020-08-04 10:26:22 +00:00
constructor (nuxt: Nuxt) {
2020-07-02 13:02:35 +00:00
this.nuxt = nuxt
2020-08-18 17:08:06 +00:00
this.ignore = new Ignore({
rootDir: nuxt.options.srcDir,
ignoreArray: nuxt.options.ignore.concat(
relative(nuxt.options.rootDir, nuxt.options.buildDir)
)
})
2020-07-02 13:02:35 +00:00
}
build () {
return _build(this)
2020-07-02 13:02:35 +00:00
}
2020-10-01 10:11:15 +00:00
close () {
// TODO: close watchers
}
}
2020-07-02 13:02:35 +00:00
// Extends VueRouter
async function _build (builder: Builder) {
const { nuxt } = builder
2020-07-02 13:02:35 +00:00
2021-04-15 19:17:44 +00:00
if (!nuxt.options.dev) {
await fsExtra.emptyDir(nuxt.options.buildDir)
}
await fsExtra.emptyDir(resolve(nuxt.options.buildDir, 'dist'))
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
await bundle(builder)
2021-01-18 11:49:50 +00:00
await nuxt.callHook('build:done', builder)
2020-07-02 13:02:35 +00:00
}
2020-08-17 18:45:32 +00:00
function watch (builder: Builder) {
2020-08-18 17:08:06 +00:00
const { nuxt, ignore } = builder
2020-08-17 18:02:10 +00:00
// Watch internal templates
const options = nuxt.options.watchers.chokidar
2020-08-18 17:08:06 +00:00
const nuxtAppWatcher = createWatcher(nuxt.options.appDir, { ...options, cwd: nuxt.options.appDir }, ignore)
nuxtAppWatcher.watchAll(debounce(() => compileTemplates(builder.templates, nuxt.options.buildDir), 100))
2020-08-17 18:02:10 +00:00
// Watch user app
// TODO: handle multiples app dirs
const appPattern = `${builder.app.dir}/**/*{${nuxt.options.extensions.join(',')}}`
2020-08-19 13:11:52 +00:00
const appWatcher = createWatcher(appPattern, { ...options, cwd: builder.app.dir }, ignore)
// appWatcher.debug('srcDir')
2020-08-18 17:08:06 +00:00
const refreshTemplates = debounce(() => generate(builder), 100)
// Watch for App.vue creation
appWatcher.watch(/^(A|a)pp\.[a-z]{2,3}/, refreshTemplates, ['add', 'unlink'])
// Watch for page changes
2020-08-18 17:08:06 +00:00
appWatcher.watch(new RegExp(`^${nuxt.options.dir.pages}/`), refreshTemplates, ['add', 'unlink'])
// Watch for plugins changes
appWatcher.watch(/^plugins/, refreshTemplates, ['add', 'unlink'])
// Shared Watcher
const watchHook: WatchCallback = (event, path) => builder.nuxt.callHook('builder:watch', event, path)
const watchHookDebounced = debounce(watchHook, 100)
appWatcher.watchAll(watchHookDebounced)
nuxtAppWatcher.watchAll(watchHookDebounced)
2020-08-17 18:02:10 +00:00
}
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
2020-08-19 13:11:52 +00:00
builder.app = await createApp(builder)
// Todo: Call app:created hook
2020-08-17 18:02:10 +00:00
const templatesDir = join(builder.nuxt.options.appDir, '_templates')
const appTemplates = await scanTemplates(templatesDir, templateData(builder))
// Todo: Call app:templates hook
2020-08-17 18:02:10 +00:00
builder.templates = [...appTemplates]
2020-08-17 18:02:10 +00:00
await compileTemplates(builder.templates, nuxt.options.buildDir)
}
async function bundle ({ nuxt }: Builder) {
// @ts-ignore
const useVite = !!nuxt.options.vite
const { bundle } = await (useVite ? import('@nuxt/vite-builder') : import('@nuxt/webpack-builder'))
return bundle(nuxt)
}
export function getBuilder (nuxt: Nuxt) {
return new Builder(nuxt)
}
export function build (nuxt: Nuxt) {
return getBuilder(nuxt).build()
}