RequireJS 的语法糖 Simplified CommonJS Wrapping

文章目录

    介绍语法糖之前,先看一段恶心的代码

    define([ "require", "jquery", "blade/object", "blade/fn", "rdapi",
             "oauth", "blade/jig", "blade/url", "dispatch", "accounts",
             "storage", "services", "widgets/AccountPanel", "widgets/TabButton",
             "widgets/AddAccount", "less", "osTheme", "jquery-ui-1.8.7.min",
             "jquery.textOverflow"],
    function (require,   $,        object,         fn,         rdapi,
              oauth,   jig,         url,         dispatch,   accounts,
              storage,   services,   AccountPanel,           TabButton,
              AddAccount,           less,   osTheme) {
    
    });
    

    这段代码的风险在于,容易出现依赖列表顺序与函数变量的对应关系不一致。
    至少我在写 angular 的时候,经常在依赖注入设置时出现类似 bug。
    例如,我想去掉 services 的依赖,经常去掉了依赖列表里的条目,但是忘了同时去掉函参里的对应项。

    好在, Requirejs 提供了一个语法糖,e.g.

    define(function (require) {
        var dependency1 = require('dependency1'),
            dependency2 = require('dependency2');
    
        return function () {};
    });
    

    这样在去掉一项依赖时,只需要删除一行代码即可,不需要瞻前顾后。

    注意,为了规范性已经可读性,最好将所有依赖都写在函数的头部。

    这样做就没有缺点了么

    一位大神在文章 AMD 的 CommonJS wrapping 提出了不同的看法。

    他不认同该语法糖的原因有二

    • 看上去是顺序执行的代码实际上不是。因为凡是使用 require 的代码都会提前执行。即,这是披着 CommonJS 皮的 AMD 代码。
    • requirejs 的依赖提取逻辑有 bug,例如对注释的支持不好。

    但是这两个问题是我可以接受的 :)

    注,AMD 与 CommonJS 的区别, 参考 使用 AMD、CommonJS 及 ES Harmony 编写模块化的 JavaScript

    • AMD(异步模块定义,Asynchronous Module Definition)采取了一种浏览器优先的方式来开发,选择了异步行为。
    • CommonJS 则采用了服务器优先的策略,采取同步行为。

    参考

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式