问题
For example:
// a.js
goog.provide('mypackage.a');
goog.provide('mypackage.commands');
mypackage.a.somevar = 1;
mypackage.commands.save = function(...) {...};
// b.js
goog.provide('mypackage.b');
goog.provide('mypackage.commands');
mypackage.b.somevar = 1;
mypackage.commands.read = function(...) {...};
// mypackage/commands.js
goog.provide('mypackage.commands');
mypackage.commands.runCommand = function(commandText, args) {
return mypackage.commands[commandText](args);
}
Is this a good way to provide an extensible set of commands, or is there something that could make this complex that I'm not thinking about?
回答1:
There is no reason that you can't or shouldn't provide the same module in different source files. If it makes sense to your source code organization scheme, then it's a perfectly fine thing to do. One of the main reasons that we have goog.provide()
is so that the same symbol can be used in several different places, but defined in whichever file happens to run first.
If I understand goog.provide()
correctly, all it does is make sure that an object is declared. So, goog.provide('mypackage.commands) makes sure that
mypackage.commands` is declared in the global scope.
So goog.provide('mypackage.commands');
just accomplishes something similar to this:
window.mypackage = window.mypackage || {};
window.mypackage.commands = window.mypackage.commands || {};
You only need to do that when you plan on adding things to that object in this source file. So, if multiple source files are all adding new items onto mypackage.commands
, then each source file would do goog.provide('mypackage.commands
)` to make sure that the right global variable structure is declared.
That appears to be what you are doing in your code example and that is a perfectly fine thing to do. It is up to your own sense of code organization whether it's better to have multiple source files all contributing to the same object (like you have) or whether you should organize your source files such that all code pertaining to one particular namespace is in the same file. That's really up to you and how you think it is best to organize your source code - there is no right or wrong answer other than there should be some rhyme and reason behind how it's organized.
Helpful reference article: https://developers.google.com/closure/library/docs/tutorial
回答2:
Using goog.provide()
to define the same namespace in multiple files will not overwrite the namespace, since each level of the namespace is checked for existence from left to right. However, the Closure Library follows the convention that each namespace is provided in only one file.
From Closure: The Definitive Guide page 49:
Every JavaScript file in the Closure Library starts with at least one call to
goog.provide().
All elements added to the namespace being provided are added in that file. Like Java, files live in a directory structure that parallels the namespace, though this is not required for Closure as it is for Java. This convention does make it easier to find the file responsible for a given namespace, however. It is recommended that you follow this convention in your own JavaScript projects that use Closure.
In addition, when using Closure Builder to manage dependencies, the following error is generated when the same namespace is provided by multiple files.
depstree.MultipleProvideError: Namespace "your.namespace" provided more than once in sources
However, if you still want to provide the same namespace in multiple files, you can manage dependencies using the Closure Compiler flag --only_closure_dependencies
without error.
来源:https://stackoverflow.com/questions/12118427/is-there-any-reason-not-to-provide-the-same-module-in-different-source-files