Nuxt/packages/nitro/src/build.ts

125 lines
4.3 KiB
TypeScript
Raw Normal View History

2020-11-20 00:16:31 +00:00
import { resolve, join } from 'upath'
2020-11-04 12:34:18 +00:00
import consola from 'consola'
2020-11-20 00:16:31 +00:00
import { rollup, watch as rollupWatch } from 'rollup'
import { readFile, emptyDir, copy } from 'fs-extra'
2020-11-14 20:41:38 +00:00
import { printFSTree } from './utils/tree'
2020-11-04 12:34:18 +00:00
import { getRollupConfig } from './rollup/config'
2020-12-07 12:48:29 +00:00
import { hl, prettyPath, serializeTemplate, writeFile, isDirectory } from './utils'
2021-01-22 19:55:59 +00:00
import { NitroContext } from './context'
import { scanMiddleware } from './server/middleware'
2020-11-04 12:34:18 +00:00
2021-01-22 19:55:59 +00:00
export async function prepare (nitroContext: NitroContext) {
consola.info(`Nitro preset is ${hl(nitroContext.preset)}`)
2020-11-04 12:34:18 +00:00
2021-01-22 19:55:59 +00:00
await cleanupDir(nitroContext.output.dir)
2020-11-20 00:16:31 +00:00
2021-01-22 19:55:59 +00:00
if (!nitroContext.output.publicDir.startsWith(nitroContext.output.dir)) {
await cleanupDir(nitroContext.output.publicDir)
}
2020-11-14 20:41:38 +00:00
2021-01-22 19:55:59 +00:00
if (!nitroContext.output.serverDir.startsWith(nitroContext.output.dir)) {
await cleanupDir(nitroContext.output.serverDir)
}
}
2020-11-20 00:16:31 +00:00
async function cleanupDir (dir: string) {
consola.info('Cleaning up', prettyPath(dir))
await emptyDir(dir)
2020-11-20 00:16:31 +00:00
}
2020-11-14 20:41:38 +00:00
2021-01-22 19:55:59 +00:00
export async function generate (nitroContext: NitroContext) {
consola.start('Generating public...')
2020-12-07 12:48:29 +00:00
2021-01-22 19:55:59 +00:00
const clientDist = resolve(nitroContext._nuxt.buildDir, 'dist/client')
2020-12-07 12:48:29 +00:00
if (await isDirectory(clientDist)) {
2021-01-22 19:55:59 +00:00
await copy(clientDist, join(nitroContext.output.publicDir, nitroContext._nuxt.publicPath))
2020-12-07 12:48:29 +00:00
}
2021-01-22 19:55:59 +00:00
const staticDir = resolve(nitroContext._nuxt.srcDir, nitroContext._nuxt.staticDir)
2020-12-07 12:48:29 +00:00
if (await isDirectory(staticDir)) {
2021-01-22 19:55:59 +00:00
await copy(staticDir, nitroContext.output.publicDir)
2020-12-07 12:48:29 +00:00
}
consola.success('Generated public ' + prettyPath(nitroContext.output.publicDir))
}
2021-01-22 19:55:59 +00:00
export async function build (nitroContext: NitroContext) {
// Compile html template
2021-01-22 19:55:59 +00:00
const htmlSrc = resolve(nitroContext._nuxt.buildDir, `views/${{ 2: 'app', 3: 'document' }[2]}.template.html`)
const htmlTemplate = { src: htmlSrc, contents: '', dst: '', compiled: '' }
htmlTemplate.dst = htmlTemplate.src.replace(/.html$/, '.js').replace('app.', 'document.')
htmlTemplate.contents = await readFile(htmlTemplate.src, 'utf-8')
2021-01-22 19:55:59 +00:00
await nitroContext._internal.hooks.callHook('nitro:template:document', htmlTemplate)
htmlTemplate.compiled = 'module.exports = ' + serializeTemplate(htmlTemplate.contents)
await writeFile(htmlTemplate.dst, htmlTemplate.compiled)
2021-01-22 19:55:59 +00:00
nitroContext.rollupConfig = getRollupConfig(nitroContext)
await nitroContext._internal.hooks.callHook('nitro:rollup:before', nitroContext)
return nitroContext._nuxt.dev ? _watch(nitroContext) : _build(nitroContext)
2020-11-20 00:16:31 +00:00
}
2021-01-22 19:55:59 +00:00
async function _build (nitroContext: NitroContext) {
nitroContext.scannedMiddleware = await scanMiddleware(nitroContext._nuxt.serverDir)
2020-11-20 00:16:31 +00:00
consola.start('Building server...')
2021-01-22 19:55:59 +00:00
const build = await rollup(nitroContext.rollupConfig).catch((error) => {
consola.error('Rollup error: ' + error.message)
2020-11-13 16:13:18 +00:00
throw error
})
2020-11-04 12:34:18 +00:00
consola.start('Writing server bundle...')
2021-01-22 19:55:59 +00:00
await build.write(nitroContext.rollupConfig.output)
2020-11-04 12:34:18 +00:00
consola.success('Server built')
2021-01-22 19:55:59 +00:00
await printFSTree(nitroContext.output.serverDir)
await nitroContext._internal.hooks.callHook('nitro:compiled', nitroContext)
return {
2021-01-22 19:55:59 +00:00
entry: resolve(nitroContext.rollupConfig.output.dir, nitroContext.rollupConfig.output.entryFileNames)
}
2020-11-04 12:34:18 +00:00
}
2020-11-20 00:16:31 +00:00
function startRollupWatcher (nitroContext: NitroContext) {
2021-01-22 19:55:59 +00:00
const watcher = rollupWatch(nitroContext.rollupConfig)
let start: number
2020-11-20 00:16:31 +00:00
watcher.on('event', (event) => {
switch (event.code) {
// The watcher is (re)starting
case 'START':
return
// Building an individual bundle
case 'BUNDLE_START':
start = Date.now()
return
// Finished building all bundles
case 'END':
2021-01-22 19:55:59 +00:00
nitroContext._internal.hooks.callHook('nitro:compiled', nitroContext)
consola.success('Nitro built', start ? `in ${Date.now() - start} ms` : '')
return
2020-11-20 00:16:31 +00:00
// Encountered an error while bundling
case 'ERROR':
consola.error('Rollup error: ' + event.error)
2020-11-20 00:16:31 +00:00
// consola.error(event.error)
}
})
return watcher
}
async function _watch (nitroContext: NitroContext) {
let watcher = startRollupWatcher(nitroContext)
nitroContext.scannedMiddleware = await scanMiddleware(nitroContext._nuxt.serverDir,
(middleware, event) => {
nitroContext.scannedMiddleware = middleware
if (['add', 'addDir'].includes(event)) {
watcher.close()
watcher = startRollupWatcher(nitroContext)
}
}
)
2020-11-20 00:16:31 +00:00
}