fixes + improvements

This commit is contained in:
Pooya Parsa 2017-06-14 02:39:03 +04:30
parent 37c92e7398
commit c519c3edff
7 changed files with 74 additions and 94 deletions

View File

@ -53,38 +53,43 @@ export default class Builder extends Tapable {
} }
// Register lifecycle hooks // Register lifecycle hooks
if (this.nuxt.options.dev) {
// Don't await for build on dev (faster startup)
this.nuxt.plugin('afterInit', () => { this.nuxt.plugin('afterInit', () => {
if (this.nuxt.dev) { this.build().catch(this.nuxt.errorHandler)
// But don't await for builder on dev (faster startup)
this.build().catch(err => {
// eslint-disable-next-line no-console
console.error(err)
}) })
} else { } else {
this.nuxt.plugin('init', () => {
// Guess it is build or production
// If build is not called it may be nuxt.start
if (this._buildStatus === STATUS.INITIAL) {
return this.production() return this.production()
} }
}) })
}
this._buildStatus = STATUS.INITIAL this._buildStatus = STATUS.INITIAL
} }
async build () { async build () {
// Ensure nuxt initialized
await this.nuxt.init()
// Avoid calling this method multiple times // Avoid calling this method multiple times
if (this._buildStatus === STATUS.BUILD_DONE) { if (this._buildStatus === STATUS.BUILD_DONE) {
return this return this
} }
// If building // If building
if (this._buildStatus === STATUS.BUILDING) { if (this._buildStatus === STATUS.BUILDING) {
return new Promise((resolve) => { return new Promise((resolve) => {
setTimeout(() => { setTimeout(() => {
resolve(this.build()) resolve(this.build())
}, 300) }, 1000)
}) })
} }
this._buildStatus = STATUS.BUILDING this._buildStatus = STATUS.BUILDING
// Ensure nuxt initialized
await this.nuxt.init()
// Check if pages dir exists and warn if not // Check if pages dir exists and warn if not
this._nuxtPages = typeof this.options.build.createRoutes !== 'function' this._nuxtPages = typeof this.options.build.createRoutes !== 'function'
@ -92,11 +97,10 @@ export default class Builder extends Tapable {
if (!fs.existsSync(join(this.options.srcDir, 'pages'))) { if (!fs.existsSync(join(this.options.srcDir, 'pages'))) {
let dir = this.options.srcDir let dir = this.options.srcDir
if (fs.existsSync(join(this.options.srcDir, '..', 'pages'))) { if (fs.existsSync(join(this.options.srcDir, '..', 'pages'))) {
console.error(`> No 'pages' directory found in ${dir}. Did you mean to run 'nuxt' in the parent ('../') directory?`) // eslint-disable-line no-console throw new Error(`No \`pages\` directory found in ${dir}. Did you mean to run \`nuxt\` in the parent (\`../\`) directory?`)
} else { } else {
console.error(`> Couldn't find a 'pages' directory in ${dir}. Please create one under the project root`) // eslint-disable-line no-console throw new Error(`Couldn't find a \`pages\` directory in ${dir}. Please create one under the project root`)
} }
process.exit(1)
} }
} }
@ -124,10 +128,7 @@ export default class Builder extends Tapable {
const bundlePath = join(serverConfig.output.path, 'server-bundle.json') const bundlePath = join(serverConfig.output.path, 'server-bundle.json')
const manifestPath = join(serverConfig.output.path, 'client-manifest.json') const manifestPath = join(serverConfig.output.path, 'client-manifest.json')
if (!fs.existsSync(bundlePath) || !fs.existsSync(manifestPath)) { if (!fs.existsSync(bundlePath) || !fs.existsSync(manifestPath)) {
console.error('[warning] No build files found, trying to build for production') // eslint-disable-line no-console throw new Error('No build files found, please run `nuxt build` before launching `nuxt start`')
return this.build().then(() => {
return this.production()
})
} }
const bundle = fs.readFileSync(bundlePath, 'utf8') const bundle = fs.readFileSync(bundlePath, 'utf8')
const manifest = fs.readFileSync(manifestPath, 'utf8') const manifest = fs.readFileSync(manifestPath, 'utf8')

View File

@ -24,9 +24,6 @@ export default class Generator extends Tapable {
let errors = [] let errors = []
let generateRoutes = [] let generateRoutes = []
// Wait for nuxt.js to be ready
await this.nuxt.init()
// Set variables // Set variables
let srcStaticPath = resolve(this.options.srcDir, 'static') let srcStaticPath = resolve(this.options.srcDir, 'static')
let srcBuiltPath = resolve(this.options.buildDir, 'dist') let srcBuiltPath = resolve(this.options.buildDir, 'dist')
@ -55,7 +52,6 @@ export default class Generator extends Tapable {
} catch (e) { } catch (e) {
console.error('Could not resolve routes') // eslint-disable-line no-console console.error('Could not resolve routes') // eslint-disable-line no-console
console.error(e) // eslint-disable-line no-console console.error(e) // eslint-disable-line no-console
process.exit(1)
throw e // eslint-disable-line no-unreachable throw e // eslint-disable-line no-unreachable
} }
} }

View File

@ -96,7 +96,7 @@ export default class ModuleContainer extends Tapable {
const originalSrc = moduleOpts.src || moduleOpts const originalSrc = moduleOpts.src || moduleOpts
// Resolve module // Resolve module
let module = originalSrc let module = originalSrc
try {
if (typeof module === 'string') { if (typeof module === 'string') {
// Using ~ or ./ shorthand modules are resolved from project srcDir // Using ~ or ./ shorthand modules are resolved from project srcDir
if (module.indexOf('~') === 0 || module.indexOf('./') === 0) { if (module.indexOf('~') === 0 || module.indexOf('./') === 0) {
@ -105,19 +105,11 @@ export default class ModuleContainer extends Tapable {
// eslint-disable-next-line no-eval // eslint-disable-next-line no-eval
module = eval('require')(module) module = eval('require')(module)
} }
} catch (e) /* istanbul ignore next */ {
// eslint-disable-next-line no-console
console.error('[nuxt] Unable to resolve module', module)
// eslint-disable-next-line no-console
console.error(e)
process.exit(0)
}
// Validate module // Validate module
/* istanbul ignore if */ /* istanbul ignore if */
if (typeof module !== 'function') { if (typeof module !== 'function') {
// eslint-disable-next-line no-console throw new Error(`[nuxt] Module ${JSON.stringify(originalSrc)} should export a function`)
console.error(`[nuxt] Module [${originalSrc}] should export a function`)
process.exit(1)
} }
// Module meta // Module meta
if (!module.meta) { if (!module.meta) {

View File

@ -62,11 +62,12 @@ export default class Nuxt extends Tapable {
this.dir = options.rootDir this.dir = options.rootDir
this.srcDir = options.srcDir this.srcDir = options.srcDir
this.buildDir = options.buildDir this.buildDir = options.buildDir
this.dev = options.dev
this.Server = Nuxt.Server this.Server = Nuxt.Server
this.Utils = Nuxt.Utils this.Utils = Nuxt.Utils
// eslint-disable-next-line no-console this.errorHandler = this.errorHandler.bind(this)
this._init = this.init().catch(console.error) this._init = this.init().catch(this.errorHandler)
this.initialized = false this.initialized = false
} }
@ -74,14 +75,35 @@ export default class Nuxt extends Tapable {
if (this._init) { if (this._init) {
return this._init return this._init
} }
// Wait for all components to be ready // Wait for all components to be ready
// Including modules
await this.applyPluginsAsync('beforeInit') await this.applyPluginsAsync('beforeInit')
// Including Build
await this.applyPluginsAsync('init') await this.applyPluginsAsync('init')
this.applyPluginsAsync('afterInit') // Extra jobs
this.applyPluginsAsync('afterInit').catch(this.errorHandler)
this.initialized = true this.initialized = true
return this return this
} }
errorHandler () {
// Global error handler
// Silent
if (this.options.errorHandler === false) {
return
}
// Custom eventHandler
if (typeof this.options.errorHandler === 'function') {
return this.options.errorHandler.apply(this, arguments)
}
// Default
// eslint-disable-next-line no-console
console.error.apply(this, arguments)
process.exit(1)
}
async close (callback) { async close (callback) {
let promises = [] let promises = []
/* istanbul ignore if */ /* istanbul ignore if */

View File

@ -183,7 +183,7 @@ export default class Renderer extends Tapable {
console.error('Fail when calling nuxt.renderAndGetWindow(url)') // eslint-disable-line no-console console.error('Fail when calling nuxt.renderAndGetWindow(url)') // eslint-disable-line no-console
console.error('jsdom module is not installed') // eslint-disable-line no-console console.error('jsdom module is not installed') // eslint-disable-line no-console
console.error('Please install jsdom with: npm install --save-dev jsdom') // eslint-disable-line no-console console.error('Please install jsdom with: npm install --save-dev jsdom') // eslint-disable-line no-console
process.exit(1) throw e
} }
} }
let options = { let options = {

View File

@ -7,29 +7,14 @@ test('Fail with routes() which throw an error', async t => {
rootDir: resolve(__dirname, 'fixtures/basic'), rootDir: resolve(__dirname, 'fixtures/basic'),
dev: false, dev: false,
generate: { generate: {
routes: function () { async routes () {
return new Promise((resolve, reject) => { throw new Error('Not today!')
reject(new Error('Not today!'))
})
} }
} }
} }
const nuxt = new Nuxt(options) const nuxt = new Nuxt(options)
return new Promise((resolve) => { return nuxt.generate()
var oldExit = process.exit
var oldCE = console.error // eslint-disable-line no-console
var _log = ''
console.error = (s) => { _log += s } // eslint-disable-line no-console
process.exit = (code) => {
process.exit = oldExit
console.error = oldCE // eslint-disable-line no-console
t.is(code, 1)
t.true(_log.includes('Could not resolve routes'))
resolve()
}
nuxt.generate()
.catch((e) => { .catch((e) => {
t.true(e.message === 'Not today!') t.true(e.message === 'Not today!')
}) })
}) })
})

View File

@ -21,44 +21,28 @@ test.serial('Nuxt.js Instance', async t => {
t.is(nuxt.initialized, true) t.is(nuxt.initialized, true)
}) })
test.serial('Fail to build when no pages/ directory but is in the parent', async t => { test.serial('Fail to build when no pages/ directory but is in the parent', t => {
const nuxt = new Nuxt({ const nuxt = new Nuxt({
dev: true, dev: false,
rootDir: resolve(__dirname, 'fixtures', 'empty', 'pages') rootDir: resolve(__dirname, 'fixtures', 'empty', 'pages')
}) })
return new Promise((resolve) => { return nuxt.build().catch(err => {
let oldExit = process.exit let s = String(err)
let oldCE = console.error // eslint-disable-line no-console t.true(s.includes('No `pages` directory found'))
let _log = '' t.true(s.includes('Did you mean to run `nuxt` in the parent (`../`) directory?'))
console.error = (s) => { _log += s } // eslint-disable-line no-console
process.exit = (code) => {
process.exit = oldExit
console.error = oldCE // eslint-disable-line no-console
t.is(code, 1)
t.true(_log.includes('No `pages` directory found. Did you mean to run `nuxt` in the parent (`../`) directory?'))
resolve() resolve()
}
nuxt.build()
}) })
}) })
test.serial('Fail to build when no pages/ directory', async t => { test.serial('Fail to build when no pages/ directory', t => {
const nuxt = new Nuxt({ const nuxt = new Nuxt({
dev: true, dev: false,
rootDir: resolve(__dirname) rootDir: resolve(__dirname)
}) })
return new Promise((resolve) => { return nuxt.build().catch(err => {
let oldExit = process.exit let s = String(err)
let oldCE = console.error // eslint-disable-line no-console t.true(s.includes('Couldn\'t find a `pages` directory'))
let _log = '' t.true(s.includes('Please create one under the project root'))
console.error = (s) => { _log += s } // eslint-disable-line no-console
process.exit = (code) => {
process.exit = oldExit
console.error = oldCE // eslint-disable-line no-console
t.is(code, 1)
t.true(_log.includes('Couldn\'t find a `pages` directory. Please create one under the project root'))
resolve() resolve()
}
nuxt.build()
}) })
}) })