更新单个 CommonJS 模块,而不必触及它所需要的每个模块

Update a single CommonJS module without having to touch every single module it is required in

这可能有点复杂,但我会尽力而为。我有一系列与 Browserify 一起使用的 API 模块,其中一些模块也调用其他模块。它们几乎交织在一起,这将使更新变得困难。

例如,假设我有五个模块:A、B、C、D 和 E。B 和 C 需要 A,C、D 和 E 需要 B。如果我需要对 A 进行一些破坏性更改的更新,我可以对其进行版本控制,但随后我需要更新 B 和 C 中的 require 语句。并且由于 B 现在使用不同版本的 A,我也需要版本 B,这意味着更改 C、D 和 E 中的 require 语句。因此,一个模块中的单个更改意味着我必须还原其他所有内容。

我应该注意到,这样做的主要原因是我必须保留旧版本。这些是小型微型网站,一个网站可能使用 A - E 构建,下一个可能使用 A' - E' 构建,但我仍然需要能够独立构建这两个网站。尽管对 A' 的更改可能不会对其公开的 API 产生影响,但我不想返回并重新测试使用每个文件修改构建的每个项目。

我想过有一个单独的每个项目文件可能需要,然后它需要该项目的所有版本化模块,但这是循环依赖。

如果重要的话,我正在使用 Gulp 和 Browserify 构建最终的 JS 文件。

我找到了可以解决问题的方法:aliasify

我将我的 require 语句更改为 require('Api/ModuleA') 然后在别名配置中我将 Api/ModuleA 映射到 ./libs/Api/ModuleA-1.0 并且它每次需要模块 A 时都会选择我想要的版本。

我使用了类似于 Java 类路径的机制。我创建了一个自定义模块解析器,并为单独的项目使用了单独的模块根。还有一个用于存放常用文件的文件夹。模块解析器首先在项目文件夹中搜索模块,如果没有找到,则在公共文件夹中搜索它。通过这种方式,您可以为特定项目提供模块 A 的专门实现。不确定它是否适合您的情况。它类似于别名,不同之处在于配置由文件系统文件夹而不是配置文件支持。

A是一个只有少数依赖的模块,被很多模块引用。他们通常称这种模块为"mature"。这些成熟的模块应该经过良好的测试,并且 public 接口不应该经常更改,因为每个依赖的模块都需要更新。因此,您可能会尝试在不破坏 api 的情况下进行更改,可能会创建一个具有版本化名称的新模块,以及使用新模块提供旧 api 的模块包装器。新组件可以使用新模块,旧组件不受影响

出于某种原因,他们使用多个数字来对软件进行版本控制。在最简单的情况下,有两个数字:主要版本和次要版本。每次发布都会更改次要版本,主要版本会在 public api 更改时增加。所有依赖于此组件的组件只需要在主要版本更改时更新。 (当然,有时在次要版本的实现中会出现错误,这些错误会破坏某些依赖的组件,但这不是通常的情况)。如果您更改 A 的 public api,您也需要更改 BC,但其他的不需要。A 会有一个主要的版本变化,B 和 C 会有一个次要的。其余保持不变。这需要一个更复杂的模块解析器,它可以根据主要版本解析最新的模块。但这就是 npm 所做的。