From b723a3d6b4f2717c00038ff4d4c301756f5b71ef Mon Sep 17 00:00:00 2001 From: Shigma <1700011071@pku.edu.cn> Date: Sat, 15 Jan 2022 21:50:12 +0800 Subject: [PATCH] fix(manager): package provider should not affect dep tree --- packages/cli/src/addons/watcher.ts | 2 +- plugins/frontend/manager/src/packages.ts | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/addons/watcher.ts b/packages/cli/src/addons/watcher.ts index d62dfc40f2..67490b3125 100644 --- a/packages/cli/src/addons/watcher.ts +++ b/packages/cli/src/addons/watcher.ts @@ -18,7 +18,7 @@ function loadDependencies(filename: string, ignored: Set) { return dependencies } -const logger = new Logger('app:watcher') +const logger = new Logger('watch') export default class FileWatcher extends Service { private root: string diff --git a/plugins/frontend/manager/src/packages.ts b/plugins/frontend/manager/src/packages.ts index d0a8580cf8..08d869b323 100644 --- a/plugins/frontend/manager/src/packages.ts +++ b/plugins/frontend/manager/src/packages.ts @@ -1,4 +1,4 @@ -import { Adapter, App, Context, Dict, omit, pick, Plugin, Schema } from 'koishi' +import { Adapter, App, Context, Dict, omit, pick, Plugin, remove, Schema } from 'koishi' import { DataSource } from '@koishijs/plugin-console' import { promises as fsp } from 'fs' import { dirname } from 'path' @@ -11,6 +11,19 @@ function unwrap(module: any) { return module.default || module } +/** require without affecting the dependency tree */ +function getExports(id: string) { + const path = require.resolve(id) + let result = require.cache[path] + if (!result) { + require(path) + result = require.cache[path] + remove(module.children, result) + delete require.cache[path] + } + return unwrap(result.exports) +} + export class PackageProvider extends DataSource> { cache: Dict> = {} task: Promise @@ -101,12 +114,12 @@ export class PackageProvider extends DataSource> { const result = pick(data, ['name', 'version', 'description']) as PackageProvider.Data // workspace packages are followed by symlinks - result.workspace = !require.resolve(path).includes('node_modules') + result.workspace = !require.resolve(name).includes('node_modules') result.shortname = data.name.replace(/(koishi-|^@koishijs\/)plugin-/, '') // check adapter const oldLength = Object.keys(Adapter.library).length - const exports = unwrap(require(name)) + const exports = getExports(name) const newLength = Object.keys(Adapter.library).length if (newLength > oldLength) this.ctx.console.services.protocols.broadcast()