An Introduction to JavaScript ES6 Arrow Functions

Fat arrow functions, also known as just arrow functions are a brand new feature in ECMAScript 2015 (formerly ES6). Rumor has it that the => syntax was adopted over -> due to CoffeeScript influence and the similarity of sharing this context.

Arrow functions serve two main purposes: more concise syntax and sharing lexical this with the parent scope. Let’s examine each in detail.

Read more

Boas práticas para fazer deploy de aplicações Node.js em produção

Um das lutas que os desenvolvedores enfrentam quando migram para o Node.js é a carência de boas práticas para a automatização do deploy. Os desafios são muitas vezes a geração de pacotes, o gerenciamento de dependência, uma única etapa para fazer o deploy, e a inicialização/reinicialização sem deixar a casa cair!

Apesar das boas práticas de deploy começarem no desenvolvimento, ferramenta de apoio para essas práticas ainda são ruins e ficam piores quando se distanciam ainda mais das estações de trabalho do desenvolvedor. Os clientes da StrongLoop regularmente pedem recomendações de como fazer deploy, e até agora não existe uma boa resposta quando se trata de ferramenta com suporte a fluxos de trabalho.
Boas práticas para fazer deploy de aplicações Node.js em produção
Existem algumas ferramentas por aí, mas muitas vezes não são combináveis, são incompletas, ou apenas não concordamos como que as coisas são feitas. Neste blog, falarei sobre quais problemas resolver com essas ferramentas, o porquê de algumas soluções não funcionarem bem e a ferramenta modular que a StrongLoop está criando. Em particular, já foi lançado o strong-build para empacotar a aplicação para o deploy e o strong-deploy para fazer o push dos pacotes da aplicação para o strong-pm, que é o gerenciador de processo que vai gerenciar a aplicação após o deploy.

Tudo empacotado no slc, um controlador via linha de comando da StrongLoop que une todas as ferramentas.

Construa as dependências nos pacotes de deploy

Mas por que? O package.json já descreve as dependências da aplicação, certo? Sim, mas apesar de ser perfeito para usar em branch de desenvolvimento, isso não deve ser usado na hora do deploy.

Caso não esteja bem protegido, cada execução do npm install pode baixar diferentes versões. Você pode até se auto proteger com um servidor próprio, mas mesmo com essa proteção, o npm install sempre baixa as dependências na hora do deploy. Caso o seu servidor npm, ou npmjs.org estiver inacessível, não será possível o deploy. O que não é nem um pouco aceitável.

Você pode agrupar as dependências, mas manter as especificações atualizadas no package.json é manual, e quando algo der errado, você nem vai perceber. Enquanto o npmjs.org estiver inacessível, não será possível fazer o deploy. Então, é preciso automatizar o build. Então é preciso escrever as próprias ferramentas descrita acima, o que não é complexo e ainda dar pra encontrar algumas ferramentas existentes como o bundle-deps (a exceção é que não suporta dependências opcionais), ou então utilizar o slc build.

O empacotamento de dependências é apenas uma parte da história para muitas aplicações Node. Apesar do Javascript não precisar de compilação, muitas aplicações ainda precisam ser buildadas. As dependências do front-end provavelmente serão baixadas (usando o bower, por exemplo), o que também não deveria acontecer na hora do deploy. O javascript talvez precisa ser minificado, e outros arquivos de assets devem ser baixados ou gerados. E toda esta saída do build deve fazer parte do deploy. Isto não é tão trivial, porque o npm não sabe o que deve incluir em um pacote. Ele geralmente usa o .gitignore para evitar colocar arquivos desnecessários… então você vai ter que manter ou gerar um arquivo .npmignore. O slc build pode ajudar com isto, também.

E por último, mesmo que utilize um pacote npm como artefato de deploy, isso funciona bem para alguns fluxos de trabalho, particularmente quando o pacote é arquivado em algo como Artifactory, o qual prefere um pacote de arquivo único, muitos outros fluxos de trabalho dão preferência ao git para arquivar os builds. O uso do git pode mesmo ser necessário, se estiver usando uma plataforma como o Heroku ou OpenShift.

A idéia de commitar as dependências provocou uma enorme discussão, centrada principalmente em torno dos prós (o uso de uma ferramenta com excelente suporte para o arquivamento de versões, rollback, etc.) e dos contras (mudanças bruscas no repositório, a grande quantidade de commits, a inflexibilidade, etc.). O debate é lamentável, porque pressume que você deve escolher entre commitar ou não as dependências, e muitas pessoas que são a favor sugerem o commit das dependências na branch de desenvolvimento. Isto é completamente desnecessário. O slc build irá commitar as dependências e o código fonte na branch de deploy, não nas branches de seu desenvolvimento ou produção. Isto fará com que, em ambas as branches, as dependências sejam instaladas via npm, e fará o mesmo com as ferramentas de customização do build (como por exemplo o bower, grunt ou gulp), e não irá commitar os binários que foram compilados de complementos (a menos que seja solicitado).

Experimente… há um bom número de opções úteis de customização, mas apenas o básico oferece suporte a maioria dos fluxos de trabalho:

Seja capaz de fazer o push dos deploys

O push dos deploys é feito quando você decide que uma nova versão é deployável, ou provavelmente o push é feito automaticamente para o staging pelas ferramentas de CI.

Você deve fazer somente o push das aplicações pré-buildadas para o deploy e para o staging, mas servidores alfa podem ter push de aplicações não buildadas, para testes contínuos com as dependências mais recente.

Você pode fazer o push nas branches do git ou nos pacotes npm, o que for o mais apropriado para o seu fluxo de trabalho.

O slc deploy faz tudo que foi descrito acima, com o push da aplicação para o gerenciador de processo da StrongLoop. Se estiver usando o git, ele pode também fazer o push para plataformas 3rdparty, embora neste caso é apenas um wrapper ao redor de git push remote deploy:master.

Faça o deploy e execute a aplicação dentro de um gerenciador de aplicações

Ao executar uma aplicação em deploy (o contrário da execução em desenvolvimento), há uma série de características desejáveis: reinicialização em caso de falha, registro de log, iniciar/parar/reiniciar (seja em modo hard ou soft), deploy de novas versões com atualização zero-downtime, clusterização, monitoramento de profiling e de desempenho, etc. Você pode configurar todos esses recursos, incluindo a opção de desabilitá-los durante o desenvolvimento, já que esses recursos costumam deixar o desenvolvimento mais difícil. Você pode fazer toda essa configuração novamente para cada aplicação nova… ou usar um supervisor/gerenciador.

Existem vários aplicativos para supervisionar aplicações Node, facilmente dar para encontrar uma dúzia no npmjs.org, alguns são tão pequenos que dar até para colar em um post de blog. Todos têm uma tendência de virar um dissipador de recursos e às vezes até forçam as aplicações a serem escritas de tal forma que só podem ser executado dentro de um supervisor específico.

Nossa solução é centrar na modularidade e utilidade. Os principais recursos são implementados sempre que possível nos módulos autônomos (o strong-cluster-control é o nosso módulo utilitário para cluster, o strong-agent é o nosso módulo para monitoramento e profiling, o strong-supervisor supervisiona uma única aplicação, etc.).

Esses recursos são utilizados para compor o gerenciador de processo da StrongLoop, que pode ser usado para iniciar uma aplicação na sua estação de trabalho com um simples slc start. Uma vez inicializado, você pode interagir com a aplicação através da linha de comando (slc ctl) ou através de uma interface gráfica (slc arc), criar um profile, dentre várias outras possibilidades, experimente os recursos da Strongloop.

Quando se trata de deploy, no entanto, é preciso mais. É preciso de um gerenciador que seja executado sob controle do gerenciador de processos do sistema, que recebe aplicações de deploy (com slc deploy), e que executa as aplicações sob supervisão. Isto é o que faz o nosso gerenciador de processo. Tanto os pacotes npm quanto as branches do git, ambos podem ser usados no deploy. Além de ter todas as características de um aplicativo de supervisão (geração de cpu profile e imagem em tempo real da heap, monitoramento de objetos, status e atualização de worker, etc.), e também ter suporte para configurar diferentes tipos de aplicação, é possível parar e reiniciar a aplicação em modo hard e soft, reinicializar a aplicação durante a inicialização do servidor, etc.

A instalação do gerenciador de processos como um serviço é tedioso, por isso o gerenciador também vem com um instalador que vai fazer a parte tediosa pra você, criando um usuário específico para executar o gerenciador, arrumando os diretórios para a sua execução, etc. Apesar do gerenciador ser executado sob qualquer gerenciador de processo razoável, atualmente a instalação automatizada suporta systemd e upstart 1.4 ou 0.6 (isto abrange a maioria das principais distribuições Linux, RHEL, Ubuntu, etc., confira a documentação para mais informações).

Para instalar a partir do npmjs.org:

Ou se preferir o docker, você pode instalar pelo Docker Hub:

Experimente! Não é preciso instalá-lo, basta executá-lo manualmente em uma máquina de desenvolvimento, veja o exemplo:

Use ferramentas que são combináveis

Repare que todas as ferramentas descritas aqui (slc build, slc deploy, slc pm/slc pm-install) podem ser combinadas de várias maneiras. Você não tem que usar todas as nossas ferramentas em todo o fluxo de trabalho, mas pelo menos elas são facilmente combináveis. Por exemplo, se você estiver fazendo o deploy no Heroku ou no OpenShift, você pode usar slc build e talvez o recurso de git push do strong-deploy, mas nem precisaria do gerenciador de processo. Da mesma forma, se você já tem um build no git ou um pacote de deploy já com as dependências buildadas dentro ele, nem precisa substituí-lo com slc build, só usar slc deploy e o gerenciador de processos.

Para mais informações confira a página do strong-pm.

E o que mais?

Assista uma demonstração! Confira este curto vídeo que vai lhe dar uma visão geral sobre o Gerenciador de Processo da StrongLoop.

Cadastre-se no webinar! “Boas práticas para fazer deploy de aplicações Node.js em produção” em 16 de abril com a StrongLoop e o desenvolvedor do núcleo Node, Sam Roberts.

Nas próximas semanas, procure aprimorar ainda mais sobre o Gerenciador de Processo da StrongLoop e seus recursos runtime. Por enquanto, aqui está uma lista de alguns artigos técnicos adicionais para você aprofundar com mais detalhes sobre como aproveitar ao máximo este lançamento:

Como executar o Gerenciador de Processo da StrongLoop em produção

Se você tem acompanhado a StrongLoop e suas ferramentas, vai perceber que eles estão tentando facilitar as coisas. É por isso que o comando npm install -g strongloop empacota muitas ferramentas dentro do comando slc – tudo isso para deixar mais fácil o build, o deploy e o monitoramento das aplicações no desenvolvimento e em produção. O que não deixa de ser um pacote grande. E muitas dessas ferramentas realmente não fazem sentido no servidor. Neste blog vou mostrar uma maneira mais amigável de executar a versão mais recente do Gerenciador de Processo da StrongLoop sem todas essas ferramentas extras, como por exemplo os geradores do Yeoman e o Arc.

O que é o Gerenciador de Processo da StrongLoop? É um gerenciador corporativo runtime para processo Node.js em produção. O Gerenciador de Processo da StrongLoop foi construído para manipular tanto o escalonamento vertical e horizontal de suas aplicações Node com facilidade.

Introdução a strong-pm

Por trás da maioria dos comandos slc existe um módulo independente. Cada módulo, assim como uma ferramenta em sua caixa de ferramentas, é utilizado preferencialmente para um único trabalho ou uma finalidade específica. Como uma ferramenta, cada comando executa uma tarefa mais simples, fazendo com que o treino e o raciocínio em torno de sua função seja mais fácil. Cada módulo, portanto, tem sua própria identidade. No caso do comando slc pm esse módulo é o strong-pm.

A instalação do strong-pm disponibiliza os comandos sl-pm e sl-pm-install, o que corresponde a slc pm e slc pm-install do módulo strongloop.

Reinicialização do servidor

Servidores param de funcionar. Os cabos de alimentação são desligados. Provedores em nuvem realizam reinicializações contínuas para aplicar patches com correções críticas. E isso é ruim o suficiente porque a aplicação cai por causa dessas reinicializações, mas não ter a aplicação reinicializada junto com o servidor é ainda pior. É aí que entra o sl-pm-install. Caso você esteja usando uma das principais distribuições do Linux, alguma versão lançada há anos atrás, há grande chances de usar o Upstart no processo de init. Em versões mais recentes, com base no RHEL7, você tem o systemd. Tanto o Upstart quanto o systemd são capazes de inicializar a aplicação durante o boot e reiniciar a aplicação caso trave. Ambos também tomam conta do log de stdout e stderr no disco ou em qualquer outro lugar.

Benefícios dos Padrões

O comando sl-pm-install possui algumas opções, mas por razões de conveniência e boas práticas, todas as opções recomendadas pela StrongSloop estão definidas como padrão. São poucas as opções que não são recomendas por padrão.

  1. Quais são as implementações de init? As opções são --systemd, --upstart 0.6 ou --upstart 1.4. A opção padrão é a --upstart 1.4 devido a popularidade do Ubuntu e por causa das últimas versões suportarem LTS.
  2. Autenticação HTTP. Óbvio que não tem como a StrongLoop dizer qual o nome de usuário e senha que deve ser usado! Mas é possível definir essa autenticação com --http-auth user:pass. Não é a solução perfeita, mas já é algo para adicionar uma política de segurança em várias camadas.
  3. Onde enviar as métricas. Isto seria um pouco difícil de adivinhar, então o melhor a ser feito é utilizar o Arc. Caso queira algo mais utilize a flag --metrics, a qual usa a URL de um serviço externo.

sudo sl-pm-install

Sem usar nenhum argumento, o comando sl-pm-install está pré configurado para utilizar no Ubuntu 12.04 ou em versão mais recente. Esse comando executa os seguintes passos:

  • cria um novo usuário strong-pm
  • altera o usuário HOME para /var/lib/strong-pm
  • instala um script de init compatível com Upstart 1.4+

Esse script init vai:

  • executar o strong-pm na porta 8701
  • certificar que o daemon do strong-pm seja executado como o usuário sem privilégios do strong-pm
  • ter o cuidado de enviar os logs de saída para /var/log/upstart/strong-pm.log
  • ajustar os limites do descritor de arquivo
  • habilitar os core dumps para o daemon, caso o sistema esteja configurado para isso

Se o servidor for uma distribuição de alguma versão mais antiga do Ubuntu, Debian, RHEL 5 ou 6, ou uma das várias outras distribuições Linux que tenha o Upstart 0.6 então você vai ter que específicá-la.

sudo sl-pm-install –upstart 0.6

O Upstart 0.6 não tem alguns recursos, mas usando algumas soluções paliativas é possível fazer quase tudo o que é feito na versão compatível com o Upstart 1.4. O que é mais notável é que os logs são enviados para o syslog e marcados como strong-pm em vez de ir para algum arquivo dedicado para o uso de log.

Para as distribuições baseadas em RHEL 7 ou em outras poucas distribuições que vêm pré-configuradas com systemd, provavelmente será preciso informar ao instalador para gerar um serviço de systemd.

sudo sl-pm-install –systemd

Mais uma vez, o resultado final é quase idêntico ao da instalação compatível com o Upstart 1.4, exceto em relação ao log. Nesse caso os logs são enviados para journald, sistema de log que já faz parte do systemd. Por padrão, a melhor maneira de acessar os logs de journald é com o comando journalctl.

Controle Remoto

Quando o servidor estiver em execução (perceba que foram 2 etapas) já vai estar pronto para o build, deploy e monitoramento. Quando estiver fazendo um deploy ou alguma configuração, certifique-se de incluir as credenciais de autenticação HTTP na URL caso tenha configurado credenciais, ou melhor ainda, experimente o novo http com suporte ssh.

E é isso! Tenha um feliz deloy.

E o que mais?

Assista uma demonstração! Confira este curto vídeo que vai lhe dar uma visão geral sobre o Gerenciador de Processo da StrongLoop.

Cadastre-se no webinar! “Melhores práticas para fazer deploy de aplicações Node.js em produção” em 16 de abril com a StrongLoop e o desenvolvedor do núcleo Node, Sam Roberts.

Nas próximas semanas, procure aprimorar ainda mais sobre o Gerenciador de Processo da StrongLoop e seus recursos runtime. Por enquanto, aqui está uma lista de alguns artigos técnicos adicionais para você aprofundar com mais detalhes sobre como aproveitar ao máximo este lançamento:

The Foundations of Universal (or Isomorphic) JavaScript

In the last tutorial, we wrote a Node program using Babel. This allowed us to use ES6 features now and experiment with new language proposals in a backwards-compatible way. We looked at testing, linting, and running programs in production.

Now let’s turn our attention to programs that share code between the server and client. These are most popularly called isomorphic or universal JavaScript applications. Since Babel compiles down to ES5 JavaScript, it allows us to write modern JavaScript (ES6 and beyond) and have it work the same across the majority of platforms[1] in use today.

Read more