Mamy dość dużą bazę kodów JavaScript i około miesiąca temu postanowiliśmy wypróbować CoffeeScript. Jeden z naszych programistów rozpoczął migrację jednego z naszych modułów z JS do CS przy użyciu http://js2coffee.org/ . To narzędzie było raczej przydatne i zajęło około dwóch lub trzech godzin przeniesienie 1000-wierszowych wierszy JavaScript. Kilka spostrzeżeń, które zauważyliśmy w tym momencie:
Wynikowy kod CoffeeScript był dość czytelny.
Skompilowaliśmy go z powrotem do JavaScript i było dość łatwe w nawigacji i debugowaniu. Podczas przenoszenia tego modułu inny programista z naszego zespołu znalazł w nim błąd. Ci dwaj programiści naprawili ten błąd w naszym starym kodzie JavaScript i nowym kodzie JavaScript, który wyszedł z kompilatora CS. Pracowali niezależnie i zajęło im to tyle samo czasu (15-20 minut).
Ze względu na fakt, że był to port, wynikowy kod nie korzystał z funkcji specyficznych dla kawy, które były odpowiednie lub pożądane. Gdybyśmy pisali w CoffeeScript od zera, kod byłby bardziej idiomatyczny. Z tego powodu zdecydowaliśmy później, że nie przeniesiemy istniejącego kodu.
Ogólnie zwiększono do pewnego stopnia czytelność krótszej funkcji i mniejszego obiektu. Jednak w przypadku dłuższych metod wcale tak nie było. Największe oszczędności na wzdęciach pochodzą ->
i są wyraźne return
, ale poza tym nasz kod nie był znacznie krótszy ani prostszy. Niektóre elementy składni wydawały się dość mylące, zwłaszcza literały obiektowe. CS pomija nawiasy klamrowe wokół definicji elementów i łączy się z „wszystko-jest-wyrażeniem” i niejawnym, return
co sprawia, że niektóre fragmenty kodu są dość trudne do odczytania.
Oto JavaScript:
var rabbitGenerator = {
makeRabbit: function(rabbitName, growCarrots) {
if (growCarrots) {
carrots.growMore(10);
} else {
carrots.ensureSupply();
}
return {
name: rabbitName,
height: 0,
actions: {
jump: function (height) {
this.height += height;
},
eatCarrot: function () {
// etc
}
}
};
},
// more members
}
Oto, jak wyglądałby odpowiedni kod CoffeeScript:
rabbitGenerator =
makeRabbit: (rabbitName, growCarrots) ->
if growCarrots
carrots.growMore 10
else
carrots.ensureSupply()
name: rabbitName // (*)
height: 0
actions:
jump: (height) ->
@height += height
eatCarrot: ->
W tej chwili dość trudno jest stwierdzić, że instrukcja return zaczyna się od (*)
wiersza. W naszym projekcie mocno polegamy na literałach obiektów: przekazujemy je jako parametry funkcji i zwracamy z innych funkcji. W wielu przypadkach obiekty te bywają dość złożone: z elementami różnych typów i kilkoma poziomami zagnieżdżenia. W naszym przypadku ogólne wrażenie było takie, że kod CoffeeScript był trudniejszy do odczytania niż zwykły kod JavaScript.
Chociaż debugowanie CoffeeScript okazało się łatwiejsze, niż się spodziewaliśmy, doświadczenie edycji znacznie się pogorszyło. Nie mogliśmy znaleźć dobrego edytora / IDE dla tego języka. Nie znormalizowaliśmy edytora / IDE dla kodu po stronie klienta dla naszego projektu i w rzeczywistości wszyscy używamy różnych narzędzi. W rzeczywistości wszyscy w zespole zgadzają się, że po przejściu na CoffeeScript otrzymują raczej słabe wsparcie ze strony swojego narzędzia. Wtyczki IDE i edytora są w bardzo wczesnej formie, a w niektórych przypadkach nie mogą nawet zapewnić właściwego podświetlania składni lub obsługi wcięć. Nie mówię o fragmentach kodu ani refaktoryzacji. Używamy WebStorm, Eclipse, NetBeans, VisualStudio, Notepad ++ i SublimeText2.
Mówiąc o narzędziach, powinienem wspomnieć, że sam kompilator CoffeScript jest pakietem Node JS. Jesteśmy głównym sklepem Java / .NET, więc wszyscy rozwijają się na Windowsach. Do niedawna obsługa systemu Windows prawie nie istniała w węźle. Nie mogliśmy uruchomić kompilatora CoffeeScript w systemie Windows, więc na razie postanowiliśmy pozostać przy <script type="text/coffeescript">
tagach i kompilatorze działającym w trybie przeglądarki.
Kompilator jest dość szybki i nie wydłuża znacznie czasu uruchamiania. Minusem jest to, że powstały JavaScript jest eval
edytowany i trochę trudno jest umieścić w nim punkty przerwania w narzędziach programistycznych przeglądarek (szczególnie w IE8). Jeśli mamy trudności z debugowaniem, kompilujemy kod CoffeeScript za pomocą tego samego narzędzia do migracji, które wymieniłem powyżej, ale nadal nie jest to zbyt wygodne.
Inne obietnice związane z CoffeeScript, takie jak automatyczne var
wstawianie lub półprzezroczyste zarządzanie za this
pomocą operatora fat arrow ( =>
) okazały się nie dawać tak dużego zysku, jak się spodziewaliśmy. Już teraz używamy JSLint jako części naszego procesu kompilacji i piszemy kod w ES3 x ES5-Strict
podzbiorze języka. W każdym razie fakt, że Kawa wytwarza ten sam „czysty” kod, jest dobrą rzeczą . Chciałbym, aby każda platforma po stronie serwera produkowała również prawidłowe znaczniki HTML5 i CSS3!
To powiedziawszy nie powiedziałbym, że CoffeeScript oszczędza dużo czasu, umieszczając var
dla mnie słowa kluczowe. Brakujące elementy var
są łatwo wychwytywane przez JSLint i można je łatwo naprawić. Co więcej, po poprawieniu przez jakiś czas i tak zaczynasz pisać dobry JavaScript . Tak więc nie powiedziałbym Kawa jest naprawdę , że pomocne w tym względzie.
Ocenialiśmy CoffeeScript przez około tydzień. Wszyscy członkowie zespołu pisali w nim kod i dzieliliśmy się naszymi doświadczeniami. Napisaliśmy z nim nowy kod i przenieśliśmy istniejący kod, gdy uznaliśmy to za stosowne. Nasze odczucia dotyczące języka były mieszane.
Ogólnie powiedziałbym, że nie przyspieszyło to naszego rozwoju, ale też nas nie spowolniło. Niektóre przyrosty prędkości spowodowane mniejszym pisaniem i mniejszą powierzchnią błędu zostały zrównoważone przez spowolnienia w innych obszarach, głównie w obsłudze narzędzi. Po tygodniu zdecydowaliśmy, że nie będziemy wymagać używania CoffeeScript, ale nie zabraniamy go również . Biorąc pod uwagę wolny wybór, w praktyce nikt go nie używa, przynajmniej na razie. Od czasu do czasu myślę o prototypowaniu jakiejś nowej funkcji, a następnie przekonwertowaniu kodu na JavaScript przed integracją z resztą projektu, aby uzyskać szybszy start, ale jeszcze tego nie próbowałem.