Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 2 commits into from
Oct 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/cli/src/commands/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export default async function build() {
process.exit(0)
}

const options = loadNuxtConfig(argv)
const options = await loadNuxtConfig(argv)

// Create production build when calling `nuxt build`
options.dev = false
Expand Down
18 changes: 10 additions & 8 deletions packages/cli/src/commands/dev.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import parseArgs from 'minimist'
import consola from 'consola'
import { loadNuxtConfig } from '../common/utils'
import { loadNuxtConfig, runAsyncScript } from '../common/utils'

export default async function dev() {
const { Nuxt } = await import('@nuxt/core')
Expand Down Expand Up @@ -50,9 +50,9 @@ export default async function dev() {
process.exit(0)
}

const config = () => {
const config = async () => {
// 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) => {
Expand All @@ -61,15 +61,15 @@ export default async function dev() {
}

// Start dev
(function startDev(oldInstance) {
async function startDev(oldInstance) {
let nuxt, builder

try {
nuxt = new Nuxt(config())
nuxt = new Nuxt(await config())
builder = new Builder(nuxt)
nuxt.hook('watch:fileChanged', (builder, fname) => {
nuxt.hook('watch:fileChanged', async (builder, fname) => {
consola.debug(`[${fname}] changed, Rebuilding the app...`)
startDev({ nuxt: builder.nuxt, builder })
await startDev({ nuxt: builder.nuxt, builder })
})
} catch (err) {
return errorHandler(err, oldInstance)
Expand All @@ -96,5 +96,7 @@ export default async function dev() {
// Handle errors
.catch(err => errorHandler(err, { builder, nuxt }))
)
})()
}

await runAsyncScript(startDev)
}
2 changes: 1 addition & 1 deletion packages/cli/src/commands/generate.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export default async function generate() {
process.exit(0)
}

const options = loadNuxtConfig(argv)
const options = await loadNuxtConfig(argv)

options.dev = false // Force production mode (no webpack middleware called)

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export default async function start() {
process.exit(0)
}

const options = loadNuxtConfig(argv)
const options = await loadNuxtConfig(argv)

// Force production mode (no webpack middleware called)
options.dev = false
Expand Down
20 changes: 18 additions & 2 deletions packages/cli/src/common/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import path from 'path'
import { existsSync } from 'fs'
import consola from 'consola'
Expand Down Expand Up @@ -34,7 +33,16 @@ const getLatestHost = (argv) => {
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 nuxtConfigFile = getNuxtConfigFile(argv)

Expand All @@ -49,6 +57,14 @@ export function loadNuxtConfig(argv) {
if (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') {
consola.fatal('Could not load config file: ' + argv['config-file'])
}
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/async-config/async-config.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { buildFixture } from '../../utils/build'

buildFixture('async-config')
10 changes: 10 additions & 0 deletions test/fixtures/async-config/nuxt.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const createData = async () => {
await new Promise(resolve => setTimeout(resolve, 500))
return {
head: {
title: 'Async Config!'
}
}
}

export default createData
3 changes: 3 additions & 0 deletions test/fixtures/async-config/pages/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<template>
<h1>I am ALIVE!</h1>
</template>
19 changes: 19 additions & 0 deletions test/unit/async-config.test.js
Original file line number Diff line number Diff line change
@@ -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)
})
})
5 changes: 4 additions & 1 deletion test/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ export const loadFixture = async function (fixture, overrides) {
const rootDir = path.resolve(__dirname, '..', 'fixtures', fixture)
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.dev = false
Expand Down