Node.js - 如何配置Node.js将函数加载到全局作用域?

3
在以前的某个时候,我曾经看到过有人可以配置Node.js以在全局范围内执行已加载的模块,但是现在我找不到如何做到这一点。
为什么我会问这个问题呢?
我有一些定义语言实用程序的旧文件,我希望在服务器和客户端上都使用它们,然而其中许多实用程序都被定义为全局作用域函数。 例如,我有像closure(fClosure)module(fModule)之类的函数,还有像$sb(arg,arg,arg)这样的实用程序,它是一个字符串构建器等等。
现在这些实用程序被定义在一个名为core.js的文件中,并且这个文件作为第一个依赖项加载到浏览器中,生活很美好。
但是,在根目录中需要这个文件可以帮助扩展Array.prototype,但是在其他模块中定义的函数是不可见的。 (请避免讨论污染或与其他库冲突的问题)
我知道这不符合CommonJS规范...但现在我只是想利用这些旧代码,而不重新组织所有代码以符合CommonJS的方式。
我也发现了RequireJS和其提出的美丽的AMD模型,但它只回答了有关如何在浏览器中运行编写为node.js的代码,而不是反之。
将其分配给全局变量将不起作用,因为这意味着我必须重写所有旧库。 我正在寻找一种方法使它们在全局范围内运行并留下它们声明的所有内容,而无需重新编写它们。
那么,有没有一种方法可以要求Node要求一个文件并在全局范围内运行它?

1
嗨!我也遇到了同样的问题。我真的不想重写那些大量的旧代码。你找到解决方案了吗? - vogdb
1
没有完美的解决方案。我们所做的是:1. 声明所有全局变量时不使用 var,2. 将所有函数声明为 v = function(){},并以老派方式解决 Web 代码和 Node 代码之间的冲突... :P - Radagast the Brown
另外,我为将来的观众添加一点提示,你可以查看require的源代码。如果我理解正确且它是require的正确源代码,那么这个问题显然没有明确的解决方案。 - vogdb
我恐怕这是故意的,经过设计... - Radagast the Brown
2个回答

10

您可以将某物指定给global对象,对于Node来说,这就像浏览器中的window一样,例如:

test.js

global.my_var = require('./my_module');

require('./display_my_var');

我的模块

module.exports = "this is a string";

display_my_var.js

console.log(my_var); // this will work, as my_var is now global

给全局变量赋值是行不通的,因为这意味着我必须重写所有遗留库。我正在寻找一种方法,在全局范围内运行它们并将其声明的内容保留在那里,而不必重写它们。 - Radagast the Brown
1
我认为这是不可能的。此外,避免在全局范围内分配变量。最好的做法是将所需的内容包含在函数参数中。 - alessioalex

2

我们做了什么

正如上面所述,本案例本来就不太健康,因此这个答案并不是一个好的示例。

我们需要对代码进行最小量的更改,具体如下。可以从中学到一些东西。

1- 重构所有传统网络代码,将全局变量声明为没有 var 的。

之前的代码:

var MyUtils = { ... };

window.some = value;

之后:

MyUtils = { ... };

some = "value";

2 - 将所有全局函数声明为已分配的全局变量

之前:

function foo() { ... }

之后:

foo = function() { ... }

3 - 解决遗留代码和新节点代码之间的冲突

这个问题是私人的,所以没有相关片段。但以下是其他内容的片段:

  • 向全局类的原型添加属性。如果你在任何一方面这样做了,那么两者现在都应该与其共存。愚蠢的例子-add()-像push一样,但返回数组

    Array.prototype.add = function(s){ this.push.apply(this, arguments); return this }

  • 缩小文件大小-我们不得不解决一个无法缩小文件大小的地方-只需找到一种不同的方式将其放入代码中,并关闭它。

  • 单元测试-每个此类全局变量都应该存在并从全局范围污染检查中排除。一旦有了完整的列表-我们再次启动(现在它也更好地记录了:))

还值得一提的是

在搜索过程中,我们遇到了一些很酷的沙盒实用程序。 沙盒化意味着在沙盒上下文中运行代码。这应该防止它进入其他范围。 这个实现各不相同。 我最欣赏的是这个:https://github.com/hflw/node-sandbox

它通过在子进程中运行“脏”代码,并帮助您连接任何“纯”代码和“脏遗留代码”之间的通信来工作。

结果是完全的分离。例如-子进程的Array.prototype不是父级的Array.prototype-每个人都可以根据自己的“犯罪”操作进行扩充...

就像我说的-我们从未绝望到如此需要它,因为节点代码是纯净的,并且不使用内置类型的任何“扩展”-它们不介意来自旧客户端代码的扩展。 但老实说-一旦代码混合在一起-团队中的每个人都开始使用来自客户端代码的扩展,这变得混乱。


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