我将代码分成几个文件,然后运行一个脚本来合并和编译它们(使用ADVANCED_OPTIMIZATIONS
)。功能的很大一部分是在单个对象的原型中实现的。
因此,当合并时,它看起来像这样:
(function(){
/** @constructor */ function MyConstructor() {};
MyConstructor.prototype = {};
MyConstructor.prototype['foo'] = function() { alert('foo'); };
MyConstructor.prototype['bar'] = function() { alert('bar'); };
MyConstructor.prototype['baz'] = function() { alert('baz'); };
window['MyConstructor'] = MyConstructor;
}());
如果您将该代码放入Closure Compiler,就像那样,这是输出(漂亮打印):
function a() {
}
a.prototype = {};
a.prototype.foo = function() {
alert("foo")
};
a.prototype.bar = function() {
alert("bar")
};
a.prototype.baz = function() {
alert("baz")
};
window.MyConstructor = a;
问题是,是否有某种方式我可以告诉Closure Compiler可以在单个对象文字中合并所有这些,即使中间有代码(在此示例中)没有,但可能有),所以无论如何,它都将它编译成一个大对象文字?
以下是一些解决方案,以及为什么它们不适合我:
{'foo':foo,'bar':bar,'baz':baz}
)。我愿意接受想法!
编辑:有些人可能会认为Closure Compiler无法做到这一点。它可以做到这一点以及更多,只是它有一种不好的态度,并在感觉就好的时候做事。
将此输入Closure:
(function(){
var MyConstructor = window['MyConstructor'] = function() {};
var myProto = {
'foo': function() { alert('foo'); },
'bar': function() { alert('bar'); }
};
myProto['baz'] = function() { alert('baz'); };
MyConstructor.prototype = myProto;
}());
结果是:
(window.MyConstructor = function() {
}).prototype = {foo:function() {
alert("foo")
}, bar:function() {
alert("bar")
}, baz:function() {
alert("baz")
}};
请参阅?但是,这是代码非常脆弱,如果稍微修改它可能编译成完全不同的东西(而不是那么好)。例如,即使在中间某处的变量赋值也可能导致它输出非常不同的结果。换句话说,这不起作用(在这种情况下除外)。
修改2 :请参阅此jsperf。 Chrome中的大对象字面值更快(与其大小成比例)。
答案 0 :(得分:0)
我正在做一个解决方法。它可能不适用,所以不能接受这个答案。不过,这就是我的情况。
我的文件夹结构如下所示:
src
├───components
└───core
并且,在编译之前,我合并src/intro.js
,src
级别的某些文件(按特定顺序),然后合并core
中的所有文件(任何顺序),然后全部在components
(任何顺序),然后是outro.js
。
现在,文件夹结构如下所示:
src
├───components
│ ├───modules
│ └───plugs-literal
└───core
├───internal
├───modules
└───plugs-literal
编译顺序是(注意箭头部分):
src/intro.js
src/core
中的几个文件,具体顺序。src/core/internal
src/core/plugs-literal-intro.js
< - src/core/plugs-literal
< - src/components/plugs-literal
< - src/core/plugs-literal-outro.js
< - src/core/modules
src/components/modules
src/outro.js
这个想法是一个文件包含一个对象文字的开头,另一个文件包含一个对象文字,两个文件夹包含属性。或多或少是这样的:
src/core/plugs-literal-intro.js
var myObjectLiteral = {
'someSimpleProp': 'foo',
'someOtherSimpleProp': 'bar',
'lastOneWithoutTrailingComma': 'baz'
src/core/plugs-literal/EXAMPLE.js
,'example': function() { alert('example'); } // comma before, not after.
src/core/plugs-literal-outro.js
};
如果这引入了一些不必要的问题,我稍后会知道。但是,我可以指定一个不同的文件夹来包含单独声明的原型属性。