






































Estude fácil! Tem muito documento disponível na Docsity
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Prepare-se para as provas
Estude fácil! Tem muito documento disponível na Docsity
Prepare-se para as provas com trabalhos de outros alunos como você, aqui na Docsity
Encontra documentos específicos para os exames da tua universidade
Prepare-se com as videoaulas e exercícios resolvidos criados a partir da grade da sua Universidade
Responda perguntas de provas passadas e avalie sua preparação.
Ganhe pontos para baixar
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Uma série de boas práticas para o desenvolvimento de aplicações com node.js, abordando temas como a organização do código, a diminuição do acoplamento e aumento do reuso de software, a utilização de nomes de arquivos no formato ‘lower-kebab-case’, a criação de scripts para carregar variáveis de ambiente, a utilização de módulos funcionais, a importância de testes unitários e a utilização de ferramentas como jasmine, mocha, chai e tap, além de outras dicas práticas para o desenvolvimento de aplicações com node.js.
Tipologia: Manuais, Projetos, Pesquisas
1 / 46
Esta página não é visível na pré-visualização
Não perca as partes importantes!







































Clique nos capítulos
INTRODUÇÃO 4
Sabe quando você faz um trabalho e ele fica tão bom que você pensa algo como: “eu gostaria de ter tido acesso a isso quando estava começando”?
Pois é, esse é o meu sentimento com este ebook.
Quando estamos começando com uma nova tecnologia sempre tudo é muito confuso, complexo e, por que não dizer, assustador?
Trabalho há onze anos com programação e há uns treze programo mesmo que não profissionalmente, desde um técnico em eletrônica que fiz em 2004 que incluía programação de microcontroladores para a indústria. Nesse ínterim tive de trocar sucessivas vezes de tecnologias, seja por questões acadêmicas, seja por questões de mercado: Assembly, C/C++, Lisp, Prolog, Visual Basic, Java, Lua, .NET, PHP e, agora, Node.js.
E a cada troca eu volto a ser um calouro, tendo de aprender não apenas sintaxe, semântica, todo o “ferramental” relacionado à tecnologia, mas o mais difícil de tudo: boas práticas!
Como saber se o código que estou escrevendo está dentro dos padrões de mercado?
Como tirar o máximo proveito da linguagem através do uso das melhores ferramentas e extensões?
Como é a arquitetura ou o mindset correto para os tipos de projetos que são criados com esta tecnologia?
Como …
E tudo fica pior quando estamos falando de uma tecnologia que não tem sequer uma década de vida ainda e até cinco anos atrás era coisa de devs malucos em eventos. São muitas as dúvidas sobre Node.js e, mesmo com o todo-poderoso Google em nossas mãos, parece que essas respostas estão desconectadas e jogadas cada uma em um canto obscuro da Internet, fazendo com que dê um trabalho enorme encontrá-las.
INTRODUÇÃO 5
Não trago aqui verdades universais ou respostas para todas as perguntas que você vai ter sobre Node.js, mas trago um apanhado da experiência coletiva de milhares de desenvolvedores ao redor do globo para formar um guia de boas práticas com Node.js. Pessoas com muito mais conhecimento de Node do que eu, e algumas dicas minhas também, afinal eu também sou um desses milhares de desenvolvedores! Talvez inclusive você reconheça alguma dica que você mesmo pode ter dado em alguma rede social ou publicação na Internet.
Espero que goste do que preparamos pra você e que este ebook seja útil na sua jornada como programador Node.js. Este é o grande propósito da Umbler:
Facilitar o desenvolvimento web, seja com a nossa
plataforma, seja com materiais como esse.
Ah, e se um dia o seu projeto virar uma startup de sucesso e você for fazer um IPO ou receber uma proposta de compra vinda do Facebook, lembra de quem te ajudou lááááá no início. ;)
Um abraço e sucesso.
Luiz Duarte
Acima de qualquer boa prática que eu possa propor neste ebook, vale ressaltar alguns princípios e motivações que devem estar acima de qualquer coisa em seus projetos com Node.js.
Nem todos princípios vão se encaixar apenas no Node.js e talvez você reconheça uma ou outra coisa que já utilize hoje em outra tecnologia, como PHP. Ótimo!
Por outro lado, talvez encontre críticas a hábitos ruins que você possui hoje. Não se assuste, parte do processo de evolução como programadores (e como pessoas!) envolve manter bons hábitos e evitar hábitos ruins o tempo todo.
Afinal, é como dizem, “o hábito faz o monge”.
Existe um dito popular que diz: “Nem todo problema é um prego e nem toda ferramenta um martelo”.
Qualquer tecnologia que lhe vendam como sendo a solução para todos seus problemas é no mínimo para se desconfiar. Node não é um canivete-suíço e possui um propósito de existir muito claro desde sua homepage até a seção de about no site oficial: ele te proporciona uma plataforma orientada à eventos, assíncrona e focada em I/O e aplicações de rede não-bloqueantes.
Isso não quer dizer que você não possa fazer coisas com ele para as quais ele não foi originalmente concebido, apenas que ele pode não ser a melhor ferramenta para resolver o problema e você pode acabar frustrado achando que a culpa é do Node. Por isso, use Node preferencialmente para:
APIs; Bots; Mensageria; IoT; Aplicações real-time;
Isso pode parecer óbvio quando falamos de uma plataforma focada em I/O não- bloqueante, mas parece que tem programador que a todo custo quer mudar isso em suas aplicações, fazendo todo tipo de malabarismo para transformar trechos de código e módulos originalmente assíncronos em tarefas síncronas.
Esqueça. Nem perca seu tempo.
Se não gosta de callbacks (será que alguém gosta?) use promises e async/await, mas não tente transformar Node.js em uma plataforma síncrona pois esse não é o objetivo dele e ele não funciona bem dessa forma, afinal ele é single-thread, lembra? Se realmente precisa que tudo rode sincronamente, use PHP ou outra plataforma que crie threads separadas e seja feliz.
Conseguimos lidar com apenas pequenas quantidades de informação de cada vez. Alguns cientistas falam de sete coisas ao mesmo tempo, outros falam de quatro coisas. Por isso que usamos pastas, módulos e por isso que criamos funções. Elas nos ajudam a lidar com a complexidade do sistema nos permitindo mexer em pequenas porções dele de cada vez.
Não saia criando dezenas de diretórios que acabarão vazios ou com apenas um arquivo dentro. Comece com o básico de pastas que você precisa e vá adicionando conforme a complexidade for aumentando. Afinal, você não compra um ônibus como primeiro veículo pensando no dia em que pode querer dar carona para muita gente, certo?
Evite o over engineering de querer ter a melhor arquitetura possível no “dia um” do seu projeto. Você deve conhecer (e evitar) o termo ‘código espaguete’, certo? Um projeto com mais pastas do que o necessário é tão nocivo quanto, é o chamado ‘código lasanha” (muitas camadas)!
para sua arquitetura. Programe de maneira que o código em si possa fazer com que o programador entenda todo o projeto. Use variáveis de ambiente (como será citado mais pra frente) e/ou arquivos JSON de configuração, o que preferir, mas configure o seu projeto adequadamente e de preferência de maneira independente de infraestrutura, para que você consiga subir sua aplicação rapidamente em qualquer lugar.
Use apenas minúsculas, sem acentos e ‘-’ como separador entre palavras. Isso evita problemas de sistemas de arquivos em sistemas operacionais diferentes que sua aplicação Node possa rodar. Ex: cadastro-cliente.js
Este é o padrão do NPM para arquivos e pastas, então é melhor seguir esta regra, por mais que não goste dela.
Veja mais regras adiante.
Muitos programadores que conheço não gostam de padrões de código. No entanto, um ponto importante a se entender é: padrões de código não são para o programador, mas sim para a empresa ou para a comunidade (no caso dos projetos open-source).
Uma vez que em empresas e projetos abertos existe uma certa rotatividade de profissionais trabalhando no mesmo código, é natural que programadores com diferente visões de como o software deve ser escrito podem mexer nele e fazer com que facilmente não exista coerência na escrita. Padrões evitam isso.
Por mais que alguns podem achar isso preciosismo, só quem já trabalhou em grandes bases e código sem padrão que sabe o quão difícil é se achar no meio de um projeto bagunçado. Para resolver isso, empresas e projetos de todos os tipos e tamanhos decidem padrões. Um ponto importante aqui é que não é o mesmo padrão para todos(as). A regra é clara: pegue um padrão que você se sinta confortável e que funcione na sua empresa/projeto.
Aqui vai uma sugestão que está ganhando cada vez mais força: StandardJS, disponível em http://standardjs.com. É um padrão rígido, inflexível, construído com opiniões fortes mas que rapidamente está dominando diversos projetos e empresas mundo afora. Eu não concordo com tudo o que prega o StandardJS, mas que ajuda a tornar o código muito mais legível e enxuto, isso com certeza.
Para ajudar com projetos já existentes, ele possui um fixer automático que corrige a maior parte dos códigos fora do estilo e, dependendo da ferramenta que estiver usando (eu uso o Visual Studio Code), te dá sugestões real-time do que você está fazendo “errado”. Costumo trabalhar em projetos remotos com outros desenvolvedores e é uma excelente maneira de garantir uma padronização entre os códigos escritos por todos. Basta rodar:
standard --fix
e praticamente tudo se resolve!
E se eu não consegui te convencer, a página deles está cheia de empresas/projetos que usem esse estilo, como: NPM, GitHub, ZenDesk, MongoDB, Typeform, ExpressJS e muito mais. Falando de NPM especificamente, muitos, mas muitos, dos mais populares módulos existentes foram escritos usando StandardJS como guia de estilo, entre eles o mocha, dotenv, mssql, express-generator e muito mais.
Node.js se tornou uma das plataformas mais populares nos últimos anos. Parte desse sucesso se deve ao fato de que é muito fácil começar projetos em Node. js, mas uma vez que você vá além do Olá Mundo básico, saber como codificar corretamente sua aplicação e como lidar com tantos erros pode facilmente se tornar um pesadelo (aliás, como na maioria das linguagens de programação).
Infelizmente, evitar que este pesadelo se torne realidade faz toda a diferença entre uma aplicação sólida em produção e um desastre em forma de software.
Com isso em mente, vamos passar neste capítulo por uma série de boas práticas usando Node.js que te ajudarão a evitar a maioria das armadilhas desta plataforma.
Vamos começar do básico, ok? Todos estamos acostumados a usar o NPM para instalar novos pacotes em nosso projeto, mas sua utilidade vai além disso. Primeiramente, eu recomendo que comece todos os seus projetos usando npm init, como abaixo:
Isto faz com que o package.json seja criado, o que permite que você adicione diversos metadados que ajudarão você e sua equipe mais tarde,, definindo a versão do node que roda o projeto, quais dependências ele possui, qual é o comando para inicializar o projeto...opa essa é uma dica quente, vamos explorá-la?
Então você abre o package.json e rapidamente entende que as dependencies são os pacotes que sua aplicação usa, mas onde deveriam estar listadas as versões dos pacotes tem um monte de símbolos que não dizem muita coisa. Resumidamente funciona assim:
mkdir novo-projeto cd novo-projeto npm init
A imagem abaixo ajuda a entender o template de versões dos pacotes do NPM, que aliás usa um padrão bem comum da indústria de software:
3 9 2
major (^) minor patch
caret (^)
tilde (~)
Patch bug fixes
Minor backwards compatible new functionality old functionality deprecated, but operational large internal refactor
Major breaking change
Além do script “start” para inicialização, temos:
E por fim, caso queira scripts personalizados, você pode adicionar o nome que quiser nos scripts, mas para chamá-lo depois deve usar o comando “npm run-script nomeDoScript”, facilitando a sua vida caso seu time tenha vários scripts diferentes.
Uma das premissas centrais do Node.js é o desacoplamento. Mais tarde falaremos de micro serviços (que é uma excelente prática para Node), mas, por ora, entenda que um dos acoplamentos que mais tomam tempo de gerência de configuração são os relacionados à serviços externos como bases de dados, APIs, etc.
Isso porque esses serviços externos possuem diferentes configurações nos diferentes ambientes que sua aplicação Node vai passar: configs de produção, de teste, de homologação, na sua máquina, etc. Como lidar com isso sem que os desenvolvedores tenham de conhecer as configurações de produção, sem ferrar com seu CI, etc? Com variáveis de ambiente!
Sempre que subimos uma aplicação Node podemos passar à ela as variáveis de ambiente daquele processo (process.env) antes do comando de inicialização:
NOME_VARIAVEL=valor node index.js
SET NOME_VARIAVEL=valor node index.js
ou em Windows
Assim, podemos passar configurações locais como variáveis de ambiente para aquela sessão da aplicação, evitando ter connection strings, por exemplo, hard- coded na sua aplicação.
Se você não achou prático, saiba que eu também não gosto de digitar isso aí toda vez que vou executar uma aplicação Node. Sendo assim, uma maneira mais profissional seria usar essa dica em conjunto com a dica anterior, de configurar scripts no package.json. Basta que você adicione as variáveis de ambiente no comando de start, como abaixo:
No entanto, se seu package.json estiver versionado, e geralmente está, isso pode não ser uma boa, porque ao fazer commit na master ele pode ser enviado ao servidor (se estiver usando CI) e estragar sua aplicação de produção. Neste caso, sugiro uma abordagem ainda mais profissional: arquivos .env.
Alguns desenvolvedores criam arquivos de configuração próprios que são lidos na inicialização da aplicação para carregar estas variáveis, no entanto, arquivos .env e o módulo dotenv (e a versão “segura” dotenv-safe) resolvem este problema facilmente. Primeiro, crie o seu arquivo .env (sem nome, apenas “.env” mesmo) e coloque uma variável de ambiente por linha, como abaixo, podendo usar # para comentários:
Agora adicione no gitignore este arquivo, para ele não ser versionado. Certifique-se de fazer cópias dele nos seus diversos ambientes com os valores de teste, homologação, produção, etc, assim, você nunca envia ele e nunca sobrescreve as configs de produção.
#meu primeiro .env VARIAVEL1=valor VARIAVEL2=valor
irá levar e isso é terrível pois ele bloqueia todas as requisições até que termine.
O problema só não é pior porque depois que o require sobre aquele módulo for chamado uma vez, ele ficará em cache. Sendo assim, todas as suas dependências devem ser carregadas e configuradas antecipadamente, o que ajudará a descobrir erros de conexão e configuração bem cedo e deixar o funcionamento da aplicação mais fluida.
Passe as conexões criadas para os subsistemas ao invés de ficar passando informações de conexão por parâmetro e permitindo que eles criem suas próprias conexões.
Claro que toda regra tem sua exceção caso venha a utilizar Node.js com bancos relacionais em PaaS, talvez tenha que abrir e fechar as conexões por conta própria e não poderá ficar repassando o objeto entre as funções, ainda assim você pode centralizar o acesso à dados em um módulo específico para tal, como um db.js, por exemplo.
Você já deve ter ouvido falar que funções são objetos de primeira classe em JavaScript, certo? Isto é dito porque em JS funções não são tratadas de maneira muito distinta de outros objetos, diferente de outras linguagens que costumam deixar muito clara a diferença entre funções e variáveis.
Programar com um mindset funcional é aproveitar essa característica inerente da linguagem e usar e abusar de funções coesas, desacopladas, que aumentem o reuso de código, a legibilidade do código, facilitem a criação de testes (que veremos mais pra frente) e muito mais. Algumas regras básicas que você pode adotar com JS “funcional” sem medo de errar são:
SRP - Single Responsibility Principle Cada função deve ter uma única razão de existir e, portanto, uma única razão para ser alterada. Jamais crie funções que atuem como “canivetes suíços“. Isso garante uma uma alta coesão e é uma boa dica para criação de módulos em JS também, evitando módulos como “utils.js”.
DRY - Don’t Repeat Yourself Trechos de código com lógica parecida? Encapsule em uma função. Funções chamadas repetidas vezes? Encapsule em um laço. Funções repetidas entre projetos? Encapsule em um módulo. Etc.
Imutabilidade Sempre que possível, trabalhe com objetos imutáveis. Isso se tornou bem mais fácil com a adição do ‘const’ no ES6.
Baixo Acoplamento Lembra da definição matemática do que é uma função? Funções são relações de um conjunto A com um conjunto B, ou seja, dados determinados parâmetros de entrada (A), teremos determinado retorno como saída (B). Sempre relacione A com B, jamais A com C (variáveis externas?) ou C com B, ou seja, para manter um baixo acoplamento a função apenas deve conhecer o conjunto de entradas para construir a partir dele as suas saídas.
Declarativo ao invés de Imperativo Use as funções declarativas nativas como foreach, map, reduce, filter, etc trabalharem duro por você sem se preocupar com os detalhes de tais lógicas fica mais legível e muitas vezes mais eficiente.
Anonymous Functions Aprenda a usar e se acostume com elas, especialmente closures e arrow functions.
Desde o ES6 que JS tem obtido características mais orientadas à objetos e alguns conceitos de OO inclusive foram citados logo acima. No entanto, focar em um JS OO, na minha opinião, não agrega tanto valor à linguagem quanto suas características funcionais.
Existem bons livros sobre programação funcional, inclusive com JavaScript, além de cursos específicos, então não entrarei em detalhes aqui. Apenas reservo este espaço para alertar sobre a importância desse mindset para o uso correto desta tecnologia e sugerir a leitura deste material simples, porém muito inteligente: JAMES SINCLAIR.