Meteor文档(请参阅Namespacing部分)说:
当您声明顶级变量时,您可以选择。您可以创建变量File Scope或Package Scope。
// File Scope. This variable will be visible only inside this
// one file. Other files in this app or package won't see it.
var alicePerson = {name: "alice"};
// Package Scope. This variable is visible to every file inside
// of this package or app. The difference is that 'var' is
// omitted.
bobPerson = {name: "bob"};
这真的很好。如果一个包有多个源代码文件,那么这些文件可以共享变量,但可以保留世界其他地方。但是我开始怀疑。
他们到底如何实现包装范围?
起初我以为他们是通过立即调用的函数表达式实现的。你知道像这样的结构:
(function() { /* your code here */ })();
所以我试图在控制台中模拟这种行为。我定义了一个这样的变量:x = "Package scope candidate";
。
我进入了控制台:
(function() {
x = "Package scope candidate";
})();
console.log(x);
我在控制台中获得了"Package scope candidate"
。多么令人失望。变量x
落在全球范围内。在Window
对象中。绝对不是我想要的。和流星?他们以某种方式管理它。他们必须使用一些我不理解的魔法。
答案 0 :(得分:1)
看起来他们重新定义了文件顶部的变量。
例如:
x = "Package scope candidate"
会变成
(function() {
var x;
(function() {
x = "Package scope candidate";
}).call(this);
}).call(this);
有一个解释器可以查找变量并将它们添加到顶部,以便它们成为范围到文件的范围,从而反映了包的范围。
如果你看一下https://github.com/meteor/meteor/blob/devel/tools/linker.js,你可以找到一个名为jsAnalyze的东西,它围绕文件查找全局变量以在文件顶部进行重新扫描。 在将文件提供给客户端之前,它将以上述方式重新打包。
jsAnalyze包会查看https://github.com/meteor/meteor/blob/94c7833c82ac6ab62c36b4a39ee315199233aef9/packages/js-analyze/js_analyze.js
所以提取全局变量&该文件使用全局变量,导入和导出重新构建,这就是它自己的命名空间。