refactor: improve cli and kit types (#369)

[skip-release] 

Co-authored-by: Pooya Parsa <pyapar@gmail.com>
This commit is contained in:
Daniel Roe 2021-07-26 15:04:35 +01:00 committed by GitHub
parent b3526ba0a4
commit 8c09d05ad2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 117 additions and 87 deletions

View File

@ -1,25 +1,28 @@
import { resolve } from 'upath'
import { requireModule } from '../utils/cjs'
import { error } from '../utils/log'
export async function invoke (args) {
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
const rootDir = resolve(args._[0] || '.')
import { defineNuxtCommand } from './index'
const { loadNuxt, buildNuxt } = requireModule('@nuxt/kit', rootDir)
export default defineNuxtCommand({
meta: {
name: 'build',
usage: 'nu build [rootDir]',
description: 'Build nuxt for production deployment'
},
async invoke (args) {
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
const rootDir = resolve(args._[0] || '.')
const nuxt = await loadNuxt({ rootDir })
const { loadNuxt, buildNuxt } = requireModule('@nuxt/kit', rootDir) as typeof import('@nuxt/kit')
nuxt.hook('error', (err) => {
error('Nuxt Build Error:', err)
process.exit(1)
})
const nuxt = await loadNuxt({ rootDir })
await buildNuxt(nuxt)
}
nuxt.hook('error', (err) => {
error('Nuxt Build Error:', err)
process.exit(1)
})
export const meta = {
usage: 'nu build [rootDir]',
description: 'Build nuxt for production deployment'
}
await buildNuxt(nuxt)
}
})

View File

@ -1,65 +1,69 @@
import { resolve } from 'upath'
import chokidar from 'chokidar'
import debounce from 'debounce-promise'
import type { Nuxt } from '@nuxt/kit'
import { createServer, createLoadingHandler } from '../utils/server'
import { showBanner } from '../utils/banner'
import { requireModule } from '../utils/cjs'
import { error } from '../utils/log'
import { defineNuxtCommand } from './index'
export async function invoke (args) {
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
const server = createServer()
const listener = await server.listen({
clipboard: args.clipboard,
open: args.open || args.o
})
export default defineNuxtCommand({
meta: {
name: 'dev',
usage: 'nu dev [rootDir] [--clipboard] [--open, -o]',
description: 'Run nuxt development server'
},
async invoke (args) {
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
const server = createServer()
const listener = await server.listen({
clipboard: args.clipboard,
open: args.open || args.o
})
const rootDir = resolve(args._[0] || '.')
const rootDir = resolve(args._[0] || '.')
const { loadNuxt, buildNuxt } = requireModule('@nuxt/kit', rootDir)
const { loadNuxt, buildNuxt } = requireModule('@nuxt/kit', rootDir) as typeof import('@nuxt/kit')
let currentNuxt
const load = async (isRestart) => {
try {
const message = `${isRestart ? 'Restarting' : 'Starting'} nuxt...`
server.setApp(createLoadingHandler(message))
if (isRestart) {
console.log(message)
let currentNuxt: Nuxt
const load = async (isRestart: boolean) => {
try {
const message = `${isRestart ? 'Restarting' : 'Starting'} nuxt...`
server.setApp(createLoadingHandler(message))
if (isRestart) {
console.log(message)
}
if (currentNuxt) {
await currentNuxt.close()
}
const newNuxt = await loadNuxt({ rootDir, dev: true, ready: false })
currentNuxt = newNuxt
await currentNuxt.ready()
await buildNuxt(currentNuxt)
server.setApp(currentNuxt.server.app)
if (isRestart && args.clear !== false) {
showBanner()
listener.showURL()
}
} catch (err) {
error(`Cannot ${isRestart ? 'restart' : 'start'} nuxt: `, err)
server.setApp(createLoadingHandler(
'Error while loading nuxt. Please check console and fix errors.'
))
}
if (currentNuxt) {
await currentNuxt.close()
}
const newNuxt = await loadNuxt({ rootDir, dev: true, ready: false })
currentNuxt = newNuxt
await currentNuxt.ready()
await buildNuxt(currentNuxt)
server.setApp(currentNuxt.server.app)
if (isRestart && args.clear !== false) {
showBanner()
listener.showURL()
}
} catch (err) {
error(`Cannot ${isRestart ? 'restart' : 'start'} nuxt: `, err)
server.setApp(createLoadingHandler(
'Error while loading nuxt. Please check console and fix errors.'
))
}
// Watch for config changes
// TODO: Watcher service, modules, and requireTree
const dLoad = debounce(load, 250)
const watcher = chokidar.watch([rootDir], { ignoreInitial: true, depth: 1 })
watcher.on('all', (_event, file) => {
if (file.includes('nuxt.config') || file.includes('modules')) {
dLoad(true)
}
})
await load(false)
}
// Watch for config changes
// TODO: Watcher service, modules, and requireTree
const dLoad = debounce(load, 250)
const watcher = chokidar.watch([rootDir], { ignoreInitial: true, depth: 1 })
watcher.on('all', (_event, file) => {
if (file.includes('nuxt.config') || file.includes('modules')) {
dLoad(true)
}
})
await load(false)
}
export const meta = {
usage: 'nu dev [rootDir] [--clipboard] [--open, -o]',
description: 'Run nuxt development server'
}
})

View File

@ -1,5 +1,25 @@
import type { Argv } from 'mri'
export const commands = {
dev: () => import('./dev'),
build: () => import('./build'),
usage: () => import('./usage')
}
export type Command = keyof typeof commands
export interface NuxtCommandMeta {
name: string;
usage: string;
description: string;
[key: string]: any;
}
export interface NuxtCommand {
invoke(args: Argv): Promise<void> | void
meta: NuxtCommandMeta
}
export function defineNuxtCommand (command: NuxtCommand): NuxtCommand {
return command
}

View File

@ -1,15 +1,17 @@
import { cyan } from 'colorette'
import { commands } from './index'
import { commands, defineNuxtCommand } from './index'
export function invoke (_args) {
const sections: string[] = []
export default defineNuxtCommand({
meta: {
name: 'help',
usage: 'nu help',
description: 'Show help'
},
invoke (_args) {
const sections: string[] = []
sections.push(`Usage: ${cyan(`nu ${Object.keys(commands).join('|')} [args]`)}`)
sections.push(`Usage: ${cyan(`nu ${Object.keys(commands).join('|')} [args]`)}`)
console.log(sections.join('\n\n') + '\n')
}
export const meta = {
usage: 'nu help',
description: 'Show help'
}
console.log(sections.join('\n\n') + '\n')
}
})

View File

@ -1,7 +1,7 @@
import 'v8-compile-cache'
import mri from 'mri'
import { red, cyan } from 'colorette'
import { commands } from './commands'
import { commands, Command, NuxtCommand } from './commands'
import { showHelp } from './utils/help'
import { showBanner } from './utils/banner'
import { error } from './utils/log'
@ -29,7 +29,7 @@ async function _main () {
}
try {
const cmd = await commands[command]()
const cmd = await commands[command as Command]().then(c => c.default || c) as NuxtCommand
if (args.h || args.help) {
showHelp(cmd.meta)
} else {
@ -40,7 +40,7 @@ async function _main () {
}
}
function onFatalError (err) {
function onFatalError (err: unknown) {
error(err)
process.exit(1)
}

View File

@ -1,6 +1,6 @@
import { normalize } from 'upath'
export function resolveModule (id, paths?) {
export function resolveModule (id: string, paths?: string) {
return normalize(require.resolve(id, {
paths: [].concat(
// @ts-ignore
@ -13,6 +13,6 @@ export function resolveModule (id, paths?) {
}))
}
export function requireModule (id, paths?) {
export function requireModule (id: string, paths?: string) {
return require(resolveModule(id, paths))
}

View File

@ -1,10 +1,11 @@
import type { RequestListener } from 'http'
import type { ListenOptions } from 'listhen'
import { loading } from '@nuxt/design'
export function createServer () {
const listener = createDynamicFunction(createLoadingHandler('Loading...'))
async function listen (opts) {
async function listen (opts: Partial<ListenOptions>) {
const { listen } = await import('listhen')
return listen(listener.call, opts)
}
@ -23,10 +24,10 @@ export function createLoadingHandler (message: string): RequestListener {
}
}
function createDynamicFunction<T extends (...args) => any>(initialValue: T) {
let fn: T = initialValue
function createDynamicFunction<T extends (...args: any[]) => any> (initialValue: T) {
let fn = initialValue
return {
set: (newFn: T) => { fn = newFn },
call: ((...args) => fn(...args)) as T
call: ((...args: Parameters<T>) => fn(...args)) as T
}
}