mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 23:22:02 +00:00
feat(cli): add prepare
command to stub module types (#370)
Co-authored-by: Pooya Parsa <pyapar@gmail.com>
This commit is contained in:
parent
8c09d05ad2
commit
57a2974450
@ -3,6 +3,7 @@ import type { Argv } from 'mri'
|
|||||||
export const commands = {
|
export const commands = {
|
||||||
dev: () => import('./dev'),
|
dev: () => import('./dev'),
|
||||||
build: () => import('./build'),
|
build: () => import('./build'),
|
||||||
|
prepare: () => import('./prepare'),
|
||||||
usage: () => import('./usage')
|
usage: () => import('./usage')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
57
packages/cli/src/commands/prepare.ts
Normal file
57
packages/cli/src/commands/prepare.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { promises as fsp } from 'fs'
|
||||||
|
import { relative, resolve } from 'upath'
|
||||||
|
import { cyan } from 'colorette'
|
||||||
|
|
||||||
|
import { requireModule, getModulePaths, getNearestPackage } from '../utils/cjs'
|
||||||
|
import { exists } from '../utils/fs'
|
||||||
|
import { success } from '../utils/log'
|
||||||
|
import { defineNuxtCommand } from './index'
|
||||||
|
|
||||||
|
export default defineNuxtCommand({
|
||||||
|
meta: {
|
||||||
|
name: 'prepare',
|
||||||
|
usage: 'nu prepare',
|
||||||
|
description: 'Prepare nuxt for development/build'
|
||||||
|
},
|
||||||
|
async invoke (args) {
|
||||||
|
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
|
||||||
|
const rootDir = resolve(args._[0] || '.')
|
||||||
|
|
||||||
|
const { loadNuxt } = requireModule('@nuxt/kit', rootDir) as typeof import('@nuxt/kit')
|
||||||
|
const nuxt = await loadNuxt({ rootDir })
|
||||||
|
|
||||||
|
const adHocModules = nuxt.options._majorVersion === 3
|
||||||
|
? ['@nuxt/kit', '@nuxt/app', '@nuxt/nitro']
|
||||||
|
: ['@nuxt/kit']
|
||||||
|
|
||||||
|
const types = [
|
||||||
|
...adHocModules,
|
||||||
|
// Modules
|
||||||
|
...nuxt.options.buildModules,
|
||||||
|
...nuxt.options.modules,
|
||||||
|
...nuxt.options._modules
|
||||||
|
].filter(f => typeof f === 'string')
|
||||||
|
|
||||||
|
const modulePaths = getModulePaths(nuxt.options.modulesDir)
|
||||||
|
const _references = await Promise.all(types.map(async (id) => {
|
||||||
|
const pkg = getNearestPackage(id, modulePaths)
|
||||||
|
return pkg ? `/// <reference types="${pkg.name}" />` : await exists(id) && `/// <reference path="${id}" />`
|
||||||
|
})).then(arr => arr.filter(Boolean))
|
||||||
|
|
||||||
|
const references = Array.from(new Set(_references)) as string[]
|
||||||
|
await nuxt.callHook('prepare:types', { references })
|
||||||
|
|
||||||
|
const declarationPath = resolve(`${rootDir}/nuxt.d.ts`)
|
||||||
|
|
||||||
|
const declaration = [
|
||||||
|
'// Declarations auto generated by `nuxt prepare`. Please do not manually modify this file.',
|
||||||
|
'',
|
||||||
|
...references,
|
||||||
|
''
|
||||||
|
].join('\n')
|
||||||
|
|
||||||
|
await fsp.writeFile(declarationPath, declaration)
|
||||||
|
|
||||||
|
success('Generated', cyan(relative(process.cwd(), declarationPath)))
|
||||||
|
}
|
||||||
|
})
|
@ -1,18 +1,34 @@
|
|||||||
import { normalize } from 'upath'
|
import { normalize, dirname } from 'upath'
|
||||||
|
|
||||||
export function resolveModule (id: string, paths?: string) {
|
export function getModulePaths (paths?: string | string[]): string[] {
|
||||||
return normalize(require.resolve(id, {
|
return [].concat(
|
||||||
paths: [].concat(
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.__NUXT_PREPATHS__,
|
global.__NUXT_PREPATHS__,
|
||||||
paths,
|
...(Array.isArray(paths) ? paths : [paths]),
|
||||||
process.cwd(),
|
process.cwd(),
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.__NUXT_PATHS__
|
global.__NUXT_PATHS__
|
||||||
).filter(Boolean)
|
).filter(Boolean)
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requireModule (id: string, paths?: string) {
|
export function resolveModule (id: string, paths?: string | string[]) {
|
||||||
|
return normalize(require.resolve(id, { paths: getModulePaths(paths) }))
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tryResolveModule (id: string, paths?: string | string[]) {
|
||||||
|
try {
|
||||||
|
return resolveModule(id, paths)
|
||||||
|
} catch { return null }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function requireModule (id: string, paths?: string | string[]) {
|
||||||
return require(resolveModule(id, paths))
|
return require(resolveModule(id, paths))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getNearestPackage (id: string, paths?: string | string[]) {
|
||||||
|
while (dirname(id) !== id) {
|
||||||
|
try { return requireModule(id + '/package.json', paths) } catch { }
|
||||||
|
id = dirname(id)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
11
packages/cli/src/utils/fs.ts
Normal file
11
packages/cli/src/utils/fs.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { promises as fsp } from 'fs'
|
||||||
|
|
||||||
|
// Check if a file exists
|
||||||
|
export async function exists (path: string) {
|
||||||
|
try {
|
||||||
|
await fsp.access(path)
|
||||||
|
return true
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import { red, yellow, cyan } from 'colorette'
|
import { green, red, yellow, cyan } from 'colorette'
|
||||||
|
|
||||||
export const error = (...args) => console.error(red('[error]'), ...args)
|
export const error = (...args: any[]) => console.error(red('[error]'), ...args)
|
||||||
export const warn = (...args) => console.warn(yellow('[warn]'), ...args)
|
export const warn = (...args: any[]) => console.warn(yellow('[warn]'), ...args)
|
||||||
export const info = (...args) => console.info(cyan('[info]'), ...args)
|
export const info = (...args: any[]) => console.info(cyan('[info]'), ...args)
|
||||||
|
export const success = (...args: any[]) => console.log(green('[success]'), ...args)
|
||||||
|
@ -66,6 +66,9 @@ export interface NuxtHooks {
|
|||||||
'config': (options: NuxtConfig) => HookResult
|
'config': (options: NuxtConfig) => HookResult
|
||||||
'run:before': (options: { argv: string[], cmd: { name: string, usage: string, description: string, options: Record<string, any> }, rootDir: string }) => HookResult
|
'run:before': (options: { argv: string[], cmd: { name: string, usage: string, description: string, options: Record<string, any> }, rootDir: string }) => HookResult
|
||||||
|
|
||||||
|
// nuxt-cli
|
||||||
|
'prepare:types': (options: { references: string[] }) => HookResult
|
||||||
|
|
||||||
// @nuxt/core
|
// @nuxt/core
|
||||||
'ready': (nuxt: Nuxt) => HookResult
|
'ready': (nuxt: Nuxt) => HookResult
|
||||||
'close': (nuxt: Nuxt) => HookResult
|
'close': (nuxt: Nuxt) => HookResult
|
||||||
|
7
playground/nuxt.d.ts
vendored
Normal file
7
playground/nuxt.d.ts
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Declarations auto generated by `nuxt prepare`. Please do not manually modify this file.
|
||||||
|
|
||||||
|
/// <reference types="@nuxt/kit" />
|
||||||
|
/// <reference types="@nuxt/nitro" />
|
||||||
|
/// <reference types="@nuxt/pages" />
|
||||||
|
/// <reference types="@nuxt/meta" />
|
||||||
|
/// <reference types="@nuxt/component-discovery" />
|
Loading…
Reference in New Issue
Block a user