【问题标题】:Javascript - build plugin for requireJSJavascript - 为 requireJS 构建插件
【发布时间】:2016-12-21 17:45:45
【问题描述】:

我编写了一个 Javascript 插件,我想让它与 requireJS 兼容。但是,我很难让它正常工作。我认为我的 AMD 写不正确或类似的东西。

当我尝试执行插件构造函数时,它在 requireJS 加载脚本后没有定义(也没有定义来自 requirejs 的回调变量)。

例如我这样使用requirejs:

requirejs([
'./assets/js/myplugin.js'
], function( myplugin) {

    console.log(myplugin); // undefined
    new MyPlugin(); // undefined

});

在 myplugin.js 我有这个脚本:

(function (root, factory) { 

if (typeof define === 'function' && define.amd) {

    define(
        'myplugin',
        ['brandname-util1/util1',
        'brandname-util2/util2',
        'brandname-util3/util3'],
        factory
    );

} else if (typeof exports === 'object' && module.exports) {

    module.exports = factory(
        root,
        require('brandname-util1'),
        require('brandname-util2'),
        require('brandname-util3')
    );

} else {

    root.MyPlugin = factory(
        root,
        root.BrandNameUtil1,
        root.BrandNameUtil2,
        root.BrandNameUtil3
    );

}

}(this, function factory(root, util1, util2, util3) {

    'use strict';

    var MyPlugin = function() {
    }

    return MyPlugin;

}));

脚本已正确加载(异步),但未定义任何内容。我不确定完全理解它是如何工作的。

编辑:这里是 utils 脚本示例:

// util1
(function(root, factory) {

    if (typeof define === 'function' && define.amd) {

        define(
            'brandname-util1/util1',
            ['jquery'],
            factory
        );

    } else if (typeof module === 'object' && module.exports) {

        module.exports = factory(require('jquery'));

    } else {

        root.BrandNameUtil1 = factory(root);

    }

}(this, function() {

    "use strict";

    var util1 = {};

    // declare some functions

    return util1;

}));

// util2
(function(root, factory) {

    if (typeof define === 'function' && define.amd) {

        define(
            'brandname-util2/util2',
            ['jquery'],
            factory
        );

    } else if (typeof module === 'object' && module.exports) {

        module.exports = factory(require('jquery'));

    } else {

        root.BrandNameUtil2 = factory(root);

    }

}(typeof window !== "undefined" ? window : this, function() {

    "use strict";

    var util2 = function() {},
        proto = util2.prototype;

    // declare some proto

    return util2;

}));

// util3
(function (root, factory) { 

    if (typeof define === 'function' && define.amd) {

        define(
            'brandname-util3/util3',
            ['brandname-util1/util1',
            'brandname-util2/util2'],
            factory
        );

    } else if (typeof module === 'object' && module.exports) {

        module.exports = factory(
            root,
            require('brandname-util1'),
            require('brandname-util2')
        );

    } else {

        root.BrandNameUtil3 = factory(
            root,
            root.BrandNameUtil1,
            root.BrandNameUtil2
        );

    }

}(this, function (root, util1, util2) {

    "use strict";

    var util3 = function() {},
        proto = util3.prototype;

    // declare some proto

    return util3;

}));

【问题讨论】:

    标签: javascript requirejs amd


    【解决方案1】:

    我看到的唯一问题是您的工厂将root 作为第一个参数,然后是模块。它在 CommonJS(第二个分支)和没有模块系统(第三个分支)中工作正常,但在 AMD 案例(第一个分支)中它会失败,因为 define 将调用您的工厂,只有 3 个参数:root 将设置为依赖列表的第一个模块,util3 不会被设置,等等

    如果您实际上没有在工厂中使用root,您可以将其从参数列表中删除并调整第 2 和第 3 分支中的调用以不通过它,一切都应该正常。

    否则,如果您的工厂确实需要它,您可以通过更改您的第一个分支来修复它:

    define(['brandname-util1/util1',
        'brandname-util2/util2',
        'brandname-util3/util3'],
        factory.bind(undefined, root)
    );
    

    这会将工厂中this 的值设置为undefined(应该没问题),并强制将工厂中的第一个参数设置为root 在您的@987654331 范围内的值@ 称呼。然后将模块附加在它之后。

    有关其工作原理的更多详细信息,请参阅bind 上的此文档。

    您也不应该在define 调用中设置模块名称。我上面显示的调用删除了模块名称。调用应该只有依赖列表和工厂。

    而且你不应该将.js 放在模块名称中。所以requirejs(['./assets/js/myplugin'], 没有.js

    【讨论】:

    • 感谢您的回答。它没有解决问题,一切都还不确定。
    • 我已经用我之前没有注意到的另外两个问题编辑了我的答案。
    • 谢谢。我不能让它工作。我想我对正确处理旧的 util 依赖的方式感到困惑。我通过添加 utils 的所有代码来编辑我的问题。
    • 我现在没有太多时间,但看了一眼您的代码,我发现 root 存在同样的问题,并使用硬编码模块名称调用 define 作为第一个参数在您的另一个中重复出现模块。您需要检查所有模块并对问题中最初的代码进行相同的更正。
    • 如果我删除硬编码的模块名称,则依赖项失败并且脚本被破坏。看来我必须定义一个名称才能在另一个匿名 AMD 模块中使用它。
    猜你喜欢
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多