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 prettyBytes from 'pretty-bytes'
|
||||||
import gzipSize from 'gzip-size'
|
import gzipSize from 'gzip-size'
|
||||||
import chalk from 'chalk'
|
import chalk from 'chalk'
|
||||||
import { emptyDir } from 'fs-extra'
|
import { emptyDir, readFile } from 'fs-extra'
|
||||||
import { getRollupConfig } from './rollup/config'
|
import { getRollupConfig } from './rollup/config'
|
||||||
import { hl, prettyPath, renderTemplate, compileTemplateToJS, writeFileP } from './utils'
|
import { hl, prettyPath, serializeTemplate, writeFileP } from './utils'
|
||||||
import { SLSOptions } from './config'
|
import { SLSOptions } from './config'
|
||||||
|
|
||||||
export async function build (options: SLSOptions) {
|
export async function build (options: SLSOptions) {
|
||||||
@ -18,13 +18,11 @@ export async function build (options: SLSOptions) {
|
|||||||
hooks.addHooks(options.hooks)
|
hooks.addHooks(options.hooks)
|
||||||
|
|
||||||
// Compile html template
|
// Compile html template
|
||||||
const htmlTemplate = {
|
const htmlSrc = resolve(options.buildDir, `views/${{ 2: 'app', 3: 'document' }[options.nuxt]}.template.html`)
|
||||||
src: resolve(options.buildDir, `views/${{ 2: 'app', 3: 'document' }[options.nuxt]}.template.html`),
|
const htmlTemplate = { src: htmlSrc, contents: '', dst: '', compiled: '' }
|
||||||
dst: '',
|
|
||||||
compiled: ''
|
|
||||||
}
|
|
||||||
htmlTemplate.dst = htmlTemplate.src.replace(/.html$/, '.js').replace('app.', 'document.')
|
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 hooks.callHook('template:document', htmlTemplate)
|
||||||
await writeFileP(htmlTemplate.dst, htmlTemplate.compiled)
|
await writeFileP(htmlTemplate.dst, htmlTemplate.compiled)
|
||||||
consola.info('Generated', prettyPath(htmlTemplate.dst))
|
consola.info('Generated', prettyPath(htmlTemplate.dst))
|
||||||
@ -42,15 +40,5 @@ export async function build (options: SLSOptions) {
|
|||||||
chalk.gray(`(Size: ${size} Gzip: ${zSize})`)
|
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)
|
await hooks.callHook('done', options)
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import defu from 'defu'
|
import defu from 'defu'
|
||||||
import { NuxtOptions } from '@nuxt/types'
|
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 type UnresolvedPath = string | ((SLSOptions) => string)
|
||||||
|
|
||||||
export interface SLSOptions {
|
export interface SLSOptions {
|
||||||
node: false
|
node: false
|
||||||
target: string
|
target: string
|
||||||
entry: string
|
entry: UnresolvedPath
|
||||||
slsDir: string
|
slsDir: string
|
||||||
outName: string
|
outName: string
|
||||||
logStartup: boolean
|
logStartup: boolean
|
||||||
@ -18,7 +19,7 @@ export interface SLSOptions {
|
|||||||
staticDir: string
|
staticDir: string
|
||||||
targetDir: string
|
targetDir: string
|
||||||
rootDir: string
|
rootDir: string
|
||||||
templates: { src: string, dst: UnresolvedPath }[]
|
runtimeDir: string
|
||||||
static: string[]
|
static: string[]
|
||||||
renderer: string
|
renderer: string
|
||||||
nuxt: 2 | 3
|
nuxt: 2 | 3
|
||||||
@ -33,13 +34,15 @@ export interface SLSOptions {
|
|||||||
version: string
|
version: string
|
||||||
}
|
}
|
||||||
hooks: { [key: string]: any } // TODO: export from hookable
|
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'> {
|
export interface SLSConfig extends Omit<Partial<SLSOptions>, 'targetDir'> {
|
||||||
targetDir: UnresolvedPath
|
targetDir: UnresolvedPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type SLSTarget = Partial<SLSConfig>
|
||||||
|
|
||||||
export function getoptions (nuxtOptions: NuxtOptions): SLSOptions {
|
export function getoptions (nuxtOptions: NuxtOptions): SLSOptions {
|
||||||
const defaults: SLSConfig = {
|
const defaults: SLSConfig = {
|
||||||
rootDir: nuxtOptions.rootDir,
|
rootDir: nuxtOptions.rootDir,
|
||||||
@ -49,7 +52,7 @@ export function getoptions (nuxtOptions: NuxtOptions): SLSOptions {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
staticAssets: nuxtOptions.generate.staticAssets,
|
staticAssets: nuxtOptions.generate.staticAssets,
|
||||||
outName: 'server.js',
|
outName: 'server.js',
|
||||||
templates: [],
|
runtimeDir: resolve(__dirname, '../runtime'),
|
||||||
static: [],
|
static: [],
|
||||||
nuxt: 2,
|
nuxt: 2,
|
||||||
logStartup: true,
|
logStartup: true,
|
||||||
@ -61,7 +64,7 @@ export function getoptions (nuxtOptions: NuxtOptions): SLSOptions {
|
|||||||
if (typeof target === 'function') {
|
if (typeof target === 'function') {
|
||||||
target = target(nuxtOptions)
|
target = target(nuxtOptions)
|
||||||
}
|
}
|
||||||
let targetDefaults = tryImport(LIB_DIR, `./targets/${target}`) || tryImport(nuxtOptions.rootDir, target)
|
let targetDefaults = TARGETS[target] || tryImport(nuxtOptions.rootDir, target)
|
||||||
if (!targetDefaults) {
|
if (!targetDefaults) {
|
||||||
throw new Error('Cannot resolve target: ' + target)
|
throw new Error('Cannot resolve target: ' + target)
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import replace from '@rollup/plugin-replace'
|
|||||||
import analyze from 'rollup-plugin-analyzer'
|
import analyze from 'rollup-plugin-analyzer'
|
||||||
|
|
||||||
import { SLSOptions } from '../config'
|
import { SLSOptions } from '../config'
|
||||||
import { RUNTIME_DIR } from '../utils'
|
import { resolvePath } from '../utils'
|
||||||
import dynamicRequire from './dynamic-require'
|
import dynamicRequire from './dynamic-require'
|
||||||
|
|
||||||
export type RollupConfig = InputOptions & { output: OutputOptions }
|
export type RollupConfig = InputOptions & { output: OutputOptions }
|
||||||
@ -50,7 +50,7 @@ export const getRollupConfig = (config: SLSOptions) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const options: RollupConfig = {
|
const options: RollupConfig = {
|
||||||
input: config.entry,
|
input: resolvePath(config, config.entry),
|
||||||
output: {
|
output: {
|
||||||
file: resolve(config.targetDir, config.outName),
|
file: resolve(config.targetDir, config.outName),
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
@ -96,10 +96,10 @@ export const getRollupConfig = (config: SLSOptions) => {
|
|||||||
const renderer = config.renderer || (config.nuxt === 2 ? 'vue2' : 'vue3')
|
const renderer = config.renderer || (config.nuxt === 2 ? 'vue2' : 'vue3')
|
||||||
options.plugins.push(alias({
|
options.plugins.push(alias({
|
||||||
entries: {
|
entries: {
|
||||||
'~runtime': RUNTIME_DIR,
|
'~runtime': config.runtimeDir,
|
||||||
'~renderer': require.resolve(resolve(RUNTIME_DIR, renderer)),
|
'~renderer': require.resolve(resolve(config.runtimeDir, renderer)),
|
||||||
'~build': config.buildDir,
|
'~build': config.buildDir,
|
||||||
'~mock': require.resolve(resolve(RUNTIME_DIR, 'mock')),
|
'~mock': require.resolve(resolve(config.runtimeDir, 'mock')),
|
||||||
...mocks.reduce((p, c) => ({ ...p, [c]: '~mock' }), {}),
|
...mocks.reduce((p, c) => ({ ...p, [c]: '~mock' }), {}),
|
||||||
...providedDeps.reduce((p, c) => ({ ...p, [c]: require.resolve(c) }), {})
|
...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 { relative, dirname, resolve } from 'path'
|
||||||
import { readFile, writeFile, mkdirp } from 'fs-extra'
|
import { writeFile, mkdirp } from 'fs-extra'
|
||||||
import jiti from 'jiti'
|
import jiti from 'jiti'
|
||||||
import { SLSOptions, UnresolvedPath } from './config'
|
import defu from 'defu'
|
||||||
|
import { SLSOptions, UnresolvedPath, SLSTarget } from './config'
|
||||||
|
|
||||||
const pwd = process.cwd()
|
export function hl (str: string) {
|
||||||
|
return '`' + str + '`'
|
||||||
export const hl = (str: string) => '`' + str + '`'
|
}
|
||||||
|
|
||||||
export function prettyPath (p: string, highlight = true) {
|
export function prettyPath (p: string, highlight = true) {
|
||||||
p = relative(pwd, p)
|
p = relative(process.cwd(), p)
|
||||||
return highlight ? hl(p) : p
|
return highlight ? hl(p) : p
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadTemplate (src: string) {
|
export function compileTemplate (contents: string) {
|
||||||
const contents = await readFile(src, 'utf-8')
|
return (params: Record<string, any>) => contents.replace(/{{ ?(\w+) ?}}/g, (_, match) => params[match] || '')
|
||||||
return (params: Record<string, string>) => contents.replace(/{{ (\w+) }}/g, `${params.$1}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function renderTemplate (src: string, dst: string, params: any) {
|
export function serializeTemplate (contents: string) {
|
||||||
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')
|
|
||||||
// eslint-disable-next-line no-template-curly-in-string
|
// eslint-disable-next-line no-template-curly-in-string
|
||||||
return `export default (params) => \`${contents.replace(/{{ (\w+) }}/g, '${params.$1}')}\``
|
return `export default (params) => \`${contents.replace(/{{ (\w+) }}/g, '${params.$1}')}\``
|
||||||
}
|
}
|
||||||
@ -35,11 +27,24 @@ export async function writeFileP (path, contents) {
|
|||||||
await writeFile(path, contents)
|
await writeFile(path, contents)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const jitiImport = (dir: string, path: string) => jiti(dir)(path)
|
export function jitiImport (dir: string, path: string) {
|
||||||
export const tryImport = (dir: string, path: string) => { try { return jitiImport(dir, path) } catch (_err) { } }
|
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 = '') {
|
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 () {
|
export function detectTarget () {
|
||||||
@ -54,5 +59,7 @@ export function detectTarget () {
|
|||||||
return 'node'
|
return 'node'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LIB_DIR = resolve(__dirname, '../lib')
|
export function extendTarget (base: SLSTarget, target: SLSTarget): SLSTarget {
|
||||||
export const RUNTIME_DIR = resolve(LIB_DIR, 'runtime')
|
// TODO: merge hooks
|
||||||
|
return defu(target, base)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user