0

我编写了一个完整的网络应用程序,并在我的 HTML 文档末尾的这一行中使用 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 上的方法时失败,然后加载编译的插件代码并在 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 加载程序中使用。

抱歉,我仍在寻找要问的正确问题。

4

1 回答 1

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";
    }
}());

它不漂亮,但它应该工作。

于 2013-07-09T14:59:03.700 回答