Introdução ao Node.js

Node.js é um runtime (i.e., ambiente) para execução de aplicações JavaScript. Neste cenário, além de ser multiplataforma, ou seja, compatível com diferentes sistemas operacionais, o próprio Node.js oferece recursos para apoiar na implementação de aplicações, confira na documentação oficial.

Criado por Ryan Dahl (2009), o Node.js é baseado no V8, implementado pelo Google e utilizado no Google Chrome. Dessa forma, enquanto o V8 foca na interpretação do código JavaScript, o Node.js se preocupa em ofertar um ambiente multiplataforma com recursos de apoio.

Para compreender o Node.js é interessante conhecer a relação entre JavaScript e ECMAScript (ES). ECMAScript é uma especificação de linguagem de script, utilizada por diferentes linguagens, por exemplo JavaScript e ActionScript (Flash). Dessa forma, JavaScript é uma linguagem de programação baseada na especificação ECMAScript. Porém, existem diferentes versões da especificação ECMAScript. Consequentemente, diferentes engines (e.g., V8) são baseadas em diferentes versões da ECMAScript.

Escalabilidade é uma das características atribuídas ao Node.js, sendo base para que diferentes profissionais recomendem o uso de Node.js para o desenvolvimento de APIs, aplicações de tempo-real, etc. Porém, os principais diferenciais do Node.js estão relacionados com sua arquitetura baseada em eventos (Event-Loop), bem como ao seu I/O não bloqueante, focado em tarefas assíncronas. Além disso, por padrão Node.js funciona por meio de single-thread, embora seja possível trabalhar com multithreading.

Principais benefícios

Quando desenvolvemos com Node.js, utilizamos uma abordagem baseada em eventos, o que exige mapear quais eventos podem ocorrer, bem como disponibilizar uma interface para ouvi-los, possibilitando executar operações específicas.

Estar preparado para trabalhar com interações de tempo real entre cliente e servidor é um diferencial interessante do Node.js. Neste ponto, destacam-se os pacotes SockJS, Socket.IO e Engine.IO. Estes pacotes são compatíveis com o protocolo WebSockets e permitem trafegar dados por meio de uma conexão bi-direcional, tratando as mensagens via eventos no JavaScript.

Por ser single-thread por padrão, podemos destacar o benefício de não ter deadlock.Por outro lado, o fator single-thread exige atenção, evitando bloco de código síncrono e demorado, sendo essencial analisar possíveis gargalos e refatorar visando tarefas assíncronas.

Gerenciamento de pacotes com NPM

NPM é um gerenciador de pacotes para código JavaScript. Trata-se de um facilitador para reutilização de código compartilhado, onde pequenos pacotes são criados para solucionar problemas específicos. Dessa forma, desenvolvedores e engenheiros de software ficam responsáveis pela composição de soluções customizadas, combinando diferentes pacotes. Porém, dependências externas são perigosas e continua sendo necessário analisar o que está sendo adotado, bem como o envolvimento da comunidade e a disponibilidade de documentação do pacote.

Neste cenário, é importante conhecer as formas de instalar pacotes na aplicação (e.g., local e global). Quando o uso do pacote se limitar no apoio ao desenvolvimento de forma externa, este deve ser instalado de forma global. Por outro lado, caso o pacote faça parte do projeto, uma dependência para que os requisitos do projeto sejam realizados, este deve ser instalado localmente.

// Global
npm install -g swagger

// Local
npm install express --save

O gerenciamento dos pacotes instalados localmente na aplicação ocorre por meio do arquivo package.json, que organiza informações sobre o projeto, suas dependências e scripts de inicialização, etc.

Para descobrir pacotes ou obter mais informações, acesse o site https://www.npmjs.com/.

Boas práticas usando Node.js

  • Instalar versão estável do Node.js (LTS);
  • Compreender o versionamento de pacotes (Major, Minor e Patch);
  • Pesquisar pacotes antes de implementar soluções específicas;
  • Padronização do código e nomenclatura de arquivos;
  • Considerar adoção de guia de estilo de código;
  • Trabalhar de forma assíncrona (promise, async/await, etc).

Gerenciamento de erros e processos

Colocar uma aplicação Node.js em produção exige alguns cuidados. Os principais estão relacionados ao gerenciamento de erros e exceções, bem como o gerenciamento automatizado de processos.

Quando ocorrem exceções ou rejeições não tratadas (uncaughtException ou unhandledRejection), o comportamento de uma aplicação Node.js torna-se imprevisível. Neste cenário, uma prática realizada pelos desenvolvedores é armazenar o log do erro/disparar email e finalizar o processo da aplicação para reiniciá-lo. Porém, o gerenciamento de processo da aplicação precisa ser automatizado, neste ponto, destacam-se os pacotes PM2 e Forever.

Existe muita discussão na comunidade sobre o gerenciamento de erros e exceções em aplicações Node.js, porém, não é uma boa prática manter uma aplicação Node.js após um erro crítico ser disparado. O uso dos eventos uncaughtException e unhandledRejection é bastante questionado, porém, na prática continua sendo utilizado para encerrar o processo da aplicação. Por fim, cabe aos desenvolvedores realizarem o tratamento em nível de código (try/catch, promise, etc).

Para mais informações, confira as dicas do framework express (http://expressjs.com/pt-br/advanced/best-practice-performance.html).

Pacotes interessantes

Pacote Descrição
standardjs Guia de estilo JavaScript, com analisador e fixador de código automático.
dotenv Pacote para carregar variáveis de ambiente.
socket.io Framework para criação de aplicações de tempo real.
swagger Pacote composto por ferramentas para projetar e criar APIs.
express Framework minimalista para desenvolvimento de aplicações web.
helmet Pacote de apoio para proteção de aplicações web.
sequelize ORM para Node.js (Banco de dados relacionais).
mongoose ODM para Node.js (MongoDB).
winston Pacote para armazenar log assíncrono.
morgan Pacote para armazenar log de requisição HTTP.
supertest Pacote para teste em alto nível de requisições HTTP.
mocha Pacote para teste unitário.

Confira as listas Awesome mantidas por alguns colaboradores:

Conclusão

Node.js está conquistando muitos desenvolvedores, mas ainda existe debate sobre quando adotá-lo. Não existe bala de prata, continua sendo importante analisar os requisitos funcionais e não funcionais de cada projeto, bem como questões sobre capacitação dos desenvolvedores para construção e manutenção de aplicações. Reconhecer os limites de cada tecnologia bem como os principais cenários para sua aplicação é importante para evitar qualquer tipo de viés, seja gerencial ou técnico.

  • Gabriel

    15/01/2018 às 18:29

    Boa garoto!

Deixe uma resposta

O seu endereço de e-mail não será publicado.. Campos obrigatórios são marcados com *