Javascript 使用RequireJS模块化应用程序
我已经编写了一个完整的web应用程序,并在HTML文档末尾的这一行中使用require引导它:Javascript 使用RequireJS模块化应用程序,javascript,jquery-plugins,requirejs,Javascript,Jquery Plugins,Requirejs,我已经编写了一个完整的web应用程序,并在HTML文档末尾的这一行中使用require引导它: <script src="js/vendor/require-2.1.6.min.js" data-main="js/main.js"></script> 现在,我想把我的应用程序移植为jQuery插件。因此,我希望最终的结果是将我的应用程序包装在jQuery fn中 (function($) { $.fn.myPlugin = function() { ... }; }(j
<script src="js/vendor/require-2.1.6.min.js" data-main="js/main.js"></script>
现在,我想把我的应用程序移植为jQuery插件。因此,我希望最终的结果是将我的应用程序包装在jQuery fn中
(function($) { $.fn.myPlugin = function() { ... }; }(jQuery));
将代码模块化以编译成单个js文件(plugin-1.0.0.min.js),将代码包含在另一个项目中,无论是否使用AMD,并使用
$('#pluginDiv').myPlugin({ options: {} });
首先,我是否需要将requirejs/requirejs.config函数更改为declares,以便将我的应用程序打包为模块化组件?还是干脆就这样离开我的应用程序?配置呢
接下来,我如何向插件用户将使用的jQuery公开我的插件,例如,在全局范围内声明的jQuery?如果他们用的是AMD,这会起作用吗
更新
对于问题1,我将我的requirejs.config移到一个构建文件build.js中,该文件需要一些附加属性:
({
baseUrl: ".",
paths: {
'jquery': 'vendor/jquery-1.9.1.min',
'lodash': 'vendor/lodash-1.3.1.min',
'knockout': 'vendor/knockout-2.2.1.min',
'bootstrap': 'vendor/bootstrap-2.3.2.min'
},
shim: { 'bootstrap': { deps: ['jquery'] } },
optimize: "none", // for debug
name: "main",
out: "plugin.js"
})
我能够使用r.js来编译它,它工作得非常好
然而,我仍然无法回答第二个问题。我编译的myPlugin.js中的代码如下:
requirejs(dependencies, function main(dependencies) {
(function($) {
$.fn.myPlugin = function(options) {
...
return this;
};
})(jQuery);
});
其中依赖项不包括jQuery。然后,我通过调用以下命令引导应用程序:
<script src="js/vendor/require-2.1.6.min.js" data-main="js/app.js"></script>
但是,我的代码总是尝试绑定插件(来自app.js),当插件不是jQuery上的方法时失败,然后加载编译的插件代码并在jQuery上创建方法。这里有什么问题
更新2
因此,我使用requirejs及其优化器创建了一个模块化JavaScript文件plugin.js。编译的插件脚本中的主代码
requirejs(dependencies, function main(dependencies) {
(function($) {
$.fn.plugin = function(options) { return this; }
})(window.jQuery);
);
在父应用程序中的主代码之后才会调用:
requirejs(['jquery','plugin'], function main($) {
$('#plugin').plugin({});
});
我想这是因为他们都在给requirejs打电话。因此,这里的问题是如何编写插件,使其在AMD加载程序中可用
很抱歉,我仍然在想应该问的问题。有一个非常标准的惯例,用于模块化插件,无论是否使用requirejs。它看起来像这样:
(function(){
var makeplugin = function(dependancies){
//do your plugin
};
if(define && define.amd) {
defined(dependancies,function(dependancies){
makeplugin(dependancies);
});
} else {
makeplugin(dependancies)
}
}());
因为您的插件在内部使用require,但您的父应用不必这样做,所以您可以使用$.getScript()加载requirejs
它不漂亮,但应该有用。让我看看你的问题是否正确。您有一个使用require的奇特插件,但希望将插件调用绑定到主窗口。$jquery object?我还不清楚一些事情。你是想把这个插件放到窗口。$还是放到带垫片的jQuery?父应用程序是否需要require.js?我想我明白了。。。您的插件旨在用作垫片,而不是jquery对象。您的插件使用jquery对象,但您希望它使用全局jquery对象,而不是require的依赖项jquery。对吗?现在,我要问最后一句话。该插件使用require。如果父应用程序不使用require,那么requirejs是如何加载的?据我所知不是这样。但是,我还没有尝试从$.loadScript加载require。让我来处理一下,今天晚些时候我会给你一个解决方案。很抱歉,我有点偏离了实际问题。所以问题是,在我的app.js文件中,最后一段代码$(“#plugin”).myPlugin(options)生成一个错误“Object has no method‘plugin’”,然后立即加载插件。我不确定为什么在运行app.js代码之前没有加载我的插件,因为插件被列为依赖项。因为require创建了自己的jQuery版本,并传递它,而不是使用全局方法。这就是为什么我一直问你是在使用window.$object还是带垫片的jQuery。上面的例子将为您解答这个问题,您可以将插件编写为normal.True。我的问题是我的makeplugin函数使用AMD。请参阅我的编辑。对,这就是解决方案中的第二条if语句。如果父级不使用require,它将加载、配置它,并成为makeplugin.Err的全局变量。定义了define和define.amd,但它在执行主应用程序代码之前不加载模块,而是在执行之后加载模块。请参见编辑。
requirejs(['jquery','plugin'], function main($) {
$('#plugin').plugin({});
});
(function(){
var makeplugin = function(dependancies){
//do your plugin
};
if(define && define.amd) {
defined(dependancies,function(dependancies){
makeplugin(dependancies);
});
} else {
makeplugin(dependancies)
}
}());
(function(){
var makeplugin = function($){
//do your plugin
};
if(define && define.amd) {
// require is defined already, just use the plugin and have it load what it needs
define(["jquery"],makeplugin);
} else if(jQuery){
// load require
jQuery.getScript("/vendor/require",function(){
require.config({
// your config
});
makeplugin(jQuery);
});
} else {
throw "requirejs or jquery are required for this plugin";
}
}());