我正在用TS构建一个库。这个库使用ssh2
库作为依赖项。
我正在尝试创建一个函数,它可以接受ssh2
配置对象或已经存在的Client
示例来执行命令(这是一个简化的情况):
import { Client, ConnectConfig } from 'ssh2';
export function runCommand(params: Client | ConnectConfig) {
if(params instanceof Client) {
// do something
} else {
// create our own client
// do something
}
}
当我构建这个库并像这样调用函数时:
const { readFileSync } = require("fs");
const { Client } = require("ssh2");
const { runCommand } = require("myLib");
const conn = new Client();
conn
.on("ready", () => {
console.log("Client :: ready");
runCommand(conn);
})
.connect({
host: "example.com",
port: 22,
username: "me",
privateKey: readFileSync(process.env.HOME + "/.ssh/id_ed25519"),
});
由于某种原因,我的函数中的instanceof
检查将返回false
。这里到底发生了什么?是TS编译问题还是Node.js将来自我的lib依赖项和消费者代码依赖项的Client
视为两个不同的类?
编译后的代码看起来像这样:
const ssh2_1 = require("ssh2");
//...
function runCommand(params) {
if (params instanceof ssh2_1.Client) {
// do something
}
else {
// create our own client
// do something
}
}
1条答案
按热度按时间56lgkhnf1#
从
instanceof
操作符的行为中可能不明显的是,类必须在父链中 * 完全 *,在JavaScript对象 * 引用 * 的意义上。因此,如果您导入
Client
类两次,它们是不同的实际对象引用,并且instanceof
可能会给予“假”否定。这很有可能是这里发生的事情:
ssh2
与你的库捆绑在一起,因此它会导入自己的依赖项副本。而你的应用会自己导入ssh2
,这会导致一个 * 单独 * 的副本。你有几个选择:
externals
),让应用安装一个您的库和应用都将导入的 * 单一 * 版本;指定peerDependencies
的典型情况instanceof
运算符;相反,使用一些启发式方法来确定对象是否具有您需要的形状;通常检查某些属性及其类型Client
类),并在应用中使用该依赖项(const { Client, runCommand } = require("myLib");
),以便它是完全相同的副本(既然它已经捆绑,为什么不重新使用它而不是重新捆绑它呢?)