如何在Node.js和浏览器之间共享代码?

我正在使用JavaScript客户端(在浏览器中运行)和Node.js服务器创建一个小型应用程序,并使用WebSocket进行通信。

我想在客户端和服务器之间共享代码。至少可以说,我才刚刚开始使用Node.js,而我对现代JavaScript的了解还有些生疏。因此,我仍然对CommonJS require()函数有所了解。如果我使用“导出”对象创建程序包,那么我将看不到如何在浏览器中使用相同的JavaScript文件。

我想创建一套在两端使用的方法和类,以方便编码和解码消息以及其他镜像任务。但是,Node.js / CommonJS打包系统似乎使我无法创建可在两侧使用的JavaScript文件。

我也尝试使用JS.Class来获得更严格的OO模型,但是我放弃了,因为我无法弄清楚如何使提供的JavaScript文件与require()一起使用。我在这里想念什么吗?

阿飞达蒙樱2020/03/23 09:26:21

我写了这个,如果要将所有变量设置为全局范围,使用起来很简单:

(function(vars, global) {
    for (var i in vars) global[i] = vars[i];
})({
    abc: function() {
        ...
    },
    xyz: function() {
        ...
    }
}, typeof exports === "undefined" ? this : exports);
伽罗理查德2020/03/23 09:26:21

将代码编写为RequireJS模块,将测试编写Jasmine测试。

这样,可以使用RequireJS在任何地方加载代码,并且可以使用jasmine-html和Node.js中的jasmine-node浏览器中运行测试,而无需修改代码或测试。

这是一个可行的例子

猪猪阿飞2020/03/23 09:26:21

如果您想使用类似Node.js的样式来编写浏览器,可以尝试dualify

没有浏览器代码编译,因此您可以不受限制地编写应用程序。

泡芙西门2020/03/23 09:26:21

now.js也值得一看。它允许您从客户端调用服务器端,并从服务器端调用客户端功能

西门2020/03/23 09:26:21

以前的解决方案都没有将CommonJS模块系统带到浏览器。

正如在其他的答案中提到,有喜欢的资产管理公司/打包解决方案Browserify堆垛机和有像RPC解决方案dnodenowjs

但是我找不到用于浏览器的CommonJS实现(包括require()函数和exports/ module.exports对象等)。所以我写了自己的书,后来才发现有人写的比我写的要好:https : //github.com/weepy/brequire这称为Brequire(浏览器要求的缩写)。

从受欢迎程度来看,资产经理可以满足大多数开发人员的需求。但是,如果您需要CommonJS的浏览器实现,Brequire可能会适合您。

2015年更新:我不再使用Brequire(几年来没有更新)。如果我只是在编写一个小的开放源代码模块,并且希望任何人都可以轻松使用,那么我将遵循类似于Caolan的回答(上图)的模式-我写了一篇关于它的博客文章前。

但是,如果我要编写供私人使用的模块或针对CommonJS标准化的社区(例如,Ampersand社区)编写模块,那么我将以CommonJS格式编写它们并使用Browserify

DavaidTony宝儿2020/03/23 09:26:21

我建议您查看Node.jsRequireJS适配器问题在于Node.js默认使用的CommonJS模块模式不是异步的,这会阻止Web浏览器中的加载。RequireJS使用AMD模式,该模式既异步又与服务器和客户端兼容,只要您使用r.js适配器即可。

乐米亚2020/03/23 09:26:21

不要忘记,JavaScript函数的字符串表示形式代表该函数的源代码。您可以简单地以封装的方式编写函数和构造函数,以便可以将它们传递给toString()并发送给客户端。

另一种方法是使用构建系统,将通用代码放在单独的文件中,然后将它们包括在服务器脚本和客户端脚本中。我通过WebSockets将这种方法用于简单的客户端/服务器游戏,其中服务器和客户端基本上都运行相同的游戏循环,并且客户端每隔一秒便与服务器同步,以确保没有人作弊。

我的游戏构建系统是一个简单的Bash脚本,该脚本通过C预处理程序运行文件,然后通过sed清除后面的垃圾cpp树叶,因此我可以使用所有常规的预处理程序,例如#include,#define,#ifdef等