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

我想在客户机和服务器之间共享代码。我才刚刚开始使用Node.js,至少可以说,我对现代JavaScript的知识有点生疏。因此,我仍然对CommonJS的require()函数感到困惑。如果我通过使用“export”对象创建我的包,那么我无法看到我如何在浏览器中使用相同的JavaScript文件。

我想创建一组在两端使用的方法和类,以方便编码和解码消息以及其他镜像任务。然而,Node.js/CommonJS打包系统似乎阻止了我创建可以在双方使用的JavaScript文件。

我还尝试使用JS.Class来获得更紧密的OO模型,但我放弃了,因为我不知道如何让提供的JavaScript文件与require()一起工作。我是不是遗漏了什么?


当前回答

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

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

我的游戏构建系统是一个简单的Bash脚本,它通过C预处理器运行文件,然后通过sed清理cpp留下的一些垃圾,所以我可以使用所有普通的预处理器,如#include, #define, #ifdef等。

其他回答

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

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

下面是一个工作示例。

也许这不完全符合你的问题,但我还是想分享一下。

我想在string上声明几个简单的string实用函数。原型,可用于节点和浏览器。我只是把这些函数保存在一个名为utilities.js的文件中(在子文件夹中),并且可以很容易地从我的浏览器代码中的脚本标记中引用它,并在我的Node.js脚本中使用require(省略.js扩展名):

my_node_script.js

var utilities = require('./static/js/utilities')

my_browser_code.html

<script src="/static/js/utilities.js"></script>

我希望这些信息对别人有用,而不是对我。

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

如果你想写一个既可以在客户端也可以在服务器端使用的模块,我有一个简短的博客文章,关于一个快速而简单的方法:为Node.js和浏览器编写,基本上如下(这与window相同):

(function(exports){

    // Your code goes here

   exports.test = function(){
        return 'hello world'
    };

})(typeof exports === 'undefined'? this['mymodule']={}: exports);

还有一些项目旨在在客户端实现Node.js API,比如Marak的gemini。

您可能还对DNode感兴趣,它允许您公开JavaScript函数,以便使用简单的基于json的网络协议从另一台机器调用它。

我写了这个,如果你想将所有变量设置为全局作用域,使用起来很简单:

(function(vars, global) {
    for (var i in vars) global[i] = vars[i];
})({
    abc: function() {
        ...
    },
    xyz: function() {
        ...
    }
}, typeof exports === "undefined" ? this : exports);