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

时间:2011-01-23 10:16:46

标签: javascript architecture components design-patterns commonjs

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

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

1 个答案:

答案 0 :(得分:72)

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

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

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

由于某些原因,这不能通过脚本标记起作用(范围未包装,因此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
}

});

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

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

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