Temos uma grande base de código JavaScript e, cerca de um mês atrás, decidimos experimentar o CoffeeScript. Um de nossos desenvolvedores começou a migrar um de nossos módulos de JS para CS usando http://js2coffee.org/ . Essa ferramenta foi bastante útil e demorou cerca de duas ou três horas para portar uma linha de algo mais do que 1000. Algumas observações que observamos naquele momento:
O código CoffeeScript resultante era bastante legível.
Nós o compilamos de volta ao JavaScript e foi muito fácil navegar e depurar. Enquanto estávamos portando esse módulo, outro desenvolvedor da nossa equipe encontrou um bug nele. Esses dois desenvolvedores corrigiram esse bug em nosso antigo código JavaScript e no novo código JavaScript que saiu do compilador CS. Eles trabalharam independentemente e levaram a mesma quantidade de tempo (15 a 20 minutos).
Devido ao fato de ser uma porta, o código resultante não estava usando recursos específicos do café que eram apropriados ou desejáveis. Se escrevermos no CoffeeScript do zero, o código seria mais idiomático. Por causa disso, decidimos que não portaríamos o código existente.
Em geral, a legibilidade de funções mais curtas e objetos menores aumentou até certo ponto. No entanto, para métodos mais longos, esse não era o caso. As maiores economias surgiram ->
e foram explícitas return
, mas, além disso, nosso código não havia sido significativamente mais curto ou mais simples. Algumas partes da sintaxe pareciam bastante confusas, especialmente literais de objetos. O CS omite chaves entre definições de membros e combinado com "tudo é uma expressão" e implícito, o return
que dificultava a leitura de alguns bits de código.
Aqui está o 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
}
E aqui está a aparência do código CoffeeScript correspondente:
rabbitGenerator =
makeRabbit: (rabbitName, growCarrots) ->
if growCarrots
carrots.growMore 10
else
carrots.ensureSupply()
name: rabbitName // (*)
height: 0
actions:
jump: (height) ->
@height += height
eatCarrot: ->
Agora, é muito difícil descobrir que a declaração de retorno começa na (*)
linha. Em nosso projeto, dependemos muito de literais de objetos: passamos como parâmetros de função e os retornamos de outras funções. Em muitos casos, esses objetos tendem a ser bastante complexos: com membros de diferentes tipos e vários níveis de aninhamento. No nosso caso, a sensação geral era de que o código CoffeeScript era realmente mais difícil de ler do que o código JavaScript comum.
Embora a depuração do CoffeeScript tenha sido mais fácil do que esperávamos, a experiência de edição diminuiu bastante. Não foi possível encontrar um bom editor / IDE para este idioma. Não padronizamos no editor / IDE o código do lado do cliente para o nosso projeto e, de fato, todos usamos ferramentas diferentes. De fato, todos os membros de uma equipe concordam que, quando mudam para o CoffeeScript, recebem um suporte bastante ruim de sua ferramenta. Os plug-ins de editor e IDE estão em uma forma muito precoce e, em alguns casos, eles nem sequer podem nos dar um suporte apropriado para realçar ou recuar na sintaxe. Não estamos falando de trechos de código ou refatoração. Usamos WebStorm, Eclipse, NetBeans, VisualStudio, Notepad ++ e SublimeText2.
Falando em ferramentas, devo mencionar que o próprio compilador CoffeScript vem como um pacote Node JS. Como somos uma loja Java / .NET principal, todos estão desenvolvendo caixas do Windows. Até recentemente, o suporte do Windows era quase inexistente no Node. Não conseguimos fazer com que o compilador CoffeeScript fosse executado no Windows; por enquanto, decidimos manter as <script type="text/coffeescript">
tags e o compilador em tempo real baseado no navegador.
O compilador é bastante rápido e não aumenta muito o tempo de inicialização. A desvantagem é que o JavaScript resultante é eval
editado e é um pouco difícil colocar pontos de interrupção nas ferramentas de desenvolvedor de navegadores (especialmente no IE8). Se tivermos dificuldade com a depuração, pré-compilamos o código CoffeeScript com a mesma ferramenta de migração listada acima, mas isso ainda não é muito conveniente.
Outras promessas do CoffeeScript, como var
inserção automática ou gerenciamento semitransparente do this
operador de seta gorda ( =>
), não deram tanto ganho quanto esperávamos. Já usamos JSLint como parte do nosso processo de construção e escrevemos código no ES3 x ES5-Strict
subconjunto da linguagem. De qualquer forma, o fato de o Coffee produzir o mesmo tipo de código "limpo" é uma coisa boa . Desejo que todas as estruturas do lado do servidor também produzam marcações HTML5 e CSS3 válidas!
Dito isto, eu não diria que o CoffeeScript economiza muito tempo colocando var
palavras-chave para mim. Os var
s ausentes são facilmente capturados pelo JSLint e são facilmente corrigíveis. Além disso, depois de corrigido por algum tempo, você começa a escrever um bom JavaScript automaticamente de qualquer maneira. Assim, eu não diria que o café é realmente que útil a este respeito.
Avaliamos o CoffeeScript por cerca de uma semana. Todos os membros da equipe estavam escrevendo um código e compartilhamos nossas experiências. Escrevemos um novo código com ele e portamos um código existente quando acharmos melhor. Nossos sentimentos sobre o idioma foram confusos.
Em geral, eu diria que isso não acelerou nosso desenvolvimento, mas também não nos atrasou. Alguns ganhos de velocidade devido à menor digitação e menos superfície de erro foram compensados por desacelerações em outras áreas, principalmente no suporte a ferramentas. Depois de uma semana , decidimos que não exigiríamos o uso do CoffeeScript, mas também não o proibiríamos . Dada a livre escolha, na prática ninguém a usa, pelo menos por enquanto. De tempos em tempos, penso em criar um novo recurso para a criação de protótipos e depois converter o código em JavaScript antes de integrar-se ao restante do projeto para obter um início mais rápido, mas ainda não tentei essa abordagem.