feat(cli): support async nuxt.config.js (#4021)

This commit is contained in:
Alexander Lichter 2018-10-18 16:57:35 +01:00 committed by Pooya Parsa
parent ab5af540e0
commit f27939d4a7
10 changed files with 70 additions and 14 deletions

View File

@ -41,7 +41,7 @@ export default async function build() {
process.exit(0) process.exit(0)
} }
const options = loadNuxtConfig(argv) const options = await loadNuxtConfig(argv)
// Create production build when calling `nuxt build` // Create production build when calling `nuxt build`
options.dev = false options.dev = false

View File

@ -1,6 +1,6 @@
import parseArgs from 'minimist' import parseArgs from 'minimist'
import consola from 'consola' import consola from 'consola'
import { loadNuxtConfig } from '../common/utils' import { loadNuxtConfig, runAsyncScript } from '../common/utils'
export default async function dev() { export default async function dev() {
const { Nuxt } = await import('@nuxt/core') const { Nuxt } = await import('@nuxt/core')
@ -50,9 +50,9 @@ export default async function dev() {
process.exit(0) process.exit(0)
} }
const config = () => { const config = async () => {
// Force development mode for add hot reloading and watching changes // Force development mode for add hot reloading and watching changes
return Object.assign(loadNuxtConfig(argv), { dev: true }) return Object.assign(await loadNuxtConfig(argv), { dev: true })
} }
const errorHandler = (err, instance) => { const errorHandler = (err, instance) => {
@ -61,15 +61,15 @@ export default async function dev() {
} }
// Start dev // Start dev
(function startDev(oldInstance) { async function startDev(oldInstance) {
let nuxt, builder let nuxt, builder
try { try {
nuxt = new Nuxt(config()) nuxt = new Nuxt(await config())
builder = new Builder(nuxt) builder = new Builder(nuxt)
nuxt.hook('watch:fileChanged', (builder, fname) => { nuxt.hook('watch:fileChanged', async (builder, fname) => {
consola.debug(`[${fname}] changed, Rebuilding the app...`) consola.debug(`[${fname}] changed, Rebuilding the app...`)
startDev({ nuxt: builder.nuxt, builder }) await startDev({ nuxt: builder.nuxt, builder })
}) })
} catch (err) { } catch (err) {
return errorHandler(err, oldInstance) return errorHandler(err, oldInstance)
@ -96,5 +96,7 @@ export default async function dev() {
// Handle errors // Handle errors
.catch(err => errorHandler(err, { builder, nuxt })) .catch(err => errorHandler(err, { builder, nuxt }))
) )
})() }
await runAsyncScript(startDev)
} }

View File

@ -38,7 +38,7 @@ export default async function generate() {
process.exit(0) process.exit(0)
} }
const options = loadNuxtConfig(argv) const options = await loadNuxtConfig(argv)
options.dev = false // Force production mode (no webpack middleware called) options.dev = false // Force production mode (no webpack middleware called)

View File

@ -48,7 +48,7 @@ export default async function start() {
process.exit(0) process.exit(0)
} }
const options = loadNuxtConfig(argv) const options = await loadNuxtConfig(argv)
// Force production mode (no webpack middleware called) // Force production mode (no webpack middleware called)
options.dev = false options.dev = false

View File

@ -1,4 +1,3 @@
import path from 'path' import path from 'path'
import { existsSync } from 'fs' import { existsSync } from 'fs'
import consola from 'consola' import consola from 'consola'
@ -34,7 +33,16 @@ const getLatestHost = (argv) => {
return { port, host, socket } return { port, host, socket }
} }
export function loadNuxtConfig(argv) { export async function runAsyncScript(fn) {
try {
await fn()
} catch (err) {
consola.error(err)
consola.fatal(`Failed to run async Nuxt script!`)
}
}
export async function loadNuxtConfig(argv) {
const rootDir = getRootDir(argv) const rootDir = getRootDir(argv)
const nuxtConfigFile = getNuxtConfigFile(argv) const nuxtConfigFile = getNuxtConfigFile(argv)
@ -49,6 +57,14 @@ export function loadNuxtConfig(argv) {
if (options.default) { if (options.default) {
options = options.default options = options.default
} }
if (typeof options === 'function') {
try {
options = await options()
} catch (error) {
consola.error(error)
consola.fatal('Error while fetching async configuration')
}
}
} else if (argv['config-file'] !== 'nuxt.config.js') { } else if (argv['config-file'] !== 'nuxt.config.js') {
consola.fatal('Could not load config file: ' + argv['config-file']) consola.fatal('Could not load config file: ' + argv['config-file'])
} }

View File

@ -0,0 +1,3 @@
import { buildFixture } from '../../utils/build'
buildFixture('async-config')

View File

@ -0,0 +1,10 @@
const createData = async () => {
await new Promise(resolve => setTimeout(resolve, 500))
return {
head: {
title: 'Async Config!'
}
}
}
export default createData

View File

@ -0,0 +1,3 @@
<template>
<h1>I am ALIVE!</h1>
</template>

View File

@ -0,0 +1,19 @@
import { getPort, loadFixture, Nuxt } from '../utils'
let port
let nuxt = null
describe('basic ssr', () => {
beforeAll(async () => {
const options = await loadFixture('async-config')
nuxt = new Nuxt(options)
port = await getPort()
await nuxt.listen(port, '0.0.0.0')
})
test('/', async () => {
expect(nuxt.options.head.title).toBe('Async Config!')
const { html } = await nuxt.renderRoute('/')
expect(html.includes('<h1>I am ALIVE!</h1>')).toBe(true)
})
})

View File

@ -23,7 +23,10 @@ export const loadFixture = async function (fixture, overrides) {
const rootDir = path.resolve(__dirname, '..', 'fixtures', fixture) const rootDir = path.resolve(__dirname, '..', 'fixtures', fixture)
const configFile = path.resolve(rootDir, 'nuxt.config.js') const configFile = path.resolve(rootDir, 'nuxt.config.js')
const config = fs.existsSync(configFile) ? (await import(`../fixtures/${fixture}/nuxt.config`)).default : {} let config = fs.existsSync(configFile) ? (await import(`../fixtures/${fixture}/nuxt.config`)).default : {}
if (typeof config === 'function') {
config = await config()
}
config.rootDir = rootDir config.rootDir = rootDir
config.dev = false config.dev = false