【问题标题】:How let users to access requirejs modules outside main?如何让用户访问 main 之外的 requirejs 模块?
【发布时间】:2014-03-07 01:22:03
【问题描述】:

我正在实现一个面向 AMD 模块的 js 框架,该框架将用于第三方网站。

通过这一行,框架用户将配置必要的模块

<script data-main="/main.js" src="/require.js"></script>

问题在于 data-main 引用是异步加载的,因此任何依赖于 main.js 加载的模块的 js 逻辑都会失败,除非我可以确定它已完成加载。

我对 requirejs 还很陌生,所以不确定创建一个可供其他人使用的框架的好的做法是什么。

如何解决这个非常简单的问题?

编辑 一个例子来解释我的观点

ma​​in.js

requirejs.config({
    paths: {
        jquery: '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min',
    }
});

主要 js 参考 + 额外代码

 <script data-main="/main.js" src="/require.js"></script>
 <script>
    require(['jquery'], function($) {
        // since main.js is not loaded yet, it will assume that there is a jquery.js 
        // file on the same folder that this file
        console.log('myModule was also loaded and can use jQuery');
    });
 </script>

【问题讨论】:

  • 看看 jQuery 的最后 20-30 行,看看是否对你有帮助。
  • @squid314:恐怕我不明白这对我的特殊情况有何帮助。你能解释一下吗?谢谢:)
  • 再想一想,也许我倒退了。 jQuery 虽然不严格地打算成为 Require 管道的一部分,但它包含将自身暴露给 Require 管道的代码。请在下面查看我的答案。
  • @Louis:将define 替换为require

标签: javascript requirejs


【解决方案1】:

如果您想依赖其他库并且专门针对在 Require 管道中,您需要做的就是使用

声明一些依赖项
define(
    'myModule',    // module name
    ['foo'],       // module dependencies
    function(foo){ // module construction
        var myModule = {};

        .... code to set up the module ....

        return myModule;
    });

和 Require 会处理事情。这将使用 Require 注册您的模块,并且在您的所有依赖项都可用之前不会尝试构建您的模块。此功能已在 here 讨论。

更新示例

Require JS 旨在使用和不使用预构建配置。 Require 配置对象的paths 属性仅向 Require 提供有关如何尝试查找尚未注册的库的信息。但是,无论模块是如何/在何处注册的,Require 都会处理注册和依赖关系解析。请参阅this JSFiddle 了解如何注册和使用依赖项的工作示例。

关于配置的更新 2

由于 RequireJS 异步加载所有内容,您是对的,您的代码示例将无法正常工作。但是,您对“应该”如何工作做出了错误的假设。你有一个不正确的例子,说明你的图书馆客户的 Require 配置是什么样子的。如果其他人正在使用 RequireJS 构建应用程序并且他们想要使用您的库,他们应该在他们的require.config 中声明您的库的路径:

require.config({
    paths: {
        // this tells require how to load jQuery (a library maintained neither by you nor your clients).
        'jquery': '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min',
        // this tells require how to load myModule (the library you are building for your clients).
        'myModule': '//example.com/js/my-module.min',
        // this tells require how to load foo (a library built and hosted by your clients).
        'foo': 'scripts/foo'
    }
});

另一方面,如果您的客户不能更新他们的 Require 配置以在声明中包含您的库,那么您就不走运了。您所能做的就是获取所有依赖项并将它们捆绑在您的分发文件中,然后声明不依赖项:

define(
    'myModule',
    [], // can't declare any dependencies
    function() {
        // these dependencies are inside of the definition function to keep the global namespace clean
        // since we need jQuery, we have to inline it:
        var jQuery = ....
        // same goes for d3.js
        var d3 = ....

        // now we can set up the module itself
        var myModule = {};
        .... code to set up the module ....
        return myModule;
    }
);

显然,此选项意味着您不能使用您的客户正在使用的库。这意味着您的库将变得更重,并且包含有效的重复代码和数据。

希望能帮助您了解 Require 的工作原理以及其他人将如何使用您的库。

【讨论】:

  • 好答案,这就是我要说的。
  • 不确定我是否理解,你会把那个代码放在哪里?......如果我把那个代码放在&lt;script data-main="/main.js" src="/require.js"&gt;&lt;/script&gt;之后inmediatly 不起作用......或者是吗? main.js 是异步加载的,因此以后添加的任何代码都需要考虑
  • 也许您需要多了解一下 RequireJS 及其依赖系统的工作原理。在这里,您调用 define 函数,它是 Require 的一部分。在其依赖项可用之前,该函数不会调用您的模块构造函数。 define 函数由require.js 提供,而不是由main.js 提供。
  • @squid314:我可能会感到困惑,但我的 requirejs 配置(我指定模块的路径,在您的情况下为 myModulefoo)在 main.js 内。如果尚未加载 requirejs 配置,这将如何工作。也许您可以添加完整的模板以使您的解决方案正常工作。谢谢
  • 请查看我的更新答案和示例 @TimmyO'Tool 。我很确定可以在 require.js 脚本标记之后添加您的库文件。
【解决方案2】:

我终于用上了这种方法

<script src="http://mydomain/js/require.js"></script>
<script>
requirejs.config({  
    baseUrl: 'http://mydomain/js' 
});
require(['main'],function(){
    // here users can do anything they want as all required libraries are loaded
});
</script>

main.js 加载了 require 指令,而不是使用脚本标签中的 data-main 属性,这提供了一个回调,用户可以在其中放置他们的代码。

【讨论】:

    猜你喜欢
    • 2012-09-09
    • 2018-04-27
    • 2015-06-08
    • 2012-12-01
    • 2020-03-25
    • 1970-01-01
    • 2014-04-17
    • 2013-09-05
    • 1970-01-01
    相关资源
    最近更新 更多