mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-27 08:02:01 +00:00
refactor server into nuxt
This commit is contained in:
parent
bf379fc0fd
commit
daa50e4efb
110
bin/nuxt-dev
110
bin/nuxt-dev
@ -8,7 +8,7 @@ const debug = require('debug')('nuxt:build')
|
||||
debug.color = 2 // force green color
|
||||
const fs = require('fs')
|
||||
const parseArgs = require('minimist')
|
||||
const { Nuxt, Server, Builder } = require('../')
|
||||
const { Nuxt, Builder } = require('../')
|
||||
const chokidar = require('chokidar')
|
||||
const resolve = require('path').resolve
|
||||
|
||||
@ -50,64 +50,64 @@ if (argv.help) {
|
||||
const rootDir = resolve(argv._[0] || '.')
|
||||
const nuxtConfigFile = resolve(rootDir, argv['config-file'])
|
||||
|
||||
var options = {}
|
||||
if (fs.existsSync(nuxtConfigFile)) {
|
||||
options = require(nuxtConfigFile)
|
||||
} else if (argv['config-file'] !== 'nuxt.config.js') {
|
||||
console.error(`> Could not load config file ${argv['config-file']}`)
|
||||
process.exit(1)
|
||||
}
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
// Force development mode: add hot reloading and watching changes
|
||||
options.dev = true
|
||||
// Load config once for chokidar
|
||||
const nuxtConfig = loadNuxtConfig()
|
||||
_.defaultsDeep(nuxtConfig, { watchers: { chokidar: { ignoreInitial: true } } })
|
||||
|
||||
const nuxt = new Nuxt(options)
|
||||
const builder = new Builder(nuxt)
|
||||
// Start dev
|
||||
let dev = startDev()
|
||||
|
||||
const port = argv.port || process.env.PORT || process.env.npm_package_config_nuxt_port
|
||||
const host = argv.hostname || process.env.HOST || process.env.npm_package_config_nuxt_host
|
||||
const server = new Server(nuxt)
|
||||
server.listen(port, host)
|
||||
|
||||
builder.build().then(() => {
|
||||
listenOnConfigChanges(nuxt, server)
|
||||
})
|
||||
|
||||
function listenOnConfigChanges (nuxt, server) {
|
||||
// Listen on nuxt.config.js changes
|
||||
const build = _.debounce(() => {
|
||||
// Start watching for nuxt.config.js changes
|
||||
chokidar
|
||||
.watch(nuxtConfigFile, nuxtConfig.watchers.chokidar)
|
||||
.on('all', _.debounce(() => {
|
||||
debug('[nuxt.config.js] changed')
|
||||
delete require.cache[nuxtConfigFile]
|
||||
var options = {}
|
||||
if (fs.existsSync(nuxtConfigFile)) {
|
||||
try {
|
||||
options = require(nuxtConfigFile)
|
||||
} catch (e) {
|
||||
return console.error(e) // eslint-disable-line no-console
|
||||
}
|
||||
}
|
||||
debug('Rebuilding the app...')
|
||||
dev = dev.then(startDev)
|
||||
}), 2500)
|
||||
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
function startDev (oldNuxt) {
|
||||
// Get latest environment variables
|
||||
const port = argv.port || process.env.PORT || process.env.npm_package_config_nuxt_port
|
||||
const host = argv.hostname || process.env.HOST || process.env.npm_package_config_nuxt_host
|
||||
|
||||
nuxt.close()
|
||||
.then(() => {
|
||||
debug('Rebuilding the app...')
|
||||
const nuxt = new Nuxt(options)
|
||||
const builder = new Builder(nuxt)
|
||||
server.nuxt = nuxt
|
||||
return builder.build()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error while rebuild the app:', error) // eslint-disable-line no-console
|
||||
process.exit(1)
|
||||
})
|
||||
}, 200)
|
||||
chokidar.watch(nuxtConfigFile, Object.assign({}, nuxt.options.watchers.chokidar, { ignoreInitial: true }))
|
||||
.on('all', build)
|
||||
// Load options
|
||||
let options = {}
|
||||
try {
|
||||
options = loadNuxtConfig()
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return // Wait for next reload
|
||||
}
|
||||
|
||||
// Create nuxt and builder instance
|
||||
const nuxt = new Nuxt(options)
|
||||
const builder = new Builder(nuxt)
|
||||
|
||||
return Promise.resolve()
|
||||
.then(() => builder.build()) // 1- Start build
|
||||
.then(() => oldNuxt ? oldNuxt.close() : Promise.resolve()) // 2- Close old nuxt after successful build
|
||||
.then(() => nuxt.listen(port, host)) // 3- Start listening
|
||||
.then(() => nuxt) // 4- Pass new nuxt to watch chain
|
||||
}
|
||||
|
||||
module.exports = nuxt
|
||||
function loadNuxtConfig () {
|
||||
let options = {}
|
||||
|
||||
if (fs.existsSync(nuxtConfigFile)) {
|
||||
delete require.cache[nuxtConfigFile]
|
||||
options = require(nuxtConfigFile)
|
||||
} else if (argv['config-file'] !== 'nuxt.config.js') {
|
||||
console.error(`> Could not load config file ${argv['config-file']}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
|
||||
// Force development mode for add hot reloading and watching changes
|
||||
options.dev = true
|
||||
|
||||
return options
|
||||
}
|
||||
|
@ -43,17 +43,21 @@ if (argv.help) {
|
||||
const rootDir = resolve(argv._[0] || '.')
|
||||
const nuxtConfigFile = resolve(rootDir, argv['config-file'])
|
||||
|
||||
var options = {}
|
||||
let options = {}
|
||||
|
||||
if (fs.existsSync(nuxtConfigFile)) {
|
||||
options = require(nuxtConfigFile)
|
||||
} else if (argv['config-file'] !== 'nuxt.config.js') {
|
||||
console.error(`> Could not load config file ${argv['config-file']}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (typeof options.rootDir !== 'string') {
|
||||
options.rootDir = rootDir
|
||||
}
|
||||
options.dev = false // Force production mode (no webpack middleware called)
|
||||
|
||||
// Force production mode (no webpack middleware called)
|
||||
options.dev = false
|
||||
|
||||
// Check if project is built for production
|
||||
const distDir = join(options.rootDir, options.buildDir || '.nuxt', 'dist' )
|
||||
@ -65,6 +69,4 @@ if (!fs.existsSync(join(distDir, 'server-bundle.json'))) {
|
||||
const nuxt = new Nuxt(options)
|
||||
const port = argv.port || process.env.PORT || process.env.npm_package_config_nuxt_port
|
||||
const host = argv.hostname || process.env.HOST || process.env.npm_package_config_nuxt_host
|
||||
new Server(nuxt).listen(port, host)
|
||||
|
||||
module.exports = nuxt
|
||||
nuxt.listen(port, host)
|
||||
|
@ -2,7 +2,6 @@ import Options from './options'
|
||||
import ModuleContainer from './module'
|
||||
import Nuxt from './nuxt'
|
||||
import Renderer from './renderer'
|
||||
import Server from './server'
|
||||
import * as Utils from 'utils'
|
||||
|
||||
export default {
|
||||
@ -10,6 +9,5 @@ export default {
|
||||
ModuleContainer,
|
||||
Nuxt,
|
||||
Renderer,
|
||||
Server,
|
||||
Utils
|
||||
}
|
||||
|
@ -1,7 +1,12 @@
|
||||
import Tapable from 'tappable'
|
||||
import chalk from 'chalk'
|
||||
import ModuleContainer from './module'
|
||||
import Renderer from './renderer'
|
||||
import Options from './options'
|
||||
import Debug from 'debug'
|
||||
|
||||
const debug = Debug('nuxt:')
|
||||
debug.color = 5
|
||||
|
||||
export default class Nuxt extends Tapable {
|
||||
constructor (_options = {}) {
|
||||
@ -38,6 +43,34 @@ export default class Nuxt extends Tapable {
|
||||
return this
|
||||
}
|
||||
|
||||
listen (port = 3000, host = 'localhost') {
|
||||
return new Promise((resolve, reject) => {
|
||||
const server = this.renderer.app.listen({ port, host, exclusive: false }, err => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
|
||||
// Show Open URL
|
||||
let _host = host === '0.0.0.0' ? 'localhost' : host
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('\n' + chalk.bold(chalk.bgBlue.black(' OPEN ') + chalk.blue(` http://${_host}:${port}\n`)))
|
||||
|
||||
// Close server on nuxt close
|
||||
this.plugin('close', () => new Promise((_resolve, _reject) => {
|
||||
server.close(_err => {
|
||||
debug('server closed')
|
||||
if (_err) {
|
||||
return _reject(err)
|
||||
}
|
||||
_resolve()
|
||||
})
|
||||
}))
|
||||
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
errorHandler /* istanbul ignore next */ () {
|
||||
// Silent
|
||||
if (this.options.errorHandler === false) {
|
||||
@ -54,7 +87,6 @@ export default class Nuxt extends Tapable {
|
||||
}
|
||||
|
||||
async close (callback) {
|
||||
// Call for close
|
||||
await this.applyPluginsAsync('close')
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
|
@ -21,31 +21,6 @@ setAnsiColors(ansiHTML)
|
||||
|
||||
let jsdom = null
|
||||
|
||||
const parseTemplate = templateStr => _.template(templateStr, {
|
||||
interpolate: /{{([\s\S]+?)}}/g
|
||||
})
|
||||
|
||||
const resourceMap = [
|
||||
{
|
||||
key: 'clientManifest',
|
||||
fileName: 'vue-ssr-client-manifest.json',
|
||||
transform: JSON.parse
|
||||
},
|
||||
{
|
||||
key: 'serverBundle',
|
||||
fileName: 'server-bundle.json',
|
||||
transform: JSON.parse
|
||||
},
|
||||
{
|
||||
key: 'appTemplate',
|
||||
fileName: 'index.html',
|
||||
transform: parseTemplate
|
||||
}
|
||||
]
|
||||
|
||||
// Protector utility against request to SSR bundle files
|
||||
const ssrResourceRegex = new RegExp(resourceMap.map(resource => resource.fileName).join('|'), 'i')
|
||||
|
||||
export default class Renderer extends Tapable {
|
||||
constructor (nuxt) {
|
||||
super()
|
||||
@ -403,3 +378,28 @@ export default class Renderer extends Tapable {
|
||||
return window
|
||||
}
|
||||
}
|
||||
|
||||
const parseTemplate = templateStr => _.template(templateStr, {
|
||||
interpolate: /{{([\s\S]+?)}}/g
|
||||
})
|
||||
|
||||
const resourceMap = [
|
||||
{
|
||||
key: 'clientManifest',
|
||||
fileName: 'vue-ssr-client-manifest.json',
|
||||
transform: JSON.parse
|
||||
},
|
||||
{
|
||||
key: 'serverBundle',
|
||||
fileName: 'server-bundle.json',
|
||||
transform: JSON.parse
|
||||
},
|
||||
{
|
||||
key: 'appTemplate',
|
||||
fileName: 'index.html',
|
||||
transform: parseTemplate
|
||||
}
|
||||
]
|
||||
|
||||
// Protector utility against request to SSR bundle files
|
||||
const ssrResourceRegex = new RegExp(resourceMap.map(resource => resource.fileName).join('|'), 'i')
|
||||
|
@ -1,62 +0,0 @@
|
||||
import http from 'http'
|
||||
import chalk from 'chalk'
|
||||
|
||||
class Server {
|
||||
constructor (nuxt) {
|
||||
this.nuxt = nuxt
|
||||
this.options = nuxt.options
|
||||
|
||||
// Initialize
|
||||
/* istanbul ignore if */
|
||||
if (nuxt.initialized) {
|
||||
// If nuxt already initialized
|
||||
this._ready = this.ready().catch(this.nuxt.errorHandler)
|
||||
} else {
|
||||
// Wait for hook
|
||||
this.nuxt.plugin('afterInit', () => {
|
||||
this._ready = this.ready()
|
||||
return this._ready
|
||||
})
|
||||
}
|
||||
|
||||
// Stop server on nuxt.close()
|
||||
this.nuxt.plugin('close', () => this.close())
|
||||
}
|
||||
|
||||
async ready () {
|
||||
/* istanbul ignore if */
|
||||
if (this._ready) {
|
||||
return this._ready
|
||||
}
|
||||
|
||||
this.server = http.createServer(this.nuxt.render)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
listen (port, host) {
|
||||
host = host || 'localhost'
|
||||
port = port || 3000
|
||||
return this.ready()
|
||||
.then(() => {
|
||||
this.server.listen(port, host, () => {
|
||||
let _host = host === '0.0.0.0' ? 'localhost' : host
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('\n' + chalk.bold(chalk.bgBlue.black(' OPEN ') + chalk.blue(` http://${_host}:${port}\n`)))
|
||||
})
|
||||
}).catch(this.nuxt.errorHandler)
|
||||
}
|
||||
|
||||
close () {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.server.close(err => {
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default Server
|
@ -1,7 +1,7 @@
|
||||
import test from 'ava'
|
||||
import { resolve } from 'path'
|
||||
import rp from 'request-promise-native'
|
||||
import { Nuxt, Server, Builder } from '../index.js'
|
||||
import { Nuxt, Builder } from '../index.js'
|
||||
|
||||
const port = 4001
|
||||
const url = (route) => 'http://localhost:' + port + route
|
||||
@ -17,8 +17,8 @@ test.before('Init Nuxt.js', async t => {
|
||||
}
|
||||
nuxt = new Nuxt(options)
|
||||
await new Builder(nuxt).build()
|
||||
server = new Server(nuxt)
|
||||
server.listen(port, 'localhost')
|
||||
|
||||
await nuxt.listen(port, 'localhost')
|
||||
})
|
||||
|
||||
test('/stateless', async t => {
|
||||
|
@ -30,7 +30,7 @@ test.before('Init Nuxt.js', async t => {
|
||||
server = http.createServer((req, res) => {
|
||||
serve(req, res, finalhandler(req, res))
|
||||
})
|
||||
server.listen(port)
|
||||
await nuxt.listen(port)
|
||||
})
|
||||
|
||||
test('/stateless', async t => {
|
||||
|
@ -2,7 +2,7 @@ import test from 'ava'
|
||||
import { resolve } from 'path'
|
||||
import rp from 'request-promise-native'
|
||||
import stdMocks from 'std-mocks'
|
||||
import { Nuxt, Server, Builder } from '../index.js'
|
||||
import { Nuxt, Builder } from '../index.js'
|
||||
|
||||
const port = 4003
|
||||
const url = (route) => 'http://localhost:' + port + route
|
||||
@ -19,8 +19,8 @@ test.before('Init Nuxt.js', async t => {
|
||||
}
|
||||
nuxt = new Nuxt(options)
|
||||
await new Builder(nuxt).build()
|
||||
server = new Server(nuxt)
|
||||
server.listen(port, 'localhost')
|
||||
|
||||
await nuxt.listen(port, 'localhost')
|
||||
})
|
||||
|
||||
test('/stateless', async t => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import test from 'ava'
|
||||
import { resolve } from 'path'
|
||||
import { Nuxt, Server, Builder } from '../index.js'
|
||||
import { Nuxt, Builder } from '../index.js'
|
||||
|
||||
const port = 4004
|
||||
// const url = (route) => 'http://localhost:' + port + route
|
||||
@ -17,8 +17,8 @@ test.before('Init Nuxt.js', async t => {
|
||||
}
|
||||
nuxt = new Nuxt(options)
|
||||
await new Builder(nuxt).build()
|
||||
server = new Server(nuxt)
|
||||
server.listen(port, 'localhost')
|
||||
|
||||
await nuxt.listen(port, 'localhost')
|
||||
})
|
||||
|
||||
test('/parent', async t => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import test from 'ava'
|
||||
import { resolve } from 'path'
|
||||
import { Nuxt, Server, Builder } from '../index.js'
|
||||
import { Nuxt, Builder } from '../index.js'
|
||||
|
||||
const port = 4005
|
||||
const url = (route) => 'http://localhost:' + port + route
|
||||
@ -17,8 +17,8 @@ test.before('Init Nuxt.js', async t => {
|
||||
}
|
||||
nuxt = new Nuxt(options)
|
||||
await new Builder(nuxt).build()
|
||||
server = new Server(nuxt)
|
||||
server.listen(port, 'localhost')
|
||||
|
||||
await nuxt.listen(port, 'localhost')
|
||||
})
|
||||
|
||||
test('/ should display an error', async t => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import test from 'ava'
|
||||
import { resolve, normalize } from 'path'
|
||||
import rp from 'request-promise-native'
|
||||
import { Nuxt, Server, Builder } from '../index.js'
|
||||
import { Nuxt, Builder } from '../index.js'
|
||||
|
||||
const port = 4006
|
||||
const url = (route) => 'http://localhost:' + port + route
|
||||
@ -18,8 +18,8 @@ test.before('Init Nuxt.js', async t => {
|
||||
config.runBuild = true
|
||||
nuxt = new Nuxt(config)
|
||||
await new Builder(nuxt).build()
|
||||
server = new Server(nuxt)
|
||||
server.listen(port, 'localhost')
|
||||
|
||||
await nuxt.listen(port, 'localhost')
|
||||
})
|
||||
|
||||
test('Vendor', async t => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import test from 'ava'
|
||||
import { resolve } from 'path'
|
||||
import rp from 'request-promise-native'
|
||||
import { Nuxt, Server, Builder } from '../index.js'
|
||||
import { Nuxt, Builder } from '../index.js'
|
||||
|
||||
const port = 4007
|
||||
const url = (route) => 'http://localhost:' + port + route
|
||||
@ -18,8 +18,8 @@ test.before('Init Nuxt.js', async t => {
|
||||
config.runBuild = true
|
||||
nuxt = new Nuxt(config)
|
||||
await new Builder(nuxt).build()
|
||||
server = new Server(nuxt)
|
||||
server.listen(port, 'localhost')
|
||||
|
||||
await nuxt.listen(port, 'localhost')
|
||||
})
|
||||
|
||||
test('/', async t => {
|
||||
|
Loading…
Reference in New Issue
Block a user