mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
refactor: move targets to src, remove template and improve runtime
This commit is contained in:
parent
ddccc9cb78
commit
47d7644b72
@ -5,9 +5,9 @@ import Hookable from 'hookable'
|
||||
import prettyBytes from 'pretty-bytes'
|
||||
import gzipSize from 'gzip-size'
|
||||
import chalk from 'chalk'
|
||||
import { emptyDir } from 'fs-extra'
|
||||
import { emptyDir, readFile } from 'fs-extra'
|
||||
import { getRollupConfig } from './rollup/config'
|
||||
import { hl, prettyPath, renderTemplate, compileTemplateToJS, writeFileP } from './utils'
|
||||
import { hl, prettyPath, serializeTemplate, writeFileP } from './utils'
|
||||
import { SLSOptions } from './config'
|
||||
|
||||
export async function build (options: SLSOptions) {
|
||||
@ -18,13 +18,11 @@ export async function build (options: SLSOptions) {
|
||||
hooks.addHooks(options.hooks)
|
||||
|
||||
// Compile html template
|
||||
const htmlTemplate = {
|
||||
src: resolve(options.buildDir, `views/${{ 2: 'app', 3: 'document' }[options.nuxt]}.template.html`),
|
||||
dst: '',
|
||||
compiled: ''
|
||||
}
|
||||
const htmlSrc = resolve(options.buildDir, `views/${{ 2: 'app', 3: 'document' }[options.nuxt]}.template.html`)
|
||||
const htmlTemplate = { src: htmlSrc, contents: '', dst: '', compiled: '' }
|
||||
htmlTemplate.dst = htmlTemplate.src.replace(/.html$/, '.js').replace('app.', 'document.')
|
||||
htmlTemplate.compiled = await compileTemplateToJS(htmlTemplate.src)
|
||||
htmlTemplate.contents = await readFile(htmlTemplate.src, 'utf-8')
|
||||
htmlTemplate.compiled = serializeTemplate(htmlTemplate.src)
|
||||
await hooks.callHook('template:document', htmlTemplate)
|
||||
await writeFileP(htmlTemplate.dst, htmlTemplate.compiled)
|
||||
consola.info('Generated', prettyPath(htmlTemplate.dst))
|
||||
@ -42,15 +40,5 @@ export async function build (options: SLSOptions) {
|
||||
chalk.gray(`(Size: ${size} Gzip: ${zSize})`)
|
||||
)
|
||||
|
||||
for (const tmpl of options.templates) {
|
||||
let dst = tmpl.dst
|
||||
if (typeof dst === 'function') {
|
||||
dst = dst(options)
|
||||
}
|
||||
const dstPath = resolve(options.targetDir, dst)
|
||||
await renderTemplate(tmpl.src, dstPath, { options })
|
||||
consola.info('Compiled', prettyPath(dstPath))
|
||||
}
|
||||
|
||||
await hooks.callHook('done', options)
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
import { resolve } from 'path'
|
||||
import defu from 'defu'
|
||||
import { NuxtOptions } from '@nuxt/types'
|
||||
import { tryImport, LIB_DIR, resolvePath, detectTarget } from './utils'
|
||||
import { tryImport, resolvePath, detectTarget } from './utils'
|
||||
import * as TARGETS from './targets'
|
||||
|
||||
export type UnresolvedPath = string | ((SLSOptions) => string)
|
||||
|
||||
export interface SLSOptions {
|
||||
node: false
|
||||
target: string
|
||||
entry: string
|
||||
entry: UnresolvedPath
|
||||
slsDir: string
|
||||
outName: string
|
||||
logStartup: boolean
|
||||
@ -18,7 +19,7 @@ export interface SLSOptions {
|
||||
staticDir: string
|
||||
targetDir: string
|
||||
rootDir: string
|
||||
templates: { src: string, dst: UnresolvedPath }[]
|
||||
runtimeDir: string
|
||||
static: string[]
|
||||
renderer: string
|
||||
nuxt: 2 | 3
|
||||
@ -33,13 +34,15 @@ export interface SLSOptions {
|
||||
version: string
|
||||
}
|
||||
hooks: { [key: string]: any } // TODO: export from hookable
|
||||
nuxtHooks: NuxtOptions['hooks']
|
||||
nuxtHooks: { [key: string]: Function } // NuxtOptions['hooks']
|
||||
}
|
||||
|
||||
export interface SLSConfig extends Omit<Partial<SLSOptions>, 'targetDir'> {
|
||||
targetDir: UnresolvedPath
|
||||
}
|
||||
|
||||
export type SLSTarget = Partial<SLSConfig>
|
||||
|
||||
export function getoptions (nuxtOptions: NuxtOptions): SLSOptions {
|
||||
const defaults: SLSConfig = {
|
||||
rootDir: nuxtOptions.rootDir,
|
||||
@ -49,7 +52,7 @@ export function getoptions (nuxtOptions: NuxtOptions): SLSOptions {
|
||||
// @ts-ignore
|
||||
staticAssets: nuxtOptions.generate.staticAssets,
|
||||
outName: 'server.js',
|
||||
templates: [],
|
||||
runtimeDir: resolve(__dirname, '../runtime'),
|
||||
static: [],
|
||||
nuxt: 2,
|
||||
logStartup: true,
|
||||
@ -61,7 +64,7 @@ export function getoptions (nuxtOptions: NuxtOptions): SLSOptions {
|
||||
if (typeof target === 'function') {
|
||||
target = target(nuxtOptions)
|
||||
}
|
||||
let targetDefaults = tryImport(LIB_DIR, `./targets/${target}`) || tryImport(nuxtOptions.rootDir, target)
|
||||
let targetDefaults = TARGETS[target] || tryImport(nuxtOptions.rootDir, target)
|
||||
if (!targetDefaults) {
|
||||
throw new Error('Cannot resolve target: ' + target)
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import replace from '@rollup/plugin-replace'
|
||||
import analyze from 'rollup-plugin-analyzer'
|
||||
|
||||
import { SLSOptions } from '../config'
|
||||
import { RUNTIME_DIR } from '../utils'
|
||||
import { resolvePath } from '../utils'
|
||||
import dynamicRequire from './dynamic-require'
|
||||
|
||||
export type RollupConfig = InputOptions & { output: OutputOptions }
|
||||
@ -50,7 +50,7 @@ export const getRollupConfig = (config: SLSOptions) => {
|
||||
}
|
||||
|
||||
const options: RollupConfig = {
|
||||
input: config.entry,
|
||||
input: resolvePath(config, config.entry),
|
||||
output: {
|
||||
file: resolve(config.targetDir, config.outName),
|
||||
format: 'cjs',
|
||||
@ -96,10 +96,10 @@ export const getRollupConfig = (config: SLSOptions) => {
|
||||
const renderer = config.renderer || (config.nuxt === 2 ? 'vue2' : 'vue3')
|
||||
options.plugins.push(alias({
|
||||
entries: {
|
||||
'~runtime': RUNTIME_DIR,
|
||||
'~renderer': require.resolve(resolve(RUNTIME_DIR, renderer)),
|
||||
'~runtime': config.runtimeDir,
|
||||
'~renderer': require.resolve(resolve(config.runtimeDir, renderer)),
|
||||
'~build': config.buildDir,
|
||||
'~mock': require.resolve(resolve(RUNTIME_DIR, 'mock')),
|
||||
'~mock': require.resolve(resolve(config.runtimeDir, 'mock')),
|
||||
...mocks.reduce((p, c) => ({ ...p, [c]: '~mock' }), {}),
|
||||
...providedDeps.reduce((p, c) => ({ ...p, [c]: require.resolve(c) }), {})
|
||||
}
|
||||
|
34
packages/nitro/src/targets/browser.ts
Normal file
34
packages/nitro/src/targets/browser.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { resolve, relative } from 'path'
|
||||
import { existsSync, copy } from 'fs-extra'
|
||||
import consola from 'consola'
|
||||
import { extendTarget } from '../utils'
|
||||
import { SLSTarget } from '../config'
|
||||
import { worker } from './worker'
|
||||
|
||||
const getScriptTag = () => '<script async defer src="/sw-register.js"></script>'
|
||||
|
||||
export const browser: SLSTarget = extendTarget(worker, {
|
||||
targetDir: ({ publicDir }) => publicDir,
|
||||
nuxtHooks: {
|
||||
'vue-renderer:ssr:templateParams' (params) {
|
||||
params.APP += getScriptTag()
|
||||
},
|
||||
'vue-renderer:spa:templateParams' (params) {
|
||||
params.APP += getScriptTag()
|
||||
}
|
||||
},
|
||||
hooks: {
|
||||
'template:document' (tmpl) {
|
||||
tmpl.compiled = tmpl.compiled.replace('</body>', getScriptTag() + '</body>')
|
||||
},
|
||||
async done ({ targetDir, publicDir }) {
|
||||
const rootIndex = resolve(publicDir, 'index.html')
|
||||
const rootFallback = resolve(publicDir, '200.html')
|
||||
if (!existsSync(rootIndex) && existsSync(rootFallback)) {
|
||||
await copy(rootFallback, rootIndex)
|
||||
}
|
||||
|
||||
consola.info(`Try with \`npx serve ${relative(process.cwd(), targetDir)}\``)
|
||||
}
|
||||
}
|
||||
})
|
7
packages/nitro/src/targets/cloudflare.ts
Normal file
7
packages/nitro/src/targets/cloudflare.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { extendTarget } from '../utils'
|
||||
import { SLSTarget } from '../config'
|
||||
import { worker } from './worker'
|
||||
|
||||
export const cloudflare: SLSTarget = extendTarget(worker, {
|
||||
|
||||
})
|
7
packages/nitro/src/targets/index.ts
Normal file
7
packages/nitro/src/targets/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export * from './browser'
|
||||
export * from './cloudflare'
|
||||
export * from './lambda'
|
||||
export * from './netlify'
|
||||
export * from './node'
|
||||
export * from './vercel'
|
||||
export * from './worker'
|
14
packages/nitro/src/targets/lambda.ts
Normal file
14
packages/nitro/src/targets/lambda.ts
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
import { relative } from 'path'
|
||||
import consola from 'consola'
|
||||
import { SLSTarget } from '../config'
|
||||
|
||||
export const lambda: SLSTarget = {
|
||||
entry: '{{ runtimeDir }}/lambda',
|
||||
hooks: {
|
||||
'done' ({ rollupConfig }) {
|
||||
const entry = relative(process.cwd(), rollupConfig.output.file).replace(/\.js$/, '')
|
||||
consola.info(`Ready to deploy lambda: \`${entry}\``)
|
||||
}
|
||||
}
|
||||
}
|
7
packages/nitro/src/targets/netlify.ts
Normal file
7
packages/nitro/src/targets/netlify.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { extendTarget } from '../utils'
|
||||
import { SLSTarget } from '../config'
|
||||
import { lambda } from './lambda'
|
||||
|
||||
export const netlify: SLSTarget = extendTarget(lambda, {
|
||||
|
||||
})
|
14
packages/nitro/src/targets/node.ts
Normal file
14
packages/nitro/src/targets/node.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { relative } from 'path'
|
||||
import consola from 'consola'
|
||||
import { SLSTarget } from '../config'
|
||||
|
||||
export const node: SLSTarget = {
|
||||
entry: '{{ runtimeDir }}/node',
|
||||
hooks: {
|
||||
'done' ({ rollupConfig }) {
|
||||
const entry = relative(process.cwd(), rollupConfig.output.file).replace(/\.js$/, '')
|
||||
consola.info(`Ready to deploy lambda: \`${entry}\``)
|
||||
consola.info(`You can try using \`node ${entry} [path]\``)
|
||||
}
|
||||
}
|
||||
}
|
7
packages/nitro/src/targets/vercel.ts
Normal file
7
packages/nitro/src/targets/vercel.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { extendTarget } from '../utils'
|
||||
import { SLSTarget } from '../config'
|
||||
import { node } from './node'
|
||||
|
||||
export const vercel: SLSTarget = extendTarget(node, {
|
||||
|
||||
})
|
14
packages/nitro/src/targets/worker.ts
Normal file
14
packages/nitro/src/targets/worker.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { SLSTarget } from '../config'
|
||||
|
||||
export const worker: SLSTarget = {
|
||||
entry: '{{ runtimeDir }}/worker',
|
||||
node: false,
|
||||
hooks: {
|
||||
'rollup:before' ({ rollupConfig }) {
|
||||
rollupConfig.output.intro =
|
||||
'const global = {}; const exports = {}; const module = { exports }; const process = { env: {}, hrtime: () => [0,0]};' +
|
||||
rollupConfig.output.intro
|
||||
rollupConfig.output.format = 'iife'
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +1,23 @@
|
||||
import { relative, dirname, resolve } from 'path'
|
||||
import { readFile, writeFile, mkdirp } from 'fs-extra'
|
||||
import { writeFile, mkdirp } from 'fs-extra'
|
||||
import jiti from 'jiti'
|
||||
import { SLSOptions, UnresolvedPath } from './config'
|
||||
import defu from 'defu'
|
||||
import { SLSOptions, UnresolvedPath, SLSTarget } from './config'
|
||||
|
||||
const pwd = process.cwd()
|
||||
|
||||
export const hl = (str: string) => '`' + str + '`'
|
||||
export function hl (str: string) {
|
||||
return '`' + str + '`'
|
||||
}
|
||||
|
||||
export function prettyPath (p: string, highlight = true) {
|
||||
p = relative(pwd, p)
|
||||
p = relative(process.cwd(), p)
|
||||
return highlight ? hl(p) : p
|
||||
}
|
||||
|
||||
export async function loadTemplate (src: string) {
|
||||
const contents = await readFile(src, 'utf-8')
|
||||
return (params: Record<string, string>) => contents.replace(/{{ (\w+) }}/g, `${params.$1}`)
|
||||
export function compileTemplate (contents: string) {
|
||||
return (params: Record<string, any>) => contents.replace(/{{ ?(\w+) ?}}/g, (_, match) => params[match] || '')
|
||||
}
|
||||
|
||||
export async function renderTemplate (src: string, dst: string, params: any) {
|
||||
const tmpl = await loadTemplate(src)
|
||||
const rendered = tmpl(params)
|
||||
await mkdirp(dirname(dst))
|
||||
await writeFile(dst, rendered)
|
||||
}
|
||||
|
||||
export async function compileTemplateToJS (src: string) {
|
||||
const contents = await readFile(src, 'utf-8')
|
||||
export function serializeTemplate (contents: string) {
|
||||
// eslint-disable-next-line no-template-curly-in-string
|
||||
return `export default (params) => \`${contents.replace(/{{ (\w+) }}/g, '${params.$1}')}\``
|
||||
}
|
||||
@ -35,11 +27,24 @@ export async function writeFileP (path, contents) {
|
||||
await writeFile(path, contents)
|
||||
}
|
||||
|
||||
export const jitiImport = (dir: string, path: string) => jiti(dir)(path)
|
||||
export const tryImport = (dir: string, path: string) => { try { return jitiImport(dir, path) } catch (_err) { } }
|
||||
export function jitiImport (dir: string, path: string) {
|
||||
return jiti(dir)(path)
|
||||
}
|
||||
|
||||
export function tryImport (dir: string, path: string) {
|
||||
try {
|
||||
return jitiImport(dir, path)
|
||||
} catch (_err) { }
|
||||
}
|
||||
|
||||
export function resolvePath (options: SLSOptions, path: UnresolvedPath, resolveBase: string = '') {
|
||||
return resolve(resolveBase, typeof path === 'string' ? path : path(options))
|
||||
if (typeof path === 'function') {
|
||||
path = path(options)
|
||||
}
|
||||
|
||||
path = compileTemplate(path)(options)
|
||||
|
||||
return resolve(resolveBase, path)
|
||||
}
|
||||
|
||||
export function detectTarget () {
|
||||
@ -54,5 +59,7 @@ export function detectTarget () {
|
||||
return 'node'
|
||||
}
|
||||
|
||||
export const LIB_DIR = resolve(__dirname, '../lib')
|
||||
export const RUNTIME_DIR = resolve(LIB_DIR, 'runtime')
|
||||
export function extendTarget (base: SLSTarget, target: SLSTarget): SLSTarget {
|
||||
// TODO: merge hooks
|
||||
return defu(target, base)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user