【问题标题】:Use AMD defined module within 3rd party, non-AMD library在第三方非 AMD 库中使用 AMD 定义的模块
【发布时间】:2015-01-25 01:39:21
【问题描述】:

我有一个库 - 称之为 SomeLib - 它被定义为支持各种模块加载器:

(function(global, factory) {
    if (typeof define === 'function' && define.amd) {
        define([], factory);
    } else if (typeof module !== 'undefined' && module.exports) {
        module.exports = factory();
    } else {
        global.UriTemplate = factory();
    }
})(this, function() {
   ...
   // returns constructor function
});

我可以很容易地用 RequireJS 加载它

require.config({
  paths: {
    'theLibrary: '../path/to/the/lib'
  }
});

然后我有另一个 3rd-party 库 - 称之为 AnotherLib - 它在内部使用 SomeLib 之类的

var the Lib = new SomeLib(...);

这意味着SomeLib 必须在全球范围内可用。

AnotherLib 只是一个普通的 JavaScript 模块函数

(function(){
  // the code
})();

它不符合特定的模块加载器。

当我在 RequireJS 中包含 AnotherLib 时,我会做类似的事情

require.config({
  paths: {
    'theLibrary: '../path/to/the/lib',
    'anotherLib: '../path/to/anotherLib'
  },
  shim: {
     'anotherLib: [
        'theLibrary'
     ]
  }
});

问题是我在 AnotherLib 中实例化 SomeLib (new SomeLib(...)) 的行上遇到了一个未定义的异常。 这是因为 SomeLib 没有在全局对象上定义,而是作为一个 AMD 模块发布,而 AnotherLib 并不“需要”。

我能否以某种方式解决这个问题,或者 AnotherLib 是否必须符合 AMD 标准并且正确地需要 SomeLib。

【问题讨论】:

    标签: javascript requirejs


    【解决方案1】:

    最好的办法是获得与 AMD 兼容的库或使库与 AMD 兼容。后一种选择将需要手动修改源代码或具有将非 AMD 兼容代码转换为真正的 AMD 模块的构建步骤。如何做到这一点取决于库的设计方式。

    一种适用于任何库的方法是故意将库所需的符号泄漏到全局空间中:

    1. 使anotherLib 依赖于一个新模块,您可以调用它SomeLib-leak

    2. 创建新模块。此定义不必位于单独的文件中。我通常在致电require.config 之前放置这样的“胶水”模块。模块是这样的:

      define('SomeLib-leak', ['SomeLib'], function (SomeLib) {
          window.SomeLib = SomeLib;
      });
      

      我确实故意让define 在此处设置模块名称。通常,您不想调用 define 设置模块名称,但是对于像我上面指出的那样放置的“胶水”模块,这是必要的。

    anotherLib 被加载时,SomeLibrary 将在全局空间中。

    【讨论】:

    • 我也是这么想的……目前正在和JS库的作者讨论(1)。 (2) 可能是一种解决方法,尽管不是很好。非常感谢
    猜你喜欢
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    相关资源
    最近更新 更多