J. *_*rsh 45 javascript jquery module requirejs
我们假设这是我的config.js或main.js:
require.config({
// paths are analogous to old-school <script> tags, in order to reference js scripts
paths: {
jquery: "libs/jquery-1.7.2.min",
underscore: "libs/underscore-min",
backbone: "libs/backbone-min",
jquerymobile: "libs/jquery.mobile-1.1.0.min",
jquerymobilerouter: "libs/jquery.mobile.router.min"
},
// configure dependencies and export value aliases for old-school js scripts
shim: {
jquery: ["require"],
underscore: {
deps: ["jquery"],
exports: "_"
},
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
jquerymobilerouter: ["jquery", "backbone", "underscore"],
jquerymobile: ["jquery", "jquerymobilerouter", "backbone", "underscore"]
}
});
require(["jquery", "backbone", "underscore", "app/app.min", "jquerymobilerouter", "jquerymobile"], function ($, Backbone, _, App) {
console.log($);
console.log(Backbone);
console.log(_);
$("body").fadeIn(function () {
App.init();
});
});
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,paths配置选项允许您引用脚本,<script>在HTML中引用标签.假设是这种情况,我是否仍然需要在下面的实际require语句中使用a $或下划线对jQuery等脚本进行别名_?考虑到如果您使用标准<script>标记引用jQuery ,$可以在整个脚本中自动使用,这似乎很奇怪.使用它不应该是一样的paths吗?
我是shim配置选项的新手,据我所知已取代已弃用的order!插件.该exports物业实际上做了什么?它似乎没有为脚本创建别名; 例如,如果我将exports下划线设置为"whatever",然后尝试console.log(whatever),则它是未定义的.那有什么意义呢?
像jQuery这样的脚本如何"全局"正确使用?也就是说,能够$在我的App.js模块或我的"app"文件夹中的任何其他模块中使用别名的正确方法是什么?我是否必须在每个单独的模块中使用jQuery并且每次都使用别名$?或者我在这里以正确的方式完成它的方式?
我也非常感谢对这个特定剧本的任何其他批评; 在我看来,Require.js的文档还有很多不足之处; 我真的很想知道的事情似乎被掩盖了,让我挠头.
Nic*_*tti 22
路径告诉require.js何时需要依赖关系.
例如,我有这样的配置:
"paths": {
"jquery": "require_jquery"
},
"shim": {
"jquery-cookie" : ["jquery"],
"bootstrap-tab" : ["jquery"],
"bootstrap-modal": ["jquery"],
"bootstrap-alert": ["jquery"]
},
Run Code Online (Sandbox Code Playgroud)
这意味着我每次都在模块中
define( ['jquery']
Run Code Online (Sandbox Code Playgroud)
requirejs require_jquery从主路径加载文件,而不是尝试加载jquery.js.在您的情况下,它将加载jQuery源文件,然后全局可用.我个人不喜欢这种方法,因此我在require_jquery.js文件中这样做:
define( ["jquery_1.7.2"], function() {
// Raw jQuery does not return anything, so return it explicitly here.
return jQuery.noConflict( true );
} );
Run Code Online (Sandbox Code Playgroud)
这意味着jQuery只会在我的模块中定义.(这是因为我写了Wordpress插件,因此我可以包含我自己的jQuery版本,而无需触及外部版本)
导出(从文档读取只是应该是您正在使用的模块的名称,以便在加载正确时可以检测到.这里有解释.所以如果你想为下划线设置导出它应该是_
正如我所解释的那样,jQuery应该是全局的,如果只是导入它,则执行文件并且jQuery是全局的
编辑 - 回答评论.
是的我的意思是,你必须为jQuery导出$或jQuery,为主干导出_.根据我从文档中获得的内容,仅在某些边缘情况下才需要这样,并且对于将全局名称空间声明为jQuery的库而言,这不是必需的.
我认为,当必须从CDN加载jQuery时,需要它们才需要它们.我认为requirejs首先尝试从CDN加载jQuery,然后通过检查"已导出"变量是否存在来进行检查以验证它是否已正确加载,如果不存在,则从本地文件系统加载它(如果你当然已经配置了后备).当requirejs无法看到404回来时,这是需要的.
jQuery是全球可用的,因为它被声明为全局的.如果你只是加载并执行jQuery脚本,你最终将得到两个全局变量,$并且jQuery(或者你可以像我一样做并避免这种情况).在define()函数内部,你可以将jQuery别名为你想要的任何东西.
define( [ 'jquery' ], function( jq ) {
// jq is jquery inside this function. if you declared it
// globally it will be also available as $ and jQuery
} );
Run Code Online (Sandbox Code Playgroud)Iso*_*ous 22
为了清除任何混淆exports,假设任何填充库将属性附加到全局上下文(window或root),或修改已存在的全局属性(例如jQuery插件).当requireJS获取加载shimmed依赖项的命令时,它会检查与exports该shim config 的值匹配的属性的全局上下文,如果找到它,则将其作为该模块的值返回.如果找不到它,则它加载相关的脚本,等待它执行,然后找到全局符号并返回它.
需要记住的一个重要事实是,除非shim配置包含exports值,init否则不会执行该配置上的任何方法.依赖性加载器必须exports在初始化该模块之前找到模块的值(这是指定的值),这就是为什么在init该模块存在垫片时需要该属性的原因.
更新:我还需要指出,如果有问题的模块在define任何地方调用,那么您对该模块的任何shim配置都将被忽略.这实际上让我有些头疼,因为我想使用shim配置调用jQuery的jQuery.noConflict(true)方法来取消jQuery的全局化,并将其范围限定为只需要它的模块,但无法让它运行起来.(有关如何使用map config而不是shim config轻松完成此操作的信息,请参阅底部更新.)
更新2:关于requireJS谷歌小组的最近一个问题让我意识到我的解释可能有些误导,所以我想澄清一下.如果通过requireJS加载至少一次, RequireJS将仅重新使用填充的依赖项.也就是说,如果你只是<script>在主机页面上有一个标签(例如,下划线),就像这样:
<script src='lib/underscore.js'></script>
<script src='lib/require.js' data-main='main.js'></script>
Run Code Online (Sandbox Code Playgroud)
...你在requireJS配置中有这样的东西:
paths: {
'underscore': 'lib/underscore'
},
shim: {
'underscore': {
exports: '_'
}
}
Run Code Online (Sandbox Code Playgroud)
然后第一次执行define(['underscore'], function (_) {});或者var _ = require('underscore');,RequireJS将重新加载下划线库,而不是重新使用先前定义的window._,因为只要requireJS知道,您之前从未加载下划线.当然,它可以检查是否_已经在根作用域上定义,但它无法验证_已经存在的那个与您的paths配置中定义的那个相同.例如,无论是prototype和jquery分配自己window.$默认的,如果requireJS假设"窗口.$"是jQuery的时候它实际上是原型,你要在一个糟糕的情况.
所有这一切意味着,如果您混合并匹配脚本加载样式,那么您的页面最终会出现以下情况:
<script src='lib/underscore.js'></script>
<script src='lib/require.js' data-main='main.js'></script>
<script src='lib/underscore.js'></script>
Run Code Online (Sandbox Code Playgroud)
第二个下划线实例是requireJS加载的实例.
基本上,必须通过requireJS加载库,以便requireJS了解它.但是,下次你需要下划线时,requireJS会"嘿,我已经加载了它,所以只需交回任何exports值,不要担心加载另一个脚本."
这意味着您有两个真正的选择.一个是我认为是反模式的:只是不要使用requireJS来表示全局脚本的依赖关系.也就是说,只要库将全局附加到根上下文,您就能够访问它,如果没有明确要求该依赖项,则会发生事件.你可以看到为什么这是一个反模式 - 你基本上只是消除了使用AMD加载器的大部分优势(显式依赖列表和可移植性).
另一个更好的选择是使用requireJS加载所有内容,以至于您自己应该创建的唯一实际脚本标记是最初加载requireJS的标记.您可以使用填充程序,但95%的情况下,在脚本中添加AMD包装器并不困难.将所有非AMD库转换为AMD兼容可能需要更多的工作,但是一旦完成了一两个,它就会变得容易多了 - 我可以使用任何通用的jQuery插件并将其转换为AMD模块不到一分钟 这通常只是一个问题
define(['jquery'], function (jQuery) {
Run Code Online (Sandbox Code Playgroud)
在顶部,和
return jQuery;
});
Run Code Online (Sandbox Code Playgroud)
在底部.我有'jquery'映射的原因jQuery而不是$我注意到这些天大多数插件都包含在这样的闭包中:
(function ($) {
// plugin code here
})(jQuery);
Run Code Online (Sandbox Code Playgroud)
注意预期的范围是个好主意.你当然可以$直接映射'jquery' ,假设插件不希望找到jQuery而不是$.这只是基本的AMD包装器 - 更复杂的通常会尝试检测正在使用哪种加载器(commonJS vs AMD与常规ol'全局)并根据结果使用不同的加载方法.你可以在google上用几秒钟轻松找到这个例子.
更新:我曾经支持使用jQuery.noConflict(true)RequireJS 的解决方法有效,但它需要对jQuery源进行非常小的修改,而且我已经想出了一个更好的方法来完成同样的事情而不修改jQuery.幸运的是,RequireJS的作者James Burke也将其添加到RequireJS文档中:http://requirejs.org/docs/jquery.html#noconflictmap
| 归档时间: |
|
| 查看次数: |
12385 次 |
| 最近记录: |