为什么只说CommonJS适合非浏览器应用程序?

Jon*_*han 41 javascript architecture components design-patterns commonjs

为什么不将它用作Javascript的通用组件模式,包括浏览器执行的Javascript?

一目了然,这似乎是模块化我正在进行的项目的好方法,它包含一个大型的Javascript代码库,包含许多组件,其中一些与彼此交互.

Kev*_*oor 72

CommonJS绝对适合浏览器,但有一些注意事项.CommonJS模块模式相当不错(我的偏见),也是为ECMAScript Harmony(计划的JavaScript语言的下一版本)提出的模块系统的一个很好的垫脚石.具体而言,Harmony模块将无法访问全局("窗口")对象.

有些人声称CommonJS模块不适合浏览器的原因是,如果没有服务器端的帮助,它们无法通过<script>标签加载.例如,假设您有一个markdown库,可以导出"convertToHTML"函数.然后,您可以创建一个如下所示的模块:

var convertToHTML = require("markdown").convertToHTML;
exports.mangleSomeText = function() {
    // do something then call convertToHTML
}
Run Code Online (Sandbox Code Playgroud)

由于某些原因,这不能通过脚本标记起作用(范围未包装,因此convertToHTML将附加到窗口,通常不会定义require,并且需要为每个模块单独创建导出).

具有一点服务器端帮助的客户端库可以允许通过脚本标签轻松加载.或者,通过XMLHttpRequest加载脚本并执行eval()的客户端库也可以工作,尽管调试体验通常不太好.

现在一个相当合理的解决方案是RequireJS,虽然也是CommonJS成员之间争议争议的主题.使用RequireJS,您可以像这样编写模块:

define(function(require, exports, module) {

var convertToHTML = require("markdown").convertToHTML;
exports.mangleSomeText = function() {
    // do something then call convertToHTML
}

});
Run Code Online (Sandbox Code Playgroud)

我们所做的就是在模块周围添加define()位.(你可能也很容易让服务器这么做,所以你甚至不需要手动输入define部分).

我现在亲自在几个项目中使用RequireJS,并且发现在没有服务器端位的情况下使用CommonJS模块是一种简单的方法.还有许多其他解决方案,如果您不依赖于运行静态JS文件,标准的CommonJS模块是一个很好的方法.

(ObDisclaimer:我开始了CommonJS项目,所以我显然有偏见.)

  • 要迂腐,ECMAScript Harmony模块确实可以访问全局对象,而不是共享的顶级词法范围. (3认同)
  • 是否可以编写一个兼容requirejs和commonjs的模块? (3认同)