Skip to content

Commit

Permalink
feat(hmr): support base and multiple roots, fix #990
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Mar 13, 2023
1 parent 42a8008 commit e68c610
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 18 deletions.
9 changes: 5 additions & 4 deletions packages/koishi/src/cli/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,11 @@ function createWorker(options: Dict<any>) {
})
}

function setEnvArg(name: string, value: string | boolean) {
function setEnvArg(name: string, value: string | boolean, toJson = false) {
if (value === true) {
process.env[name] = ''
process.env[name] = toJson ? '""' : ''
} else if (value) {
process.env[name] = value
process.env[name] = toJson ? JSON.stringify(value) : value
}
}

Expand All @@ -114,7 +114,8 @@ export default function (cli: CAC) {
console.warn(`${kleur.red('error')} log level should be a positive integer.`)
process.exit(1)
}
setEnvArg('KOISHI_WATCH_ROOT', watch)
setEnvArg('KOISHI_WATCH_ROOT', watch) // for backward compatibility
setEnvArg('KOISHI_WATCH', watch, true)
setEnvArg('KOISHI_LOG_TIME', logTime)
process.env.KOISHI_LOG_LEVEL = logLevel || ''
process.env.KOISHI_DEBUG = debug || ''
Expand Down
40 changes: 26 additions & 14 deletions plugins/hmr/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ interface Reload {
const logger = new Logger('watch')

class Watcher {
private root: string
private base: string
private watcher: FSWatcher

/**
Expand Down Expand Up @@ -65,17 +65,23 @@ class Watcher {
private stashed = new Set<string>()

constructor(private ctx: Context, private config: Watcher.Config) {
this.base = resolve(ctx.loader.baseDir, config.base || '')
ctx.root.watcher = this
ctx.on('ready', () => this.start())
ctx.on('dispose', () => this.stop())
}

relative(filename: string) {
if (!this.base) return filename
return relative(this.base, filename)
}

start() {
const { loader } = this.ctx
const { root = '', ignored = [] } = this.config
this.root = resolve(loader.baseDir, root)
this.watcher = watch(this.root, {
const { root, ignored } = this.config
this.watcher = watch(root, {
...this.config,
cwd: this.base,
ignored: ['**/node_modules/**', '**/.git/**', '**/logs/**', ...makeArray(ignored)],
})

Expand All @@ -84,27 +90,28 @@ class Watcher {
const triggerLocalReload = debounce(this.config.debounce, () => this.triggerLocalReload())

this.watcher.on('change', async (path) => {
const isEntry = path === loader.filename || loader.envFiles.includes(path)
const filename = resolve(this.base, path)
const isEntry = filename === loader.filename || loader.envFiles.includes(filename)
if (loader.suspend && isEntry) {
loader.suspend = false
return
}

logger.debug('change detected:', relative(this.root, path))
logger.debug('change detected:', path)

if (isEntry) {
if (require.cache[path]) {
if (require.cache[filename]) {
this.ctx.loader.fullReload()
} else {
const config = await loader.readConfig()
this.ctx.root.state.update(config)
this.ctx.emit('config')
}
} else {
if (this.externals.has(path)) {
if (this.externals.has(filename)) {
this.ctx.loader.fullReload()
} else if (require.cache[path]) {
this.stashed.add(path)
} else if (require.cache[filename]) {
this.stashed.add(filename)
triggerLocalReload()
}
}
Expand Down Expand Up @@ -259,7 +266,7 @@ class Watcher {

try {
for (const [runtime, { filename, children }] of reloads) {
const path = relative(this.root, filename)
const path = this.relative(filename)

try {
this.ctx.registry.delete(runtime.plugin)
Expand Down Expand Up @@ -304,19 +311,24 @@ namespace Watcher {
export const using = ['loader']

export interface Config extends WatchOptions {
root?: string
base?: string
root?: string[]
debounce?: number
ignored?: string[]
}

export const Config: Schema<Config> = Schema.object({
root: Schema.string().required().description('要监听的根目录,相对于当前工作路径。'),
base: Schema.string().description('用户显示路径的根目录,默认为当前工作路径。'),
root: Schema.union([
Schema.array(String),
Schema.transform(String, (value) => [value]),
]).description('要监听的文件或目录列表,相对于 `base` 路径。'),
debounce: Schema.natural().role('ms').default(100).description('延迟触发更新的等待时间。'),
ignored: Schema.union([
Schema.array(String),
Schema.transform(String, (value) => [value]),
]).description('要忽略的文件或目录。'),
}).description('热重载设置')
})
}

export default Watcher

0 comments on commit e68c610

Please sign in to comment.