Разделих кода си на няколко файла и след това стартирах скрипт, за да ги обединя и компилирам (с 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, че е добре да обединявам всички тези в един обектен литерал и дори ако има код между тях (в този пример има t, но може да има), така че независимо от всичко, всичко това се компилира в един голям обектен литерал?
Ето няколко решения и защо те няма да работят за мен:
- Решение 1: Просто ги декларирайте в един голям обектен литерал.
Няма да работи, защото имам кода си в няколко файла и планирам да го направя така, че потребителите могат да премахнат някои от тях (ако не им трябват) преди компилация. Обектните литерали имат разделители със запетая, които биха превърнали това в кошмар. - Решение 2: Декларирайте цялата функционалност извън обекта (като частни променливи в затварянето) и ги прикачете в опростен обектен литерал в края, който има само препратки към свойства (като
{'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 (пропорционално на неговия размер).
Редактиране 3: Доклад за грешка в Closure Compiler.
ADVANCED_OPTIMIZATIONS
. Това, което имам предвид, е, че вече направи много други много по-сложни неща, които потенциално биха могли да нарушат моите javascripts сериозно (и понякога го направиха, за щастие имам модулни тестове, за да знам кога това се случва). Освен това има случай в моя код, когато Closure компилаторът ПРАВИ точно това! Ще редактирам с пример. - person Camilo Martin   schedule 30.09.2012WHITESPACE_ONLY
(супер безопасно), другият правиSIMPLE_OPTIMIZATIONS
(нещо, което трябва да е безопасно в 99% от случаите, помислете за YUI компилатор), а това, което харесвам, е, когато правиADVANCED_OPTIMIZATIONS
, с други думи, има високо има вероятност да разбие кода ви, освен ако не сте много внимателни, но от друга страна, кодът работи по-бързо и е много по-малък от това, което може да направи вашият градински минификатор. - person Camilo Martin   schedule 30.09.2012767,727 ±8.03% 61% slower
означава, че определен фрагмент работи с около 767 727 операции в секунда, в рамките на 8% допустима грешка и е 61% по-бавен от най-бързия фрагмент. - person Camilo Martin   schedule 01.10.2012