为什么CommonJS仅适用于非浏览器应用程序?

时间:2022-03-10 22:46:10

Why not use it as a general component pattern for Javascript, including browser-executed Javascript?

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

At a glance, it seems to be a good way to modularize the project I'm currently working on, which consists of a large Javascript code-base, with lots of components, some of which interact with eachother.

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

1 个解决方案

#1


72  

CommonJS is definitely suitable for the browser, with some caveats. The CommonJS module pattern is quite nice (in my biased opinion), and is also a good stepping stone to the module system proposed for ECMAScript Harmony (the planned next release of the JavaScript language). Specifically, Harmony modules won't have access to the global ("window") object.

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

The reason that some people claim CommonJS modules are not suitable for the browser is that they can't be loaded via a <script> tag without some server-side assistance. For example, imagine you have a markdown library that exports a "convertToHTML" function. You could then make a module that looks like this:

有些人声称CommonJS模块不适合浏览器的原因是,如果没有服务器端的帮助,它们无法通过

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

This doesn't work via a script tag for a few reasons (the scope isn't wrapped, so convertToHTML would get attached to window, require wouldn't typically be defined and exports needs to be created separately for each module).

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

A client side library with a tiny bit of server side help could allow this to load via script tags easily. Or, a client side library that loads the script via XMLHttpRequest and does an eval() would also work, though the debugging experience is often not as good.

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

A fairly reasonable solution right now, though one that is also the subject of contentious debate among CommonJS members, is RequireJS. Using RequireJS, you can write your module like this:

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

define(function(require, exports, module) {

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

});

All we did was add that define() bit around the module. (You could likely make a server do that pretty easily as well, so that you don't even need to manually type the define part).

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

I've personally used RequireJS on a couple of projects now and find it an easy way to make use of CommonJS modules without a server-side bit. There are many other solutions and if you aren't reliant on running static JS files, standard CommonJS modules are a great way to go.

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

(ObDisclaimer: I started the CommonJS project, so I am clearly biased.)

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

#1


72  

CommonJS is definitely suitable for the browser, with some caveats. The CommonJS module pattern is quite nice (in my biased opinion), and is also a good stepping stone to the module system proposed for ECMAScript Harmony (the planned next release of the JavaScript language). Specifically, Harmony modules won't have access to the global ("window") object.

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

The reason that some people claim CommonJS modules are not suitable for the browser is that they can't be loaded via a <script> tag without some server-side assistance. For example, imagine you have a markdown library that exports a "convertToHTML" function. You could then make a module that looks like this:

有些人声称CommonJS模块不适合浏览器的原因是,如果没有服务器端的帮助,它们无法通过

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

This doesn't work via a script tag for a few reasons (the scope isn't wrapped, so convertToHTML would get attached to window, require wouldn't typically be defined and exports needs to be created separately for each module).

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

A client side library with a tiny bit of server side help could allow this to load via script tags easily. Or, a client side library that loads the script via XMLHttpRequest and does an eval() would also work, though the debugging experience is often not as good.

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

A fairly reasonable solution right now, though one that is also the subject of contentious debate among CommonJS members, is RequireJS. Using RequireJS, you can write your module like this:

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

define(function(require, exports, module) {

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

});

All we did was add that define() bit around the module. (You could likely make a server do that pretty easily as well, so that you don't even need to manually type the define part).

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

I've personally used RequireJS on a couple of projects now and find it an easy way to make use of CommonJS modules without a server-side bit. There are many other solutions and if you aren't reliant on running static JS files, standard CommonJS modules are a great way to go.

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

(ObDisclaimer: I started the CommonJS project, so I am clearly biased.)

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