ove*_*nd1 3 javascript google-closure-library
我的新工作是使用Google Closure库编写面向组件的JavaScript.我喜欢活动,组件,服务和模块.但由于需要编写混乱使用命名空间的代码,因此工作非常苛刻.以下代码是典型的:
goog.provide(com.bin.slash.dot.closure.widget.SuperForm);
goog.require(com.bin.slash.dot.closure.widget.Avatar);
// ... ten require calls more...
com.bin.slash.dot.closure.widget.SuperForm = function() {
goog.base(this);
this._internal = new com.bin.slash.dot.closure.widget.Avatar(
com.bin.slash.dot.closure.widget.Avatar.SRC_PATH);
};
Run Code Online (Sandbox Code Playgroud)
我无法相信这是真的.我并不害怕输入所有这些,但我只是觉得逻辑在这个符号地狱中消失了.扫描非常困难,因此需要更多时间来了解正在发生的事情.我的老板说,不鼓励写下以下快捷方式:
var SF = com.bin.slash.dot.closure.widget.SuperForm = function(){};
Run Code Online (Sandbox Code Playgroud)
因为所有这些都将在编译后绑定到全局命名空间(窗口),因此它们可能会干扰其他内容.
问题是如何避免这个符号地狱?
更新:我改进了我的开发人员流程,解决了地狱的问题.现在我编写了甜蜜的JavaScript,然后由Grunt使用sweet.js宏自动编译:
// For each file I define three macros which are replaced
// in the compile time with hell of a long paths.
macro dir { rule { $x } => { my.very.very.long.namespace $x } }
macro class { rule { $x } => { dir.NameOfMyClass $x } }
macro proto { rule { $x } => { class.prototype $x } }
dir.NameOfMyClass = function() {}; // yields: my.very.very.long.namespaceNameOfMyClass = function() {};
class.CONSTANT = "I don't know why we write constants into classes, not prototypes"; // yields: my.very.very.long.namespaceNameOfMyClass.CONSTANT = ...;
proto.method1 = function() {}; // yields my.very.very.long.namespaceNameOfMyClass.prototype.method1 = function(){};
Run Code Online (Sandbox Code Playgroud)
宏编译器创建的所有噪声都被优秀的shelljs删除.
假设您正在使用Closure Compiler,请考虑goog.scope.有内置的编译器支持,可在优化之前替换别名变量:
goog.scope - 来自Closure Library wiki的设计文档goog.scopegoog.scopegoog.provide和goog.require语法没有改变;考虑到上述指南,您的代码示例可能看起来像这样:
goog.provide('my.very.long.namespace.NameOfMyClass');
goog.require('my.very.long.namespace');
/** @constructor */
my.very.long.namespace.NameOfMyClass = function() { /*...*/ };
goog.scope(function() {
var _ = my.very.long.namespace.NameOfMyClass;
_.CONSTANT = 'I don\'t know why we write constants into classes, not prototypes';
_.prototype.method1 = function() {};
}); // goog.scope
Run Code Online (Sandbox Code Playgroud)
由于我没有足够的声誉来添加评论:
我的老板说,不鼓励写下以下快捷方式:
Run Code Online (Sandbox Code Playgroud)var SF = com.bin.slash.dot.closure.widget.SuperForm = function(){};因为所有这些都将在编译后绑定到全局命名空间(窗口),因此它们可能会干扰其他内容.
即使没有这些快捷方式,高级编译也可以重命名符号,例如SF或 myVariable简单ga.这可能会导致与Google Analytics等外部代码发生冲突.
Closure支持的防止全局范围内此类冲突的方法是在编译后引入一个立即调用的函数表达式(源代码).使用编译器标志:--output_wrapper "(function(){%output%})();"或符合严格模式的变体:--output_wrapper "(function(){%output%}).call(this);".使用时,老板不鼓励的快捷方式可以避免与外部符号发生冲突.