如何在运行时发现和加载 js 文件

How to discover and load js files at runtime?

本文关键字:加载 js 文件 发现 运行时      更新时间:2023-09-26

我正在编写一个基于节点.js的服务器,用于管理一系列设备。基于节点.js的服务器告诉连接的客户端其功能。这些能力由单独的 js 文件定义,这些文件定义通过 util.inherits() 使用继承的对象。

遇到的问题是,现在,我必须为新功能定义一个新的 js,然后更新主 js 程序以require新的 js,更改代码以发布该功能可用,然后在客户端请求时利用新功能。

我想使主代码更通用,从而可以

  1. 检测新能力,
  2. 自动包含它们,
  3. 通知客户,以及
  4. 利用代码。

我可以通过支持树浏览的各种 npm 模块进行检测,我可以为所有功能指定一个子目录并发现那里的文件。我认为我可以在步骤 2 中使用 require(尽管不是 100% 确定),但是我不知道如何执行步骤 3 和 4,或者将步骤 2 的结果与步骤 3 和 4 一起使用。

我会重视关于如何解决这个问题的任何反馈。


澄清我的问题。现在我的逻辑如下:

var logicA = requires('./capabilities/a.js');
var logicB = requires('./capabilities/b.js');
var logicC = requires('./capabilities/c.js');
var Comms.CAPABILITY_A = 'a';
var Comms.CAPABILITY_B = 'b';
var Comms.CAPABILITY_C = 'c';
var Comms.MSG_CAPABILITY = 0;
var Comms.MSG_DO_LOGIC = 1;
function onMessageReceived(comms, msgId, body) {
    switch (msgId) {
        case(MSG_DO_LOGIC):
           doLogic(body);
           break;
        ...
    }
}
function doLogic(flag) {
   switch(flag) {
      case(Comms.CAPABILITY_A):
          logicA.doLogic();
          break;
      case(Comms.CAPABILITY_B):
          logicB.doLogic();
          break;
      case(Comms.CAPABILITY_C):
          logicC.doLogic();
          break;
   }
}

在客户端,我有硬编码的逻辑,假定什么是可用的。我可以通过让服务器向客户端发送功能数组来删除它,然后客户端可以选择数组的一个元素并将其作为执行逻辑的请求传递回去。这不是我的问题。

我的问题是了解如何使主机程序动态加载所有逻辑,然后评估在动态加载的逻辑上执行哪个逻辑。

应该声明,当我说动态时,我的意思是可用的代码是在运行时确定的。但是,仅在首次启动服务器时执行评估。

我通过创建一个寄存器解决了这个问题.js其中保存了所有协议。每次创建新协议时,我都会将其添加到寄存器中。

通过寄存器,我可以获取所有已注册协议的数组。我可以将它们传回客户端,客户端可以选择协议,我可以通过寄存器类请求协议的实例。

虽然有一些硬编码,但它仅限于与协议位于同一目录中的寄存器类。

因此,在寄存器中,我具有以下功能:

getList()
getText()
validateProtocolId()
getProtocol()

我使用 getList() 返回已注册的协议 ID 数组。我使用 getText() 来提供人类可读的支持协议列表。我使用 validateProtocolId() 来验证从客户端返回的 id,以确认该 id 表示已注册的协议,然后使用 getProtocol() 生成已注册协议的实例。

从本质上讲,getProtocol()只是适当地做一个require('./<protocol file>.js')

它不像自动发现那样优雅,但它允许对注册的内容进行更严格的控制,而无需强制自定义文件等。