feat: improve programatic usage (#6868)

This commit is contained in:
Pooya Parsa 2020-01-19 09:36:06 +01:00 committed by GitHub
parent 8907e1553f
commit 2707bdb37e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 183 additions and 58 deletions

View File

@ -0,0 +1,5 @@
export default {
head: {
title: 'Programmatic Works'
}
}

View File

@ -0,0 +1,12 @@
{
"name": "example-programmatic",
"dependencies": {
"nuxt": "latest"
},
"scripts": {
"dev": "node scripts/dev",
"build": "node scripts/build",
"start": "node scripts/start",
"post-update": "yarn upgrade --latest"
}
}

View File

@ -0,0 +1,5 @@
<template>
<div>
Works
</div>
</template>

View File

@ -0,0 +1,8 @@
const { loadNuxt, build } = require('nuxt')
const main = async () => {
const nuxt = await loadNuxt({ for: 'build' })
await build(nuxt)
}
main()

View File

@ -0,0 +1,9 @@
const { loadNuxt, build } = require('nuxt')
const main = async () => {
const nuxt = await loadNuxt({ for: 'dev' })
build(nuxt)
await nuxt.listen(3000)
}
main()

View File

@ -0,0 +1,8 @@
const { loadNuxt } = require('nuxt-start')
const main = async () => {
const nuxt = await loadNuxt({ for: 'start' })
await nuxt.listen(3000)
}
main()

View File

@ -1 +1,10 @@
import Builder from './builder'
export { default as Builder } from './builder' export { default as Builder } from './builder'
export function getBuilder (nuxt) {
return new Builder(nuxt)
}
export function build (nuxt) {
return getBuilder(nuxt).build()
}

View File

@ -1,67 +1,20 @@
import path from 'path' import path from 'path'
import consola from 'consola'
import defaultsDeep from 'lodash/defaultsDeep' import defaultsDeep from 'lodash/defaultsDeep'
import { defaultNuxtConfigFile, getDefaultNuxtConfig } from '@nuxt/config' import { loadNuxtConfig as _loadNuxtConfig, getDefaultNuxtConfig } from '@nuxt/config'
import { clearRequireCache, scanRequireTree } from '@nuxt/utils'
import esm from 'esm'
export async function loadNuxtConfig (argv, context) { export async function loadNuxtConfig (argv, configContext) {
const rootDir = path.resolve(argv._[0] || '.') const rootDir = path.resolve(argv._[0] || '.')
let nuxtConfigFile const configFile = argv['config-file']
let options = {}
try { // Load config
nuxtConfigFile = require.resolve(path.resolve(rootDir, argv['config-file'])) const options = await _loadNuxtConfig({
} catch (e) { rootDir,
if (e.code !== 'MODULE_NOT_FOUND') { configFile,
throw (e) configContext
} else if (argv['config-file'] !== defaultNuxtConfigFile) { })
consola.fatal('Could not load config file: ' + argv['config-file'])
}
}
if (nuxtConfigFile) {
// Clear cache
clearRequireCache(nuxtConfigFile)
options = esm(module)(nuxtConfigFile) || {}
if (options.default) {
options = options.default
}
if (typeof options === 'function') {
try {
options = await options(context)
if (options.default) {
options = options.default
}
} catch (error) {
consola.error(error)
consola.fatal('Error while fetching async configuration')
}
}
// Don't mutate options export
options = Object.assign({}, options)
// Keep _nuxtConfigFile for watching
options._nuxtConfigFile = nuxtConfigFile
// Keep all related files for watching
options._nuxtConfigFiles = Array.from(scanRequireTree(nuxtConfigFile))
if (!options._nuxtConfigFiles.includes(nuxtConfigFile)) {
options._nuxtConfigFiles.unshift(nuxtConfigFile)
}
}
if (typeof options.rootDir !== 'string') {
options.rootDir = rootDir
}
// Nuxt Mode // Nuxt Mode
options.mode = options.mode = (argv.spa && 'spa') || (argv.universal && 'universal') || options.mode
(argv.spa && 'spa') || (argv.universal && 'universal') || options.mode
// Server options // Server options
options.server = defaultsDeep({ options.server = defaultsDeep({

View File

@ -56,7 +56,7 @@ describe('cli/utils', () => {
expect(options.testOption).not.toBeDefined() expect(options.testOption).not.toBeDefined()
expect(consola.fatal).toHaveBeenCalledTimes(1) expect(consola.fatal).toHaveBeenCalledTimes(1)
expect(consola.fatal).toHaveBeenCalledWith(expect.stringMatching(/Could not load config file/)) expect(consola.fatal).toHaveBeenCalledWith(expect.stringMatching(/Config file not found/))
}) })
test('loadNuxtConfig: async config-file', async () => { test('loadNuxtConfig: async config-file', async () => {

View File

@ -1,2 +1,3 @@
export { defaultNuxtConfigFile, getDefaultNuxtConfig } from './config' export { defaultNuxtConfigFile, getDefaultNuxtConfig } from './config'
export { getNuxtConfig } from './options' export { getNuxtConfig } from './options'
export { loadNuxtConfig } from './load'

View File

@ -0,0 +1,68 @@
import path from 'path'
import consola from 'consola'
import { clearRequireCache, scanRequireTree } from '@nuxt/utils'
import esm from 'esm'
import { defaultNuxtConfigFile } from './config'
export async function loadNuxtConfig ({
rootDir = '.',
configFile = defaultNuxtConfigFile,
configContext = {}
} = {}) {
rootDir = path.resolve(rootDir)
let options = {}
try {
configFile = require.resolve(path.resolve(rootDir, configFile))
} catch (e) {
if (e.code !== 'MODULE_NOT_FOUND') {
throw (e)
} else if (configFile !== defaultNuxtConfigFile) {
consola.fatal('Config file not found: ' + configFile)
}
// Skip configFile if cannot resolve
configFile = undefined
}
if (configFile) {
// Clear cache
clearRequireCache(configFile)
options = esm(module)(configFile) || {}
if (options.default) {
options = options.default
}
if (typeof options === 'function') {
try {
options = await options(configContext)
if (options.default) {
options = options.default
}
} catch (error) {
consola.error(error)
consola.fatal('Error while fetching async configuration')
}
}
// Don't mutate options export
options = Object.assign({}, options)
// Keep _nuxtConfigFile for watching
options._nuxtConfigFile = configFile
// Keep all related files for watching
options._nuxtConfigFiles = Array.from(scanRequireTree(configFile))
if (!options._nuxtConfigFiles.includes(configFile)) {
options._nuxtConfigFiles.unshift(configFile)
}
}
if (typeof options.rootDir !== 'string') {
options.rootDir = rootDir
}
return options
}

View File

@ -1,3 +1,5 @@
export { default as Module } from './module' export { default as Module } from './module'
export { default as Nuxt } from './nuxt' export { default as Nuxt } from './nuxt'
export { default as Resolver } from './resolver' export { default as Resolver } from './resolver'
export { loadNuxtConfig } from '@nuxt/config'
export { loadNuxt } from './load'

40
packages/core/src/load.js Normal file
View File

@ -0,0 +1,40 @@
import { loadNuxtConfig } from '@nuxt/config'
import Nuxt from './nuxt'
const OVERRIDES = {
dry: { dev: false, server: false },
dev: { dev: true, _build: true },
build: { dev: false, server: false, _build: true },
start: { dev: false, _start: true }
}
export async function loadNuxt (loadOptions) {
// Normalize loadOptions
if (typeof loadOptions === 'string') {
loadOptions = { for: loadOptions }
}
const { ready = true } = loadOptions
const _for = loadOptions.for || 'dry'
// Get overrides
const override = OVERRIDES[_for]
// Unsupported purpose
if (!override) {
throw new Error('Unsupported for: ' + _for)
}
// Load Config
const config = await loadNuxtConfig(loadOptions)
// Apply config overrides
Object.assign(config, override)
// Initiate Nuxt
const nuxt = new Nuxt(config)
if (ready) {
await nuxt.ready()
}
return nuxt
}

View File

@ -1 +1,6 @@
import Generator from './generator'
export { default as Generator } from './generator' export { default as Generator } from './generator'
export function getGenerator (nuxt) {
return new Generator(nuxt)
}