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 { rollup, OutputOptions } from 'rollup'
|
||||
import Hookable from 'hookable'
|
||||
import defu from 'defu'
|
||||
import prettyBytes from 'pretty-bytes'
|
||||
import gzipSize from 'gzip-size'
|
||||
import chalk from 'chalk'
|
||||
import { copy, emptyDir, existsSync } from 'fs-extra'
|
||||
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) {
|
||||
consola.info(`Generating bundle for ${hl(target.target)}`)
|
||||
|
||||
const _targetDefaults = tryImport(__dirname, `./targets/${target.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 config: any = getTargetConfig(baseConfig, target)
|
||||
|
||||
const hooks = new Hookable()
|
||||
hooks.addHooks(config.hooks)
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { resolve } from 'path'
|
||||
import consola from 'consola'
|
||||
import { build, compileHTMLTemplate, ensureDist } from './build'
|
||||
import { getBaseConfig } from './config'
|
||||
|
||||
async function _runCLI () {
|
||||
export async function runCLI () {
|
||||
const rootDir = resolve(process.cwd(), process.argv[2] || '.')
|
||||
|
||||
// Config
|
||||
@ -23,10 +22,3 @@ async function _runCLI () {
|
||||
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 { tryImport } from './utils'
|
||||
import defu from 'defu'
|
||||
import { tryImport, LIB_DIR } from './utils'
|
||||
|
||||
export function getBaseConfig (rootDir) {
|
||||
const baseConfig = {
|
||||
let baseConfig = {
|
||||
rootDir,
|
||||
buildDir: '',
|
||||
targets: [],
|
||||
@ -14,7 +15,13 @@ export function getBaseConfig (rootDir) {
|
||||
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')
|
||||
|
||||
@ -25,3 +32,24 @@ export function getBaseConfig (rootDir) {
|
||||
|
||||
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 replace from '@rollup/plugin-replace'
|
||||
import analyze from 'rollup-plugin-analyzer'
|
||||
import ts from 'rollup-plugin-ts'
|
||||
import { RUNTIME_DIR } from '../utils'
|
||||
import dynamicRequire from './dynamic-require'
|
||||
|
||||
export type RollupConfig = InputOptions & { output: OutputOptions }
|
||||
@ -83,22 +83,14 @@ export const getRollupConfig = (config) => {
|
||||
const renderer = config.renderer || (config.nuxt === 2 ? 'vue2' : 'vue3')
|
||||
options.plugins.push(alias({
|
||||
entries: {
|
||||
'~runtime': path.resolve(__dirname, '../runtime'),
|
||||
'~renderer': require.resolve('../runtime/' + renderer),
|
||||
'~runtime': RUNTIME_DIR,
|
||||
'~renderer': require.resolve(path.resolve(RUNTIME_DIR, renderer)),
|
||||
'~build': config.buildDir,
|
||||
'~mock': require.resolve('../runtime/mock'),
|
||||
'~mock': require.resolve(path.resolve(RUNTIME_DIR, '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
|
||||
options.plugins.push(resolve({
|
||||
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 jiti from 'jiti'
|
||||
|
||||
@ -31,4 +31,8 @@ export async function compileTemplateToJS (src: string, dst: string) {
|
||||
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