问题
Meteor documentation (see section Namespacing) says:
When you declare a top-level variable, you have a choice. You can make the variable File Scope or 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"};
This is really nice. If a package has more than one source code file, the files can share variables but keep the rest of the world out. However I started wondering.
How the hell do they achieve package scope?
At first I thought they achieved it with immediately invoked function expressions. You know constructs like this:
(function() { /* your code here */ })();
So I tried to emulate this behaviour in the console. I define a variable like this: x = "Package scope candidate";.
I entered in the console:
(function() {
x = "Package scope candidate";
})();
console.log(x);
and I get "Package scope candidate" in the console. How disappointing. The variable x landed in the global scope. In the Window object. Absolutely not what I wanted. And Meteor? They managed it somehow. They must have used some magic I don't understand.
回答1:
It looks like they redefine the variables at the top of the file.
For example:
x = "Package scope candidate"
would become
(function() {
var x;
(function() {
x = "Package scope candidate";
}).call(this);
}).call(this);
There's an interpreter that looks for the variables and adds them in at the top so that they become scoped to the file, which in turn reflects the packages scope.
If you look at https://github.com/meteor/meteor/blob/devel/tools/linker.js you can find something called jsAnalyze that looks around the file for global variables to rescope at the top of the file. Before the file is served to the client it is repackaged in a way like above.
The jsAnalyze package does this have a look at https://github.com/meteor/meteor/blob/94c7833c82ac6ab62c36b4a39ee315199233aef9/packages/js-analyze/js_analyze.js
So the globals are extracted & the file is restructured with the globals, imports, and exports and this is how its namespaced off on its own.
来源:https://stackoverflow.com/questions/20791621/how-is-package-scope-achieved