mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
refactror: separate lib
This commit is contained in:
parent
05e8d538db
commit
5538f342f7
@ -2,33 +2,18 @@ import { resolve } from 'path'
|
|||||||
import consola from 'consola'
|
import consola from 'consola'
|
||||||
import { rollup, OutputOptions } from 'rollup'
|
import { rollup, OutputOptions } from 'rollup'
|
||||||
import Hookable from 'hookable'
|
import Hookable from 'hookable'
|
||||||
import defu from 'defu'
|
|
||||||
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 { copy, emptyDir, existsSync } from 'fs-extra'
|
import { copy, emptyDir, existsSync } from 'fs-extra'
|
||||||
import { getRollupConfig } from './rollup/config'
|
import { getRollupConfig } from './rollup/config'
|
||||||
import { tryImport, hl, prettyPath, renderTemplate, compileTemplateToJS } from './utils'
|
import { getTargetConfig } from './config'
|
||||||
|
import { hl, prettyPath, renderTemplate, compileTemplateToJS } from './utils'
|
||||||
|
|
||||||
export async function build (baseConfig, target) {
|
export async function build (baseConfig, target) {
|
||||||
consola.info(`Generating bundle for ${hl(target.target)}`)
|
consola.info(`Generating bundle for ${hl(target.target)}`)
|
||||||
|
|
||||||
const _targetDefaults = tryImport(__dirname, `./targets/${target.target}`) ||
|
const config: any = getTargetConfig(baseConfig, target)
|
||||||
tryImport(baseConfig.rootDir, target.target)
|
|
||||||
if (!_targetDefaults) {
|
|
||||||
throw new Error('Cannot resolve target: ' + target.target)
|
|
||||||
}
|
|
||||||
|
|
||||||
const config: any = defu(
|
|
||||||
// Target specific config by user
|
|
||||||
target,
|
|
||||||
// Global user config
|
|
||||||
baseConfig,
|
|
||||||
// Target defaults
|
|
||||||
_targetDefaults,
|
|
||||||
// Generic defaults
|
|
||||||
{ outDir: resolve(baseConfig.buildDir, `dist/${target.target}`), outName: 'index.js' }
|
|
||||||
)
|
|
||||||
|
|
||||||
const hooks = new Hookable()
|
const hooks = new Hookable()
|
||||||
hooks.addHooks(config.hooks)
|
hooks.addHooks(config.hooks)
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import consola from 'consola'
|
|
||||||
import { build, compileHTMLTemplate, ensureDist } from './build'
|
import { build, compileHTMLTemplate, ensureDist } from './build'
|
||||||
import { getBaseConfig } from './config'
|
import { getBaseConfig } from './config'
|
||||||
|
|
||||||
async function _runCLI () {
|
export async function runCLI () {
|
||||||
const rootDir = resolve(process.cwd(), process.argv[2] || '.')
|
const rootDir = resolve(process.cwd(), process.argv[2] || '.')
|
||||||
|
|
||||||
// Config
|
// Config
|
||||||
@ -23,10 +22,3 @@ async function _runCLI () {
|
|||||||
await build(baseConfig, target)
|
await build(baseConfig, target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function runCLI () {
|
|
||||||
_runCLI().catch((err) => {
|
|
||||||
consola.error(err)
|
|
||||||
process.exit(1)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { resolve } from 'path'
|
import { resolve } from 'path'
|
||||||
import { tryImport } from './utils'
|
import defu from 'defu'
|
||||||
|
import { tryImport, LIB_DIR } from './utils'
|
||||||
|
|
||||||
export function getBaseConfig (rootDir) {
|
export function getBaseConfig (rootDir) {
|
||||||
const baseConfig = {
|
let baseConfig = {
|
||||||
rootDir,
|
rootDir,
|
||||||
buildDir: '',
|
buildDir: '',
|
||||||
targets: [],
|
targets: [],
|
||||||
@ -14,7 +15,13 @@ export function getBaseConfig (rootDir) {
|
|||||||
logStartup: true
|
logStartup: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.assign(baseConfig, tryImport(rootDir, './nuxt.config')!.serverless)
|
const nuxtConfig = tryImport(rootDir, './nuxt.config')
|
||||||
|
if (!nuxtConfig) {
|
||||||
|
throw new Error('`nuxt.config` file not found in: ' + rootDir)
|
||||||
|
}
|
||||||
|
if (nuxtConfig.serverless) {
|
||||||
|
baseConfig = defu(nuxtConfig.serverless, baseConfig)
|
||||||
|
}
|
||||||
|
|
||||||
baseConfig.buildDir = resolve(baseConfig.rootDir, baseConfig.buildDir || '.nuxt')
|
baseConfig.buildDir = resolve(baseConfig.rootDir, baseConfig.buildDir || '.nuxt')
|
||||||
|
|
||||||
@ -25,3 +32,24 @@ export function getBaseConfig (rootDir) {
|
|||||||
|
|
||||||
return baseConfig
|
return baseConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getTargetConfig (baseConfig, target) {
|
||||||
|
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
|
||||||
|
{ outDir: resolve(baseConfig.buildDir, `dist/${target.target}`), outName: 'index.js' }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
6
packages/nitro/src/nuxt-serverless.ts
Normal file
6
packages/nitro/src/nuxt-serverless.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
require('../dist').runCLI().catch((error) => {
|
||||||
|
const consola = require('consola')
|
||||||
|
consola.error(error)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
@ -8,7 +8,7 @@ import alias from '@rollup/plugin-alias'
|
|||||||
import json from '@rollup/plugin-json'
|
import json from '@rollup/plugin-json'
|
||||||
import replace from '@rollup/plugin-replace'
|
import replace from '@rollup/plugin-replace'
|
||||||
import analyze from 'rollup-plugin-analyzer'
|
import analyze from 'rollup-plugin-analyzer'
|
||||||
import ts from 'rollup-plugin-ts'
|
import { RUNTIME_DIR } from '../utils'
|
||||||
import dynamicRequire from './dynamic-require'
|
import dynamicRequire from './dynamic-require'
|
||||||
|
|
||||||
export type RollupConfig = InputOptions & { output: OutputOptions }
|
export type RollupConfig = InputOptions & { output: OutputOptions }
|
||||||
@ -83,22 +83,14 @@ export const getRollupConfig = (config) => {
|
|||||||
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': path.resolve(__dirname, '../runtime'),
|
'~runtime': RUNTIME_DIR,
|
||||||
'~renderer': require.resolve('../runtime/' + renderer),
|
'~renderer': require.resolve(path.resolve(RUNTIME_DIR, renderer)),
|
||||||
'~build': config.buildDir,
|
'~build': config.buildDir,
|
||||||
'~mock': require.resolve('../runtime/mock'),
|
'~mock': require.resolve(path.resolve(RUNTIME_DIR, 'mock')),
|
||||||
...mocks.reduce((p, c) => ({ ...p, [c]: '~mock' }), {})
|
...mocks.reduce((p, c) => ({ ...p, [c]: '~mock' }), {})
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// https://github.com/wessberg/rollup-plugin-ts
|
|
||||||
options.plugins.push(ts({
|
|
||||||
transpileOnly: true,
|
|
||||||
transpiler: 'babel',
|
|
||||||
include: ['**/*.ts'],
|
|
||||||
exclude: ['*.json', 'node_modules']
|
|
||||||
}))
|
|
||||||
|
|
||||||
// https://github.com/rollup/plugins/tree/master/packages/node-resolve
|
// https://github.com/rollup/plugins/tree/master/packages/node-resolve
|
||||||
options.plugins.push(resolve({
|
options.plugins.push(resolve({
|
||||||
extensions,
|
extensions,
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
function getProxy (name) {
|
|
||||||
const fn = function () { }
|
|
||||||
fn.prototype.name = name
|
|
||||||
|
|
||||||
const props = {}
|
|
||||||
|
|
||||||
return new Proxy(fn, {
|
|
||||||
get (_target, prop) {
|
|
||||||
if (prop === 'caller') { return null }
|
|
||||||
return (props[prop] = props[prop] || getProxy(`${name}.${prop.toString()}`))
|
|
||||||
},
|
|
||||||
apply (_target, _this, _args) {
|
|
||||||
console.debug(`${name}(...)`)
|
|
||||||
return getProxy(`${name}()`)
|
|
||||||
},
|
|
||||||
construct (_target, _args, _newT) {
|
|
||||||
return getProxy(`[${name}]`)
|
|
||||||
},
|
|
||||||
enumerate (_target) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = getProxy('mock')
|
|
@ -1,55 +0,0 @@
|
|||||||
import { createRenderer } from 'vue-bundle-renderer'
|
|
||||||
import devalue from '@nuxt/devalue'
|
|
||||||
|
|
||||||
// @ts-ignore
|
|
||||||
import { renderToString } from '~renderer'
|
|
||||||
// @ts-ignore
|
|
||||||
import server from '~build/dist/server/server'
|
|
||||||
// @ts-ignore
|
|
||||||
import clientManifest from '~build/dist/server/client.manifest.json'
|
|
||||||
// @ts-ignore
|
|
||||||
import htmlTemplate from '~build/views/document.template.js'
|
|
||||||
|
|
||||||
const renderer = createRenderer(server, {
|
|
||||||
clientManifest,
|
|
||||||
renderToString
|
|
||||||
})
|
|
||||||
|
|
||||||
export async function render (url, ctx: any) {
|
|
||||||
const start = process.hrtime()
|
|
||||||
|
|
||||||
const ssrContext: any = {
|
|
||||||
url,
|
|
||||||
runtimeConfig: {
|
|
||||||
public: {},
|
|
||||||
private: {}
|
|
||||||
},
|
|
||||||
...ctx
|
|
||||||
}
|
|
||||||
const rendered = await renderer.renderToString(ssrContext)
|
|
||||||
|
|
||||||
const state = `<script>window.__NUXT__=${devalue(ssrContext.nuxt /* nuxt 2 */ || ssrContext.payload /* nuxt 3 */)}</script>`
|
|
||||||
const _html = `<div id="__nuxt">${rendered.html}</div>`
|
|
||||||
|
|
||||||
const html = htmlTemplate({
|
|
||||||
HTML_ATTRS: '',
|
|
||||||
HEAD_ATTRS: '',
|
|
||||||
BODY_ATTRS: '',
|
|
||||||
HEAD: rendered.renderResourceHints() + rendered.renderStyles() + (ssrContext.styles || ''),
|
|
||||||
APP: _html + state + rendered.renderScripts()
|
|
||||||
})
|
|
||||||
|
|
||||||
const end = process.hrtime(start)
|
|
||||||
const time = ((end[0] * 1e9) + end[1]) / 1e6
|
|
||||||
|
|
||||||
return {
|
|
||||||
html,
|
|
||||||
status: 200,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'text/html;charset=UTF-8',
|
|
||||||
// @ts-ignore
|
|
||||||
'X-Nuxt-Coldstart': global._coldstart + 'ms',
|
|
||||||
'X-Nuxt-ResponseTime': time + 'ms'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
import { createRenderer } from 'vue-server-renderer/build.prod.js'
|
|
||||||
|
|
||||||
const _renderer = createRenderer({})
|
|
||||||
|
|
||||||
export function renderToString (component, context) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
_renderer.renderToString(component, context, (err, result) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err)
|
|
||||||
}
|
|
||||||
return resolve(result)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
// @ts-ignore
|
|
||||||
export { renderToString } from '@vue/server-renderer'
|
|
@ -1,16 +0,0 @@
|
|||||||
// @ts-ignore
|
|
||||||
import { render } from '~runtime/server'
|
|
||||||
|
|
||||||
addEventListener('fetch', (event: any) => {
|
|
||||||
event.respondWith(handleEvent(event.request))
|
|
||||||
})
|
|
||||||
|
|
||||||
async function handleEvent (request) {
|
|
||||||
try {
|
|
||||||
const url = new URL(request.url)
|
|
||||||
const { html, status, headers } = await render(url.pathname, { req: request })
|
|
||||||
return new Response(html, { status, headers })
|
|
||||||
} catch (error) {
|
|
||||||
return new Response('Internal Error: ' + error, { status: 500 })
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
export default {
|
|
||||||
entry: require.resolve('./entry'),
|
|
||||||
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,27 +0,0 @@
|
|||||||
// @ts-ignore
|
|
||||||
import { render } from '~runtime/server'
|
|
||||||
// @ts-ignore
|
|
||||||
export { render } from '~runtime/server'
|
|
||||||
|
|
||||||
async function cli () {
|
|
||||||
const url = process.argv[2] || '/'
|
|
||||||
|
|
||||||
const debug = (label, ...args) => console.debug(`> ${label}:`, ...args)
|
|
||||||
|
|
||||||
const { html, status, headers } = await render(url)
|
|
||||||
|
|
||||||
debug('URL', url)
|
|
||||||
debug('Status', status)
|
|
||||||
for (const header in headers) {
|
|
||||||
debug(header, headers[header])
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('\n', html)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (require.main === module) {
|
|
||||||
cli().catch((err) => {
|
|
||||||
console.error(err)
|
|
||||||
process.exit(1)
|
|
||||||
})
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
|
|
||||||
import consola from 'consola'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
entry: require.resolve('./entry'),
|
|
||||||
hooks: {
|
|
||||||
'done' ({ rollupConfig }) {
|
|
||||||
consola.info(`Usage: \`node ${rollupConfig.output.file} [route]\``)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
// @ts-ignore
|
|
||||||
import { render } from '~runtime/server'
|
|
||||||
|
|
||||||
addEventListener('fetch', (event: any) => {
|
|
||||||
const url = new URL(event.request.url)
|
|
||||||
|
|
||||||
if (url.pathname.startsWith('/_nuxt') || url.pathname.includes('.') /* is file :} */) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
event.respondWith(handleEvent(url, event.request))
|
|
||||||
})
|
|
||||||
|
|
||||||
self.addEventListener('install', () => {
|
|
||||||
// @ts-ignore
|
|
||||||
self.skipWaiting()
|
|
||||||
})
|
|
||||||
|
|
||||||
self.addEventListener('activate', (event) => {
|
|
||||||
// @ts-ignore
|
|
||||||
event.waitUntil(self.clients.claim())
|
|
||||||
})
|
|
||||||
|
|
||||||
async function handleEvent (url, request) {
|
|
||||||
try {
|
|
||||||
const { html, status, headers } = await render(url.pathname, { req: request })
|
|
||||||
return new Response(html, { status, headers })
|
|
||||||
} catch (error) {
|
|
||||||
return new Response('Internal Error: ' + error, { status: 500 })
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<!-- SW_INIT-->
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<link rel="prefetch" href="/nuxt.sw.js">
|
|
||||||
<script>
|
|
||||||
async function reload() {
|
|
||||||
const html = await fetch(window.location.href).then(r => r.text())
|
|
||||||
if (html.includes('<!-- SW_INIT-->')) {
|
|
||||||
window.location.reload(false)
|
|
||||||
} else {
|
|
||||||
document.open()
|
|
||||||
document.write(html)
|
|
||||||
document.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function register() {
|
|
||||||
const registration = await navigator.serviceWorker.register('/nuxt.sw.js')
|
|
||||||
await navigator.serviceWorker.ready
|
|
||||||
registration.active.addEventListener('statechange', (event) => {
|
|
||||||
if (event.target.state === 'activated') {
|
|
||||||
reload()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (location.hostname !== 'localhost' && location.protocol === 'http:') {
|
|
||||||
location.replace(location.href.replace('http://', 'https://'))
|
|
||||||
} else {
|
|
||||||
register()
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
Loading...
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,24 +0,0 @@
|
|||||||
import { resolve } from 'path'
|
|
||||||
import consola from 'consola'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
entry: require.resolve('./entry'),
|
|
||||||
node: false,
|
|
||||||
copyAssets: '.',
|
|
||||||
outName: 'nuxt.sw.js',
|
|
||||||
templates: [
|
|
||||||
{ src: resolve(__dirname, 'index.html'), dst: 'index.html' },
|
|
||||||
{ src: resolve(__dirname, 'index.html'), dst: '200.html' }
|
|
||||||
],
|
|
||||||
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'
|
|
||||||
},
|
|
||||||
done ({ outDir }) {
|
|
||||||
consola.info(`Try with \`npx serve ${outDir}\``)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
// @ts-ignore
|
|
||||||
import { render } from '~runtime/server'
|
|
||||||
|
|
||||||
module.exports = async (req, res) => {
|
|
||||||
try {
|
|
||||||
const { html, status, headers } = await render(req.url, { req, res })
|
|
||||||
for (const header in headers) {
|
|
||||||
res.setHeader(header, headers[header])
|
|
||||||
}
|
|
||||||
res.status(status)
|
|
||||||
res.end(html)
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
res.status(500)
|
|
||||||
res.end('Internal Error: ' + error)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
import consola from 'consola'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
entry: require.resolve('./entry'),
|
|
||||||
dynamicImporter: false,
|
|
||||||
hooks: {
|
|
||||||
'done' () {
|
|
||||||
consola.info('Run `vercel serverless` to serverless!')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
import { relative, dirname } from 'path'
|
import { relative, dirname, resolve } from 'path'
|
||||||
import { readFile, writeFile, mkdirp } from 'fs-extra'
|
import { readFile, writeFile, mkdirp } from 'fs-extra'
|
||||||
import jiti from 'jiti'
|
import jiti from 'jiti'
|
||||||
|
|
||||||
@ -31,4 +31,8 @@ export async function compileTemplateToJS (src: string, dst: string) {
|
|||||||
await writeFile(dst, compiled)
|
await writeFile(dst, compiled)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const tryImport = (dir, path) => { try { return jiti(dir)(path) } catch (_err) { } }
|
export const jitiImport = (dir, path) => jiti(dir)(path)
|
||||||
|
export const tryImport = (dir, path) => { try { return jitiImport(dir, path) } catch (_err) { } }
|
||||||
|
|
||||||
|
export const LIB_DIR = resolve(__dirname, '../lib')
|
||||||
|
export const RUNTIME_DIR = resolve(LIB_DIR, 'runtime')
|
||||||
|
Loading…
Reference in New Issue
Block a user