假设我想将jquery与使用标准闭包定义的标准的非amd启用的jquery插件一起使用:(function($))( $.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插件。
我已尝试将jquery-myplugin
设置为deps
的{{1}}(以及其他方式)但我永远无法让它正常工作。
似乎我遇到以下情况的问题:
我已经看到类似的问题浮出水面,但没有一个实际上解决了这个问题只给出了模糊的建议,比如“使用shim config”...
修改
我也尝试过使用
jquery
虽然插件方法在以这种方式加载为AMD模块后可用,但我仍然无法访问:"jquery-myplugin": {
deps: ["jquery"],
exports: "jQuery.fn.myplugin"
}
因为默认的$ object尚未使用myplugin代码进行扩展。
答案 0 :(得分:3)
使用jQuery.noConflict(true)
删除jQuery
全局变量。当您的插件加载时,它会尝试访问jQuery
,但不能,导致此失败。
如果您的插件是一个模块,它可以访问jQuery作为依赖项。或者您可以将jQuery
作为全局提供。
答案 1 :(得分:-1)
首先,确保" path / to / jquery-myplugin"实际上扩展了window.jQuery
而不是$
noConflict()会保留window.jQuery
个对象,但会从window.$
取消绑定。在某些新浏览器window.$
内置了本地document.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 $;
},
}
}
});
答案 2 :(得分:-1)
我今天和你有同样的问题。以下是我可以解决的问题:
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不会按顺序加载脚本,因此插件js文件可能会在jquery之前加载,这将导致执行失败。对不起。
如果有人有另一个想法......