Requirejs 使用noConflict模式下的jQuery在require.js中加载不兼容AMD的jQuery插件的正确方法?
假设我想将jquery与使用标准闭包定义的标准、非amd支持的jquery插件一起使用:Requirejs 使用noConflict模式下的jQuery在require.js中加载不兼容AMD的jQuery插件的正确方法?,requirejs,amd,Requirejs,Amd,假设我想将jquery与使用标准闭包定义的标准、非amd支持的jquery插件一起使用:(函数($)($.fn.myplugin={…})(jquery)
(函数($)($.fn.myplugin={…})(jquery)所有这些都位于js/libs/jquery/jquery.myplugin.js
中
我使用这个配置:
require.config({
baseUrl: 'js/',
paths: {
'jquery': 'libs/jquery/jquery-noconflict',
'underscore': 'libs/underscore/underscore',
'backbone': 'libs/backbone/backbone',
'jquery-myplugin': 'libs/jquery/jquery.myplugin'
},
shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'jquery-myplugin': {
deps: ['jquery']
}
});
我在libs/jQuery/jQuery noconflict.js
中以无冲突模式加载jQuery,因为我不想污染全局命名空间:
define(['libs/jquery'], function () {
return jQuery.noConflict(true);
});
这就是我加载主app.js的方式:
define([
'jquery',
'underscore',
'backbone',
'jquery-myplugin'],
function($, _, Backbone, MyPlugin){
//MyPlugin is always undefined, not even sure if
//I should be passing it here if it only extends jQuery?
});
现在,我遇到了一个问题——虽然我可以毫无问题地使用上面定义的所有库,但我无法制定正确的shim
配置来加载未启用AMD的jquery插件
我曾尝试将jquerymyplugin
设置为jquery
的deps
(以及其他方法),但我始终无法让它工作
似乎我对以下场景有问题:
jQuery以无冲突模式加载
插件代码运行,扩展了上面jQuery的实例
我可以在我的应用程序中使用$,并通过插件代码进行扩展,因此$.myplugin可用
我看到过类似的问题,但没有一个真正解决了这个问题,只给出了模糊的建议,比如“使用垫片配置”
编辑
我也试过使用
"jquery-myplugin": {
deps: ["jquery"],
exports: "jQuery.fn.myplugin"
}
虽然插件方法在以这种方式加载为AMD模块后可用,但我仍然无法访问:$('.class').myplugin()
作为默认$object并没有使用myplugin代码进行扩展。使用jQuery.noConflict(true)
删除jQuery
全局变量。加载插件时,它尝试访问jQuery
,但无法访问,导致此故障
如果您的插件是一个模块,那么它可以作为依赖项访问jQuery。或者您可以将jQuery
作为全局变量保留。首先,确保“path/to/jQuery myplugin”实际上扩展了窗口。jQuery
而不是$
noConflict()离开窗口。jQuery
对象已定义,但从窗口解除绑定。$
在一些新浏览器上窗口。$
是本机文档的内置别名。querySelectorAll
函数
其次,您的myplugin不需要返回自身,因为它本身无法使用。因为它扩展了jQuery,所以从myplugin调用返回jQuery
最后,“path/to/jquery myplugin”不是一个模块。这是一个普通的JS文件。可能RequireJS试图像模块一样加载它,但没有找到define()
调用,这会导致混乱。尝试将“.js”文件扩展名添加到引用中,以向RequireJS发出需要使用“js!”插件加载资源的信号
require.config({
paths: {
"jquery": "path/to/jquery",
"jquery-myplugin": "path/to/jquery-myplugin.js"
},
shim: {
"jquery": {
init: function() {
return window.jQuery.noConflict();
},
"jquery-myplugin": {
deps: ['jquery']
init: function($) {
return $;
},
}
}
});
今天我和你有同样的问题。下面是我如何修复它的:
requirejs.config({
"baseUrl": "js/lib",
"paths": {
"app": "../app"
}
});
// Final version of jQuery with all needed plugins.
define("jquery", ["jquery-core", "myplugin"], function(jqCore) {
return jqCore;
});
// Define core jQuery module.
define("jquery-core", ["jquery-1.9.1.min"], function() {
return jQuery.noConflict(true);
});
// This module exposes jquery module to the global scope and returns previous defined version.
define("jq-global", ["jquery-core"], function(jqCore) {
var tmp = jQuery;
jQuery = jqCore;
return tmp;
});
// Define your plugin here, and don't forget to reset previous jQuery version.
define("myplugin", ["jq-global", "jquery.myplugin"], function(jqGlobal, jqPlugin) {
jQuery = jqGlobal;
});
// Load the main app module to start the app
requirejs(["app/main"]);
现在,在我的app/main.js文件中,我可以执行以下操作:
define(["jquery"], function($) {
$('body').myplugin();
});
这里的想法是在执行插件代码之前临时公开jQuery。到目前为止,我没有在需要加载更多模块的更大环境中测试该解决方案,因此我不能保证它能够长期工作;)
编辑
这个解决方案行不通!!由于requirejs不按顺序加载脚本,因此可能在jquery之前加载插件js文件,这将导致执行失败。对不起
如果有人有其他想法…谢谢Sean,我知道这里会发生什么,我想做的是正确地使用require.js,其中没有一个模块应该创建全局变量,如果需要,所有其他模块都将jQuery作为依赖项加载。如果是这样,您将无法使用未转换的插件。如果您希望jQuery仅作为一个模块可用,那么您必须将插件转换为使用define()
,以便声明对jQuery的依赖关系。感谢Sean,我的印象是,shim config仍然允许您在不使用全局依赖关系的情况下处理未启用AMD的模块。为了让第三方代码与AMD/require一起工作,你不得不修改第三方代码。Shim可以让你把一个简单的脚本变成一个模块,但是它不能让你获得依赖性。如果您将jQuery作为一个全局查询,它会成功的。令人遗憾的是,第三方的东西不能与AMD合作。当jQuery采用它时,我有很高的期望。当主干网将其移除后,很明显我们不会很快看到大规模采用。这是错误的。noConflict的代码如下:javascript noConflict:function(deep){if(window.$==jQuery){window.$=}if(deep&&window.jQuery==jQuery){window.jQuery==jQuery;}返回jQuery;},
当您传递“deep”参数时,它也会解除绑定window.jQuery,因此,您可以在同一页上运行多个版本。您对此仍有问题吗?模块依赖项应在数组中表示:define(['dep1','dep2'…'depn'],function(dep1,dep2,…depn){})代码>如上所述,这是一个很好的捕获,但这只是我在stackoverflow上的错误输入,根本问题仍然存在