diff --git a/packages/nitro/src/build.ts b/packages/nitro/src/build.ts index 9f4397e155..6d223c0fc8 100644 --- a/packages/nitro/src/build.ts +++ b/packages/nitro/src/build.ts @@ -8,43 +8,41 @@ import chalk from 'chalk' import { emptyDir } from 'fs-extra' import { getRollupConfig } from './rollup/config' import { hl, prettyPath, renderTemplate, compileTemplateToJS } from './utils' -import { getTargetConfig, SLSConfig } from './config' +import { SLSOptions } from './config' -export async function build (baseConfig, target) { +export async function build (options: SLSOptions) { console.log('\n') - consola.info(`Generating bundle for ${hl(target.target)}`) - - const config: any = getTargetConfig(baseConfig, target) + consola.info(`Generating bundle for ${hl(options.target)}`) const hooks = new Hookable() - hooks.addHooks(config.hooks) + hooks.addHooks(options.hooks) - await hooks.callHook('config', config) + await hooks.callHook('options', options) - emptyDir(config.targetDir) + emptyDir(options.targetDir) - config.rollupConfig = getRollupConfig(config) - await hooks.callHook('rollup:before', config) - const build = await rollup(config.rollupConfig) + options.rollupConfig = getRollupConfig(options) + await hooks.callHook('rollup:before', options) + const build = await rollup(options.rollupConfig) - const { output } = await build.write(config.rollupConfig.output as OutputOptions) + const { output } = await build.write(options.rollupConfig.output as OutputOptions) const size = prettyBytes(output[0].code.length) const zSize = prettyBytes(await gzipSize(output[0].code)) - consola.success('Generated', prettyPath((config.rollupConfig.output as any).file), + consola.success('Generated', prettyPath((options.rollupConfig.output as any).file), chalk.gray(`(Size: ${size} Gzip: ${zSize})`) ) - for (const tmpl of config.templates) { - const dstPath = resolve(config.targetDir, tmpl.dst) - await renderTemplate(tmpl.src, dstPath, { config }) + for (const tmpl of options.templates) { + const dstPath = resolve(options.targetDir, tmpl.dst) + await renderTemplate(tmpl.src, dstPath, { options }) consola.info('Compiled', prettyPath(dstPath)) } - await hooks.callHook('done', config) + await hooks.callHook('done', options) } -export async function compileHTMLTemplate (baseConfig: SLSConfig) { - const htmlTemplateFile = resolve(baseConfig.buildDir, `views/${{ 2: 'app', 3: 'document' }[baseConfig.nuxt]}.template.html`) +export async function compileHTMLTemplate (options: SLSOptions) { + const htmlTemplateFile = resolve(options.buildDir, `views/${{ 2: 'app', 3: 'document' }[options.nuxt]}.template.html`) const htmlTemplateFileJS = htmlTemplateFile.replace(/.html$/, '.js').replace('app.', 'document.') await compileTemplateToJS(htmlTemplateFile, htmlTemplateFileJS) consola.info('Generated', prettyPath(htmlTemplateFileJS)) diff --git a/packages/nitro/src/config.ts b/packages/nitro/src/config.ts index 3c7882341d..a42c9a8860 100644 --- a/packages/nitro/src/config.ts +++ b/packages/nitro/src/config.ts @@ -3,77 +3,61 @@ import defu from 'defu' import { NuxtOptions } from '@nuxt/types' import { tryImport, LIB_DIR } from './utils' -export interface SLSConfig { +export interface SLSOptions { node: false + target: 'vercel' | 'cloudflare' | 'node' | 'sw' | string entry: string outDir: string slsDir: string outName: string logStartup: boolean + inlineChunks: boolean buildDir: string publicDir: string staticDir: string + targetDir: string rootDir: string - targets: ((SLSConfig & { target: string }) | string)[] - target: string - templates: string[] + templates: { src: string, dst: string }[] + static: string[] renderer: string nuxt: 2 | 3 analyze: boolean minify: boolean + rollupConfig?: any + hooks: { [key: string]: any } // TODO: export from hookable } -export function getBaseConfig (options: NuxtOptions): SLSConfig { - const baseConfig = { - rootDir: options.rootDir, - buildDir: options.buildDir, - publicDir: options.generate.dir, - slsDir: null, - targets: [], +export interface SLSConfig extends Partial {} + +export function getoptions (nuxtOptions: NuxtOptions): SLSOptions { + const defaults: SLSConfig = { + rootDir: nuxtOptions.rootDir, + buildDir: nuxtOptions.buildDir, + publicDir: nuxtOptions.generate.dir, + outName: 'index.js', templates: [], - static: [ - '/about' - ], + static: [], nuxt: 2, - target: null, - minify: null, - analyze: null, logStartup: true, - ...options.serverless + inlineChunks: false } - baseConfig.buildDir = resolve(baseConfig.rootDir, baseConfig.buildDir || '.nuxt') - baseConfig.publicDir = resolve(baseConfig.rootDir, baseConfig.publicDir || 'dist') - baseConfig.slsDir = resolve(baseConfig.rootDir, baseConfig.slsDir || '.sls') - - baseConfig.targets = baseConfig.targets.map(t => typeof t === 'string' ? { target: t } : t) - if (baseConfig.target && !baseConfig.targets.find(t => t.target === baseConfig.target)) { - baseConfig.targets.push({ target: baseConfig.target }) + let target = nuxtOptions.serverless.target || process.env.SLS_TARGET || 'node' + if (typeof target === 'function') { + target = target(nuxtOptions) + } + let targetDefaults = tryImport(LIB_DIR, `./targets/${target}`) || tryImport(nuxtOptions.rootDir, target) + targetDefaults = targetDefaults.default || targetDefaults + if (!targetDefaults) { + throw new Error('Cannot resolve target: ' + target) } - return baseConfig -} - -export function getTargetConfig (baseConfig: SLSConfig, target: SLSConfig) { - const _targetDefaults = tryImport(LIB_DIR, `./targets/${target.target}`) || - tryImport(baseConfig.rootDir, target.target) - if (!_targetDefaults) { - throw new Error('Cannot resolve target: ' + target.target) - } - - // TODO: Merge hooks - - return defu( - // Target specific config by user - target, - // Global user config - baseConfig, - // Target defaults - _targetDefaults, - // Generic defaults - { - targetDir: resolve(baseConfig.slsDir, target.target), - outName: 'index.js' - } - ) + const options: SLSOptions = defu(nuxtOptions.serverless, targetDefaults, defaults, { target }) + + options.buildDir = resolve(options.rootDir, options.buildDir || '.nuxt') + options.publicDir = resolve(options.rootDir, options.publicDir || 'dist') + options.slsDir = resolve(options.rootDir, options.slsDir || '.sls') + options.targetDir = resolve(options.slsDir, target) + + return options } diff --git a/packages/nitro/src/index.ts b/packages/nitro/src/index.ts index a9839ab8d9..8219c15c62 100644 --- a/packages/nitro/src/index.ts +++ b/packages/nitro/src/index.ts @@ -1,6 +1,6 @@ import type { Module } from '@nuxt/types' import { build, compileHTMLTemplate } from './build' -import { getBaseConfig } from './config' +import { getoptions } from './config' export default function slsModule () { const { nuxt } = this @@ -10,37 +10,32 @@ export default function slsModule () { } // Config - const baseConfig = getBaseConfig(nuxt.options) + const options = getoptions(nuxt.options) - if (baseConfig.minify !== false) { + if (options.minify !== false) { nuxt.options.build._minifyServer = true } nuxt.options.build.standalone = true nuxt.hook('generate:cache:ignore', (ignore) => { - ignore.push(baseConfig.slsDir) + ignore.push(options.slsDir) }) nuxt.hook('generate:page', (page) => { // TODO: Use ssrContext - if (!baseConfig.static.includes(page.route)) { + if (!options.static.includes(page.route)) { page.exclude = true } }) - nuxt.hook('generate:done', () => buildSLS(baseConfig)) + nuxt.hook('generate:done', () => buildSLS(options)) } -async function buildSLS (baseConfig) { +async function buildSLS (options) { // Compile html template - await compileHTMLTemplate(baseConfig) + await compileHTMLTemplate(options) - // Bundle for each target - for (const target of baseConfig.targets) { - if (baseConfig.target && target.target !== baseConfig.target) { - continue - } - await build(baseConfig, target) - } + // Bundle target + await build(options) } diff --git a/packages/nitro/src/rollup/config.ts b/packages/nitro/src/rollup/config.ts index 6f9fd1e6e8..aef1d40f6b 100644 --- a/packages/nitro/src/rollup/config.ts +++ b/packages/nitro/src/rollup/config.ts @@ -9,13 +9,13 @@ import json from '@rollup/plugin-json' import replace from '@rollup/plugin-replace' import analyze from 'rollup-plugin-analyzer' -import { SLSConfig } from '../config' +import { SLSOptions } from '../config' import { RUNTIME_DIR } from '../utils' import dynamicRequire from './dynamic-require' export type RollupConfig = InputOptions & { output: OutputOptions } -export const getRollupConfig = (config: SLSConfig) => { +export const getRollupConfig = (config: SLSOptions) => { const mocks = [ // @nuxt/devalue 'consola',