使用RequireJS模块化应用程序

时间:2013-07-08 18:15:51

标签: javascript jquery-plugins requirejs

我已经编写了一个完整的Web应用程序,并在HTML文档的末尾使用require中的require引导它:

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

在main.js中,我使用以下两个函数声明我的应用程序:

requirejs.config({

    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'] } }
});

requirejs(dependencies, function main(dependencies) { ... });

现在,我想将我的应用程序移植为jQuery插件。因此,我希望最终结果是将我的应用程序包装在jQuery fn中,

(function($) { $.fn.myPlugin = function() { ... }; }(jQuery));

模块化代码以编译成单个js文件(plugin-1.0.0.min.js),将代码包含在另一个项目中,有或没有AMD,并使用

将我的应用程序加载到div中
$('#pluginDiv').myPlugin({ options: {} }); 

首先,我是否需要更改requirejs / requirejs.config函数进行声明才能将我的应用程序打包为模块化组件?或者我只是这样离开我的应用程序?配置怎么样?

接下来,我如何将我的插件公开给插件用户将使用的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中的代码是

requirejs.config({
    paths: { 'jquery': 'vendor/jquery-1.9.1.min' },
    shim: { 'myPlugin': ['jquery'] }
});

requirejs(['jquery','myPlugin'], function main($) {
    $('#plugin').myPlugin(options);
});

但是,我的代码总是尝试绑定插件(来自app.js),当插件不是jQuery上的方法时失败,然后THEN加载编译的插件代码并在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加载器中使用。

对不起,我还在找出要问的正确问题。

1 个答案:

答案 0 :(得分:1)

对于使用和不使用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
(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";
    }
}());

它不漂亮,但它应该有用。