chore(nuxt3): add more types (#51)

Co-authored-by: Pooya Parsa <pyapar@gmail.com>
This commit is contained in:
Daniel Roe 2021-04-04 23:15:34 +01:00 committed by GitHub
parent 6c86b222a8
commit 2db79adfb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 123 additions and 48 deletions

View File

@ -24,6 +24,7 @@
"@rollup/plugin-node-resolve": "^11.2.1", "@rollup/plugin-node-resolve": "^11.2.1",
"@types/jest": "^26.0.22", "@types/jest": "^26.0.22",
"@types/node": "^14.14.37", "@types/node": "^14.14.37",
"@types/rimraf": "^3.0.0",
"chalk": "^4.1.0", "chalk": "^4.1.0",
"defu": "^3.2.2", "defu": "^3.2.2",
"esbuild": "^0.10.0", "esbuild": "^0.10.0",

View File

@ -36,6 +36,12 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"nuxt-cli": "^0.1.1", "nuxt-cli": "^0.1.1",
"scule": "^0.1.1", "scule": "^0.1.1",
"ufo": "^0.6.10" "ufo": "^0.6.10",
"upath": "^2.0.1"
},
"devDependencies": {
"@types/fs-extra": "^9.0.10",
"@types/hash-sum": "^1.0.0",
"@types/lodash": "^4.14.168"
} }
} }

View File

@ -34,7 +34,7 @@ export async function createApp (
pages: { pages: {
dir: 'pages' dir: 'pages'
} }
}) } as NuxtApp)
// Resolve app.main // Resolve app.main
const resolveOptions = { const resolveOptions = {

View File

@ -9,7 +9,7 @@ import {
scanTemplates, scanTemplates,
NuxtTemplate NuxtTemplate
} from './template' } from './template'
import { createWatcher } from './watch' import { createWatcher, WatchCallback } from './watch'
import { createApp, NuxtApp } from './app' import { createApp, NuxtApp } from './app'
import Ignore from './utils/ignore' import Ignore from './utils/ignore'
@ -20,7 +20,7 @@ export class Builder {
templates: NuxtTemplate[] templates: NuxtTemplate[]
app: NuxtApp app: NuxtApp
constructor (nuxt) { constructor (nuxt: Nuxt) {
this.nuxt = nuxt this.nuxt = nuxt
this.ignore = new Ignore({ this.ignore = new Ignore({
rootDir: nuxt.options.srcDir, rootDir: nuxt.options.srcDir,
@ -65,7 +65,7 @@ function watch (builder: Builder) {
// Watch user app // Watch user app
// TODO: handle multiples app dirs // TODO: handle multiples app dirs
const appPattern = `${builder.app.dir}/**/*.{${nuxt.options.extensions.join(',')}}` const appPattern = `${builder.app.dir}/**/*{${nuxt.options.extensions.join(',')}}`
const appWatcher = createWatcher(appPattern, { ...options, cwd: builder.app.dir }, ignore) const appWatcher = createWatcher(appPattern, { ...options, cwd: builder.app.dir }, ignore)
// appWatcher.debug('srcDir') // appWatcher.debug('srcDir')
const refreshTemplates = debounce(() => generate(builder), 100) const refreshTemplates = debounce(() => generate(builder), 100)
@ -77,7 +77,8 @@ function watch (builder: Builder) {
appWatcher.watch(/^plugins/, refreshTemplates, ['add', 'unlink']) appWatcher.watch(/^plugins/, refreshTemplates, ['add', 'unlink'])
// Shared Watcher // Shared Watcher
const watchHookDebounced = debounce((event, file) => builder.nuxt.callHook('builder:watch', event, file), 100) const watchHook: WatchCallback = (event, path) => builder.nuxt.callHook('builder:watch', event, path)
const watchHookDebounced = debounce(watchHook, 100)
appWatcher.watchAll(watchHookDebounced) appWatcher.watchAll(watchHookDebounced)
nuxtAppWatcher.watchAll(watchHookDebounced) nuxtAppWatcher.watchAll(watchHookDebounced)
} }

View File

@ -9,18 +9,18 @@ export interface NuxtPlugin {
} }
const MODES_REGEX = /\.(server|client)(\.\w+)*$/ const MODES_REGEX = /\.(server|client)(\.\w+)*$/
const getPluginMode = (src) => { const getPluginMode = (src: string) => {
const [, mode = 'all'] = src.match(MODES_REGEX) || [] const [, mode = 'all'] = src.match(MODES_REGEX) || []
return mode return mode as NuxtPlugin['mode']
} }
export function resolvePlugins (builder: Builder, app: NuxtApp) { export async function resolvePlugins (builder: Builder, app: NuxtApp) {
return resolveFiles(builder, 'plugins/**/*.{js,ts}', app.dir) const plugins = await resolveFiles(builder, 'plugins/**/*.{js,ts}', app.dir)
.then(plugins => plugins.map((src) => {
return { return plugins.map(src => ({
src, src,
mode: getPluginMode(src) mode: getPluginMode(src)
} })
})) )
} }

View File

@ -1,8 +1,10 @@
import { join, relative, dirname } from 'path'
import fsExtra from 'fs-extra' import fsExtra from 'fs-extra'
import globby from 'globby' import globby from 'globby'
import lodashTemplate from 'lodash/template' import lodashTemplate from 'lodash/template'
import { join, relative, dirname } from 'upath'
import * as nxt from './utils/nxt' import * as nxt from './utils/nxt'
import type { Builder } from './builder'
export interface NuxtTemplate { export interface NuxtTemplate {
src: string // Absolute path to source file src: string // Absolute path to source file
@ -10,7 +12,7 @@ export interface NuxtTemplate {
data?: any data?: any
} }
export function templateData (builder) { export function templateData (builder: Builder) {
return { return {
globals: builder.globals, globals: builder.globals,
app: builder.app, app: builder.app,
@ -21,7 +23,7 @@ export function templateData (builder) {
async function compileTemplate (tmpl: NuxtTemplate, destDir: string) { async function compileTemplate (tmpl: NuxtTemplate, destDir: string) {
const srcContents = await fsExtra.readFile(tmpl.src, 'utf-8') const srcContents = await fsExtra.readFile(tmpl.src, 'utf-8')
let compiledSrc let compiledSrc: string
try { try {
compiledSrc = lodashTemplate(srcContents, {})(tmpl.data) compiledSrc = lodashTemplate(srcContents, {})(tmpl.data)
} catch (err) { } catch (err) {
@ -38,7 +40,7 @@ export function compileTemplates (templates: NuxtTemplate[], destDir: string) {
return Promise.all(templates.map(t => compileTemplate(t, destDir))) return Promise.all(templates.map(t => compileTemplate(t, destDir)))
} }
export async function scanTemplates (dir: string, data?: Object) { export async function scanTemplates (dir: string, data?: Record<string, any>) {
const templateFiles = (await globby(join(dir, '/**'))) const templateFiles = (await globby(join(dir, '/**')))
return templateFiles.map(src => ({ return templateFiles.map(src => ({
@ -48,7 +50,7 @@ export async function scanTemplates (dir: string, data?: Object) {
})) }))
} }
export function watchTemplate (template: NuxtTemplate, _watcher: any, _cb: Function) { export function watchTemplate (template: NuxtTemplate, _watcher: any, _cb: () => any) {
template.data = new Proxy(template.data, { template.data = new Proxy(template.data, {
// TODO: deep watch option changes // TODO: deep watch option changes
}) })

View File

@ -42,27 +42,27 @@ export default class Ignore {
} }
readIgnoreFile () { readIgnoreFile () {
if (this.findIgnoreFile()) { if (this.findIgnoreFile() && this.ignoreFile) {
return fs.readFileSync(this.ignoreFile, 'utf8') return fs.readFileSync(this.ignoreFile, 'utf8')
} }
} }
addIgnoresRules () { addIgnoresRules () {
const content = this.readIgnoreFile() const content = this.readIgnoreFile()
if (!this.ignore) {
this.ignore = ignore(this.ignoreOptions)
}
if (content) { if (content) {
this.ignore.add(content) this.ignore.add(content)
} }
if (this.ignoreArray && this.ignoreArray.length > 0) { if (this.ignoreArray && this.ignoreArray.length > 0) {
if (!this.ignore) {
this.ignore = ignore(this.ignoreOptions)
}
this.ignore.add(this.ignoreArray) this.ignore.add(this.ignoreArray)
} }
} }
filter (paths: string[]) { filter (paths: string[] = []) {
if (this.ignore) { if (this.ignore) {
return this.ignore.filter([].concat(paths || [])) return this.ignore.filter(([] as string[]).concat(paths))
} }
return paths return paths
} }

View File

@ -20,7 +20,18 @@ export const importSources = (sources: string | string[], { lazy = false } = {})
}).join('\n') }).join('\n')
} }
export const serializeRoute = (route: NuxtRoute) => { interface SerializedRoute {
name?: string
path: string
children: SerializedRoute[]
/**
* @private
*/
__file: string
component: string
}
export const serializeRoute = (route: NuxtRoute): SerializedRoute => {
return { return {
name: route.name, name: route.name,
path: route.path, path: route.path,

View File

@ -1,37 +1,42 @@
import chokidar, { WatchOptions } from 'chokidar' import chokidar, { WatchOptions } from 'chokidar'
import defu from 'defu' import defu from 'defu'
import consola from 'consola' import consola from 'consola'
import Ignore from './utils/ignore' import Ignore from './utils/ignore'
export type WatchEvent = 'add' | 'addDir' | 'change' | 'unlink' | 'unlinkDir'
export type WatchCallback = (event: WatchEvent, path: string) => void
export type WatchFilter = (event: WatchEvent, path: string) => boolean | null
export function createWatcher ( export function createWatcher (
pattern: string, pattern: string,
options?: WatchOptions, options?: WatchOptions,
ignore?: Ignore ignore?: Ignore
) { ) {
const opts = defu(options, { const opts = defu(options!, {
ignored: [], ignored: [],
ignoreInitial: true ignoreInitial: true
}) })
const watcher = chokidar.watch(pattern, opts) const watcher = chokidar.watch(pattern, opts)
const watchAll = (cb: Function, filter?: Function) => { const watchAll = (cb: WatchCallback, filter?: WatchFilter) => {
watcher.on('all', (event, path: string) => { watcher.on('all', (event, path: string) => {
if (ignore && ignore.ignores(path)) { if (ignore && ignore.ignores(path)) {
return return
} }
const _event = { event, path } if (!filter || filter(event, path)) {
if (!filter || filter(_event)) { cb(event, path)
cb(_event)
} }
}) })
} }
const watch = (pattern: string | RegExp, cb: Function, events?: string[]) => const watch = (pattern: string | RegExp, cb: WatchCallback, events?: WatchEvent[]) =>
watchAll(cb, ({ event, path }) => path.match(pattern) && (!events || events.includes(event))) watchAll(cb, (event, path) => path.match(pattern) && (!events || events.includes(event)))
const debug = (tag: string = '[Watcher]') => { const debug = (tag: string = '[Watcher]') => {
consola.log(tag, 'Watching ', pattern) consola.log(tag, 'Watching ', pattern)
watchAll((e) => { watchAll((event, path) => {
consola.log(tag, e.event, e.path) consola.log(tag, event, path)
}) })
} }

View File

@ -44,7 +44,8 @@ export async function build (rootDir: string, stub: boolean) {
if (buildOptions.entries) { if (buildOptions.entries) {
if (!Array.isArray(buildOptions.entries)) { if (!Array.isArray(buildOptions.entries)) {
buildOptions.entries = Object.entries(buildOptions.entries) buildOptions.entries = Object.entries(buildOptions.entries)
} ctx.entries.push(...buildOptions.entries.map(entry => resolveEntry(entry))) }
ctx.entries.push(...buildOptions.entries.map(entry => resolveEntry(entry)))
} }
if (pkg.dependencies) { if (pkg.dependencies) {
ctx.externals.push(...Object.keys(pkg.dependencies)) ctx.externals.push(...Object.keys(pkg.dependencies))
@ -84,7 +85,7 @@ export async function build (rootDir: string, stub: boolean) {
return return
} }
consola.info(chalk.cyan(`Builduing ${pkg.name}`)) consola.info(chalk.cyan(`Building ${pkg.name}`))
if (process.env.DEBUG) { if (process.env.DEBUG) {
consola.info(` consola.info(`
${chalk.bold('Root dir:')} ${ctx.rootDir} ${chalk.bold('Root dir:')} ${ctx.rootDir}
@ -98,7 +99,7 @@ export async function build (rootDir: string, stub: boolean) {
const usedImports = new Set<string>() const usedImports = new Set<string>()
if (rollupOptions) { if (rollupOptions) {
const buildResult = await rollup(rollupOptions) const buildResult = await rollup(rollupOptions)
const outputOptions = rollupOptions.output as OutputOptions const outputOptions = rollupOptions.output
const { output } = await buildResult.write(outputOptions) const { output } = await buildResult.write(outputOptions)
for (const entry of output.filter(e => e.type === 'chunk') as OutputChunk[]) { for (const entry of output.filter(e => e.type === 'chunk') as OutputChunk[]) {
@ -115,6 +116,7 @@ export async function build (rootDir: string, stub: boolean) {
} }
// Types // Types
rollupOptions.plugins = rollupOptions.plugins || []
rollupOptions.plugins.push(dts()) rollupOptions.plugins.push(dts())
const typesBuild = await rollup(rollupOptions) const typesBuild = await rollup(rollupOptions)
await typesBuild.write(outputOptions) await typesBuild.write(outputOptions)
@ -179,32 +181,33 @@ function resolveEntry (input: string | [string, Partial<BuildEntry>] | Partial<B
let entry: Partial<BuildEntry> let entry: Partial<BuildEntry>
if (typeof input === 'string') { if (typeof input === 'string') {
entry = { name: input } entry = { name: input }
} } else if (Array.isArray(input)) {
if (Array.isArray(input)) {
entry = { name: input[0], ...input[1] } entry = { name: input[0], ...input[1] }
} else {
entry = input
} }
entry.input = entry.input ?? resolve(entry.srcDir || 'src', './' + entry.name) entry.input = entry.input ?? resolve(entry.srcDir || 'src', './' + entry.name)
entry.output = entry.output ?? resolve(entry.distDir || 'dist', './' + entry.name) entry.output = entry.output ?? resolve(entry.distDir || 'dist', './' + entry.name)
entry.bundle = entry.bundle ?? !(entry.input.endsWith('/') || entry.name.endsWith('/')) entry.bundle = entry.bundle ?? !(entry.input.endsWith('/') || entry.name?.endsWith('/'))
entry.format = entry.format ?? 'esm' entry.format = entry.format ?? 'esm'
return entry as BuildEntry return entry as BuildEntry
} }
function dumpObject (obj) { function dumpObject (obj: Record<string, any>) {
return '{ ' + Object.keys(obj).map(key => `${key}: ${JSON.stringify(obj[key])}`).join(', ') + ' }' return '{ ' + Object.keys(obj).map(key => `${key}: ${JSON.stringify(obj[key])}`).join(', ') + ' }'
} }
function getRollupOptions (ctx: BuildContext): RollupOptions | null { function getRollupOptions (ctx: BuildContext): RollupOptions & { output: OutputOptions & { dir: string }} | null {
const extensions = ['.ts', '.mjs', '.js', '.json'] const extensions = ['.ts', '.mjs', '.js', '.json']
const r = (...path) => resolve(ctx.rootDir, ...path) const r = (...path: string[]) => resolve(ctx.rootDir, ...path)
const entries = ctx.entries.filter(e => e.bundle) const entries = ctx.entries.filter(e => e.bundle)
if (!entries.length) { if (!entries.length) {
return null return null
} }
return <RollupOptions>{ return {
input: entries.map(e => e.input), input: entries.map(e => e.input),
output: { output: {
@ -227,7 +230,7 @@ function getRollupOptions (ctx: BuildContext): RollupOptions | null {
}, },
onwarn (warning, rollupWarn) { onwarn (warning, rollupWarn) {
if (!['CIRCULAR_DEPENDENCY'].includes(warning.code)) { if (!warning.code || !['CIRCULAR_DEPENDENCY'].includes(warning.code)) {
rollupWarn(warning) rollupWarn(warning)
} }
}, },

View File

@ -2333,6 +2333,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/glob@npm:*":
version: 7.1.3
resolution: "@types/glob@npm:7.1.3"
dependencies:
"@types/minimatch": "*"
"@types/node": "*"
checksum: 633bf1dda9a30899b233ed6b97c75cdd59f2ee856a12240c85474ce6889e26b3b3520b62de56f6bb61824af0ef51b311a0cae305f27ba0de8ddc4898a3673d42
languageName: node
linkType: hard
"@types/graceful-fs@npm:^4.1.2": "@types/graceful-fs@npm:^4.1.2":
version: 4.1.5 version: 4.1.5
resolution: "@types/graceful-fs@npm:4.1.5" resolution: "@types/graceful-fs@npm:4.1.5"
@ -2342,6 +2352,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/hash-sum@npm:^1.0.0":
version: 1.0.0
resolution: "@types/hash-sum@npm:1.0.0"
checksum: 258949e981df134cfc20a1ada051bc94fdc139249a30141459eace36cd336e0500d83e33bb418d9b3f852e8ea33b6b86512828358f5e21a376189b500cde8115
languageName: node
linkType: hard
"@types/http-proxy@npm:^1.17.5": "@types/http-proxy@npm:^1.17.5":
version: 1.17.5 version: 1.17.5
resolution: "@types/http-proxy@npm:1.17.5" resolution: "@types/http-proxy@npm:1.17.5"
@ -2400,6 +2417,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/lodash@npm:^4.14.168":
version: 4.14.168
resolution: "@types/lodash@npm:4.14.168"
checksum: 9a4e25f89fc035b9f0388f1f7be85e5eff49f9e6db0d93432c9a89fce0916f8a89db4e8290415f7ea02de6b00d3573826378dcb655b7b2d20530a6e8d6dd6fd0
languageName: node
linkType: hard
"@types/mime@npm:^1": "@types/mime@npm:^1":
version: 1.3.2 version: 1.3.2
resolution: "@types/mime@npm:1.3.2" resolution: "@types/mime@npm:1.3.2"
@ -2414,6 +2438,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/minimatch@npm:*":
version: 3.0.4
resolution: "@types/minimatch@npm:3.0.4"
checksum: abbe7031d8a6144c36f1803c5c1914885c2349d5d73fc45aae44807c12c4c803b8acfb134c71c7eff75c462c218697f982b96633f8fdf71b83ec50eba36122a6
languageName: node
linkType: hard
"@types/minimatch@npm:^3.0.3": "@types/minimatch@npm:^3.0.3":
version: 3.0.3 version: 3.0.3
resolution: "@types/minimatch@npm:3.0.3" resolution: "@types/minimatch@npm:3.0.3"
@ -2489,6 +2520,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/rimraf@npm:^3.0.0":
version: 3.0.0
resolution: "@types/rimraf@npm:3.0.0"
dependencies:
"@types/glob": "*"
"@types/node": "*"
checksum: 00a00a430f838ddafdbc17386f08d928b1ae7aeada84d112f4369a7a89b4d47c1bb6849688f1d6ee404a08338ab52a80c742f0c3040d63ccc2aaec04bd1009f5
languageName: node
linkType: hard
"@types/serve-static@npm:^1.13.9": "@types/serve-static@npm:^1.13.9":
version: 1.13.9 version: 1.13.9
resolution: "@types/serve-static@npm:1.13.9" resolution: "@types/serve-static@npm:1.13.9"
@ -10410,6 +10451,7 @@ __metadata:
"@rollup/plugin-node-resolve": ^11.2.1 "@rollup/plugin-node-resolve": ^11.2.1
"@types/jest": ^26.0.22 "@types/jest": ^26.0.22
"@types/node": ^14.14.37 "@types/node": ^14.14.37
"@types/rimraf": ^3.0.0
chalk: ^4.1.0 chalk: ^4.1.0
defu: ^3.2.2 defu: ^3.2.2
esbuild: ^0.10.0 esbuild: ^0.10.0
@ -10439,6 +10481,9 @@ __metadata:
"@nuxt/nitro": ^0.2.2 "@nuxt/nitro": ^0.2.2
"@nuxt/vite-builder": ^0.1.1 "@nuxt/vite-builder": ^0.1.1
"@nuxt/webpack-builder": ^0.1.1 "@nuxt/webpack-builder": ^0.1.1
"@types/fs-extra": ^9.0.10
"@types/hash-sum": ^1.0.0
"@types/lodash": ^4.14.168
chokidar: ^3.5.1 chokidar: ^3.5.1
consola: ^2.15.3 consola: ^2.15.3
defu: ^3.2.2 defu: ^3.2.2
@ -10451,6 +10496,7 @@ __metadata:
nuxt-cli: ^0.1.1 nuxt-cli: ^0.1.1
scule: ^0.1.1 scule: ^0.1.1
ufo: ^0.6.10 ufo: ^0.6.10
upath: ^2.0.1
languageName: unknown languageName: unknown
linkType: soft linkType: soft