【问题标题】:Update a single CommonJS module without having to touch every single module it is required in更新单个 CommonJS 模块,而无需触及它所需的每个模块
【发布时间】:2016-10-22 08:53:46
【问题描述】:

这可能有点复杂,但我会尽力而为。我有一系列与 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 文件。

【问题讨论】:

    标签: javascript gulp browserify commonjs


    【解决方案1】:

    我发现了一些可以解决问题的方法:aliasify

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 我考虑过使用回退,但不同的版本不一定会弃用旧版本。同样的原因,它并不总是 API 更改。例如,Logger 可能需要为某些项目添加额外的日志记录源,或者 Data 模块可能需要以不同的方式组织。外部 API 没有改变,在版本控制的意义上说不是“更新”或“更好”,只是不同。
      • 我认为日志模块不应该依赖于它的来源或它的目标。它可以提供一个可配置的接口,应用程序的主入口(每个项目都不同)可以提供日志源或目标的列表。
      猜你喜欢
      • 2012-07-09
      • 1970-01-01
      • 2014-05-30
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 1970-01-01
      • 2017-12-11
      • 2014-12-25
      相关资源
      最近更新 更多