Node.js和客户端共享相同的脚本

12
使用Node.js的理论好处之一是可以在客户端和服务器之间共享相同的脚本,这样如果客户端不支持javascript,也可以将相同的功能降级到服务器端。
但是,Node.js的require()方法是独立的。在加载的脚本中,可以向this或exports添加内容,稍后可以在检索脚本的对象中使用它们。
var stuff = require('stuff');
stuff.show();
在 stuff.js 中:
this.show = function() {
    return 'here is my stuff';
}

所以,在客户端重复使用这个脚本时,.show() 方法将被添加到 window 作用域中。这不是我们想要的,相反地,我们想要将它添加到自定义的命名空间中。

到目前为止,我唯一的解决方案是类似下面这样(在 stuff.js 中):

var ns = typeof exports == 'undefined' ? (function() {
    return window['stuff'] = {};
})() : exports;

ns.show = function() {
    return 'here is my stuff';
}

delete ns; // remove ns from the global scope

这个方案很好用,因为我可以在服务器和客户端上调用stuff.show()。但它看起来有点奇怪。我尝试搜索解决方案,但是node.js对我来说还很新,所以可靠的资源很少。请问有没有更好的解决方法?

1个回答

6
简单来说,如果你想重用脚本,不要使用Node.js特定的东西,你必须使用最低公共分母,即浏览器。
解决方案如下:
  1. 过度使用并使用RequireJS,这将使其在Node.js和浏览器中都能工作。但是您需要在服务器端使用RequireJS格式,并且还需要插入一个“即时转换”脚本...

  2. 编写自己的加载器

    1. 在服务器和客户端两端均用匿名函数包装您的重用脚本
    2. 现在创建一些代码,用户在该函数上调用call(module),在Node端,您将模块传递给this,在客户端,您传递命名空间对象
  3. 保持简单,像现在这样,在Node.js端的模块范围内不要使用this

我希望能够给您提供一个简单的开箱即用的解决方案,但是在这种情况下,两个环境的差异太大了。如果您真的有大量的代码,可以考虑生成文件的构建脚本。

1
你可以编写自己的 require 函数,并将其作为脚本加载到浏览器中,它的工作方式与在 node.js 上完全相同。 - Raynos
5
不太行,"require" 是同步的操作,你需要下载脚本才能执行,这会花费相当长的时间并阻塞其他任务。 - Ivo Wetzel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接