velocity.ui 间歇性失败并出现错误 "Velocity UI Pack: velocity must be loaded first."

velocity.ui intermittently fails with the error "Velocity UI Pack: velocity must be loaded first."

当我加载 velocity.ui 时,控制台出现间歇性错误:

Velocity UI Pack: Velocity must be loaded first. Aborting.

和 none 个 velocity.ui 的动画可用。

我可以用这样简单的方法重现问题:

<script>
require.config({
  baseUrl: "/static/lib/",
  paths: {
    jquery: "external/jquery",
    velocity: "external/velocity/velocity.min",
    "velocity.ui": "external/velocity/velocity.ui.min",
  }
});

require(["jquery", "velocity.ui"]);
</script>

当我查看网络请求时,我看到 velocity velocity.ui 之前加载了 velocity.ui 确实有 define(["velocity"], ....

解决方案

如果您的项目完全使用 jQuery ,出于任何原因, 那么您必须使 velocity 依赖于 jquery 模块。否则,您将 运行 陷入您 运行 的问题。创建一个名为 velocity-glue:

的模块
define(['velocity', 'jquery'], function (velocity) {
  return velocity;
});

修改您的配置,使其包含这两个条目。

map: {
  "*": {
    velocity: "velocity-glue",
  },
  "velocity-glue": {
    velocity: "velocity",
  },
}

第一个条目使得 velocity-glue 在需要 velocity 时被使用。第二个条目确保 velocity-glue 可以得到原始的 velocity.

说明

我将使用 "Velocity" 在全球范围内引用该产品:这包括两个模块(velocityvelocity-ui)。

问题是 Velocity 不是 AMD 的好公民。通过这个,我的意思是它的模块依赖于全局变量并将自己导出为全局变量,即使它们是通过 AMD 加载器加载的,这对 AMD 模块来说是不好的行为。

Velocity 可以在有或没有 jQuery 的情况下使用。 当 Velocity 在没有 jQuery 的情况下使用时,它使用一种最小的 polyfill,它只提供作为jQuery 的大部分功能都符合 Velocity 的需要。由于 Velocity 可以在有或没有 jQuery 的情况下使用,它的模块在调用 define 时不会 而不是 在它们的依赖项中列出 jQuery,否则,它们会要求您使用 jQuery.

无论 Velocity 是否作为 AMD 模块加载,它都会自行安装,以便可以作为其中之一的 Velocity 属性 进行访问(如果它们存在):window.jQuery window.Zepto,或 window。 Velocity 将按照此处给出的顺序使用它可以使用的第一个。因此,如果既没有安装 jQuery 也没有安装 Zepto,它将以 window.Velocity 的形式访问。但是如果安装了 jQuery,它将可以作为 window.jQuery.Velocity 访问。问题是 velocityvelocity.ui 都在 3 个可能的位置 独立地 之间执行计算选择。让我们考虑一些场景:

场景A:

  1. jquery 加载。
  2. velocity 安装为 window.jQuery.Velocity
  3. velocity.ui 寻找 window.jQuery.Velocity。很好

场景 B:

[jquery 尚未加载。]

  1. velocity 安装为 window.Velocity
  2. velocity.ui 寻找 window.Velocity。很好

jquery 以后可能加载也可能不加载。没关系。)

场景 C:

  1. velocity 将自身安装为 window.Velocity,因为 jQuery 未加载。
  2. jquery 加载。
  3. velocity.ui 寻找 window.jQuery.Velocity 因为 window.jQuery 确实存在,但 window.jQuery.Velocity 不存在! 您遇到错误

请注意,在上面的场景中,velocity 总是 velocity.ui 之前加载,因为 velocity.uivelocity 列为其依赖项.但是, jQuery 相对于其他两个模块的加载顺序不受限制,因为(如前所述)它们不依赖于 jquery.

我在此答案的第一部分中给出的解决方案通过限制加载顺序解决了这个问题:jquery 将始终在两个模块之前加载。