watch 模式
在mainTask
执行过程中,根据options
来判断是否添加watcher
,此处使用chokidar
实现监听模式。
const startWatcher = async () => {
if (!options.watch) return
const { watch } = await import('chokidar')
const customIgnores = options.ignoreWatch
? Array.isArray(options.ignoreWatch)
? options.ignoreWatch
: [options.ignoreWatch]
: []
const ignored = [
'**/{.git,node_modules}/**',
options.outDir,
...customIgnores,
]
const watchPaths =
typeof options.watch === 'boolean'
? '.'
: Array.isArray(options.watch)
? options.watch.filter((path): path is string => typeof path === 'string')
: options.watch
const watcher = watch(watchPaths, {
ignoreInitial: true,
ignorePermissionErrors: true,
ignored,
})
watcher.on('all', async (type, file) => {
file = slash(file)
if (options.publicDir && isInPublicDir(options.publicDir, file)) {
logger.info('CLI', `Change in public dir: ${file}`)
copyPublicDir(options.publicDir, options.outDir)
return
}
// By default we only rebuild when imported files change
// If you specify custom `watch`, a string or multiple strings
// We rebuild when those files change
let shouldSkipChange = false
if (options.watch === true) {
if (file === 'package.json' && !buildDependencies.has(file)) {
const currentHash = await getAllDepsHash(process.cwd())
shouldSkipChange = currentHash === depsHash
depsHash = currentHash
} else if (!buildDependencies.has(file)) {
shouldSkipChange = true
}
}
if (shouldSkipChange) {
return
}
debouncedBuildAll()
})
}