<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Node.js - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Aprenda a codificar - de graça. Tutoriais de programação em Python, JavaScript, Linux e muito mais. ]]>
        </description>
        <link>https://www.freecodecamp.org/portuguese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Node.js - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 22 May 2026 15:17:00 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/tag/node-js/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Construindo uma aplicação de CRUD simples com Express e MongoDB ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Zell Liew Por muito tempo, não ousei me aventurar no desenvolvimento de back-end. Me sentia intimidado por causa da minha falta de formação acadêmica em programação. Lembro-me de quando finalmente criei coragem para tentar o desenvolvimento de  back-end. Tive tanta dificuldade em entender a documentação do Express, ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/construindo-uma-aplicacao-de-crud-simples-com-express-e-mongodb/</link>
                <guid isPermaLink="false">6687425423266d03fc8b83da</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Kris Lagerström ]]>
                </dc:creator>
                <pubDate>Sun, 04 Aug 2024 23:29:53 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/1_umzW9eAqELBCuo458Rzdcw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/building-a-simple-crud-application-with-express-and-mongodb-63f80f3eb1cd/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Building a Simple CRUD Application with Express and MongoDB</a>
      </p><p>Escrito por: Zell Liew</p><p>Por muito tempo, não ousei me aventurar no desenvolvimento de <em>back-end</em>. Me sentia intimidado por causa da minha falta de formação acadêmica em programação.</p><p>Lembro-me de quando finalmente criei coragem para tentar o desenvolvimento de <em>back-end</em>. Tive tanta dificuldade em entender a documentação do Express, MongoDB e Node.js que desisti.</p><p>No fim, voltei e trabalhei para esclarecer minha confusão. Agora, um ano depois, entendi como trabalhar com essas ferramentas. Então, decidi escrever este tutorial abrangente para que você não precise passar pela mesma dor de cabeça que eu passei.</p><h3 id="crud-express-e-mongodb">CRUD, Express e MongoDB</h3><p>CRUD, Express e MongoDB são palavras grandes para uma pessoa que nunca tocou em programação do lado do servidor em sua vida. Vamos apresentar rapidamente o que elas são antes de mergulharmos no tutorial.</p><p><a href="https://pt.wikipedia.org/wiki/Express.js"><strong>Express</strong></a> é um <em>framework </em>para construir aplicações para a web com base no Node.js. Ele simplifica o processo de criação do servidor que já está disponível no Node. Caso você esteja se perguntando: o Node permite que você use JavaScript como sua linguagem do lado do servidor.</p><p><a href="https://pt.wikipedia.org/wiki/MongoDB"><strong>MongoDB</strong></a> é um banco de dados. É no banco de dados que você armazena informações para seus sites (ou aplicações) para a web.</p><p><a href="https://pt.wikipedia.org/wiki/CRUD"><strong>CRUD</strong></a> é uma abreviação em inglês para Criar, Ler, Atualizar e Excluir. É um conjunto de operações que fazemos para que os servidores as executem (POST, GET, PUT e DELETE, respectivamente). Isso é o que cada operação faz:</p><ul><li><strong>Criar (POST)</strong> — Criar algo</li><li><strong>Ler (GET)</strong> — Obter algo</li><li><strong>Atualizar (PUT)</strong> — Alterar algo</li><li><strong>Excluir (DELETE)</strong>– Remover algo</li></ul><p>Se colocarmos CRUD, Express e MongoDB juntos em um único diagrama, seria assim:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_UKwrPtpRSGFiDomm.png" class="kg-image" alt="0_UKwrPtpRSGFiDomm" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_UKwrPtpRSGFiDomm.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_UKwrPtpRSGFiDomm.png 800w" sizes="(min-width: 720px) 720px" width="800" height="294" loading="lazy"><figcaption>À direita, o navegador. Entre ele e o servidor, as operações de CRUD.</figcaption></figure><p>CRUD, Express e MongoDB fazem mais sentido para você agora?</p><p>Ótimo. Vamos em frente.</p><h3 id="o-que-vamos-construir">O que vamos construir</h3><p>Vamos construir uma aplicação de lista simples que permite que você acompanhe as coisas dentro de uma lista (como uma Lista de Tarefas, por exemplo).</p><p>Bem, uma lista de tarefas é meio chata. Que tal fazermos uma lista de citações de personagens de Star Wars? Incrível, não é? Além disso, <a href="https://github.com/zellwk/crud-express-mongo">aqui é onde</a> você pode encontrar o código finalizado para a aplicação.</p><p>A propósito, o que estamos construindo não é uma aplicação de página única atraente. Estamos focando principalmente em como usar o CRUD, o Express e Mongo DB neste tutorial. Serão, portanto, mais orientações de como criar o lado do servidor. Não vou enfatizar o estilo.</p><p>Você precisará de duas coisas para começar com este tutorial:</p><ol><li>Você não deve ter medo de digitar comandos em um shell. Confira <a href="https://zellwk.com/blog/fear-of-command-line/">este artigo</a> (em inglês) se estiver com medo.</li><li>Você precisa ter o <a href="https://nodejs.org/">Node</a> instalado.</li></ol><p>Para verificar se você tem o Node instalado, abra sua linha de comando e execute o seguinte código:</p><pre><code>$ node -v</code></pre><p>Você deve obter um número de versão se tiver o Node instalado. Se não tiver, você pode instalar o Node baixando o instalador do <a href="https://nodejs.org/">site do Node</a> ou baixando-o por meio de gerenciadores de pacotes como <a href="http://brew.sh/">Homebrew</a> (Mac) e <a href="https://chocolatey.org/">Chocolatey</a> (Windows).</p><h3 id="come-ando">Começando</h3><p>Comece criando uma pasta para este projeto. Sinta-se à vontade para chamá-la do que quiser. Depois de navegar até ela, execute o comando <code>npm init</code>.</p><p>Esse comando cria um arquivo <code>package.json</code>, que ajuda você a gerenciar as dependências que instalaremos mais tarde no tutorial.</p><pre><code>$ npm init</code></pre><p>Basta pressionar Enter em tudo o que aparecer. Falarei sobre o que você precisa saber à medida que avançamos.</p><h3 id="executando-o-node-pela-primeira-vez-em-sua-vida">Executando o Node pela primeira vez em sua vida</h3><p>A maneira mais simples de usar o node é executar o comando node e especificar um caminho para um arquivo. Vamos criar um arquivo chamado <code>server.js</code> para executar o node.</p><pre><code>$ touch server.js</code></pre><p>Quando executarmos o arquivo <code>server.js</code>, queremos ter certeza de que ele está sendo executado corretamente. Para fazer isso, basta escrever uma instrução <code>console.log</code> no server.js:</p><pre><code>console.log('Que o Node esteja com você')</code></pre><p>Agora, execute node server.js em sua linha de comando e você deverá ver a instrução que você registrou:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_82cfsJUuV4b0Mmn2.png" class="kg-image" alt="0_82cfsJUuV4b0Mmn2" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_82cfsJUuV4b0Mmn2.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_82cfsJUuV4b0Mmn2.png 769w" sizes="(min-width: 720px) 720px" width="769" height="53" loading="lazy"><figcaption>Se você enxergar <em>May Node be with you</em> (Que o Node esteja com você), é sinal de que deu certo.</figcaption></figure><p>Ótimo. Vamos em frente e aprender como usar o Express agora.</p><h3 id="usando-o-express">Usando o Express</h3><p>Primeiro, temos que instalar o Express antes de podermos usá-lo em nossa aplicação. Instalar o Express é muito fácil. Tudo o que temos que fazer é executar um comando de instalação com o gerenciador de pacotes do Node (npm), que vem junto com o Node.</p><p>Execute o comando <code>npm install express --save</code> em sua linha de comando:</p><pre><code>$ npm install express --save</code></pre><p>Depois de terminar, você deverá ver que o npm salvou o Express como uma dependência no <code>package.json</code>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_WQ2iauA--9SEqja3.png" class="kg-image" alt="0_WQ2iauA--9SEqja3" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_WQ2iauA--9SEqja3.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_WQ2iauA--9SEqja3.png 617w" width="617" height="174" loading="lazy"><figcaption>A versão da dependência será diferente, dependendo de quando você estiver lendo este artigo.</figcaption></figure><p>Em seguida, usamos o express em server.js exigindo-o.</p><pre><code>const express = require('express');
const app = express();</code></pre><p>A primeira coisa que queremos fazer é criar um servidor ao qual os navegadores possam se conectar. Podemos fazer isso com a ajuda de um método <code>listen</code> fornecido pelo Express:</p><pre><code>app.listen(3000, function() {
	console.log('Escutando na porta 3000')
})</code></pre><p>Agora, execute <code>node server.js</code> e navegue até <code>localhost:3000</code> em seu navegador. Você deverá ver uma mensagem que diz <code>Cannot get /</code>.</p><figure class="kg-card kg-image-card"><img src="https://cdn-media-1.freecodecamp.org/images/0*HuIZ1G3D7TMPjbdU.png" class="kg-image" alt="0HuIZ1G3D7TMPjbdU" width="800" height="141" loading="lazy"></figure><p>Isso é um bom sinal. Significa que <strong>agora podemos nos comunicar com nosso servidor do Express através do navegador</strong>. É aqui que começamos as operações CRUD.</p><h3 id="crud-ler">CRUD — LER</h3><p>A operação <strong>LER</strong> é realizada pelos navegadores sempre que você visita uma página da web. Nos bastidores, os navegadores enviam uma solicitação <strong>GET</strong> ao servidor para realizar uma operação de LEITURA. O motivo pelo qual vemos o erro "Cannot get /" é porque ainda não enviamos nada de volta ao navegador do nosso servidor.</p><p>No Express, lidamos com uma solicitação <strong>GET</strong> com o método get:</p><pre><code>app.get(caminho, callback)</code></pre><p><strong>O primeiro argumento, caminho</strong>, é o caminho da solicitação GET. É qualquer coisa que vem depois do nome de domínio.</p><p>Quando estamos visitando <code>localhost:3000</code>, nossos navegadores estão, na verdade, procurando por <code>localhost:3000/</code>. O argumento caminho, neste caso, é <code>/</code>.</p><p><strong>O segundo argumento é uma função de <em>callback</em></strong> que informa ao servidor o que fazer quando o caminho é correspondido. Ele recebe dois argumentos, um objeto de solicitação e um objeto de resposta:</p><pre><code>app.get('/', function (request, response) {
  // faça algo aqui
})</code></pre><p>Por enquanto, vamos escrever "Olá Mundo" de volta para o navegador. Fazemos isso usando um método <em>send</em> que vem com o objeto de resposta:</p><pre><code>app.get('/', function(req, res) {
  res.send('Olá Mundo')
}) // Observação: solicitação e resposta são geralmente escritas como req e res, respectivamente.</code></pre><p>Vou começar a escrever em código ES6 e mostrar como converter para ES6 ao longo do caminho também. Primeiro, estou substituindo o function() pela <a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Functions/Arrow_functions"><em>arrow function</em>, da ES6</a>. O código abaixo é o mesmo que o código acima:</p><pre><code>app.get('/', (req, res) =&gt; {
  res.send('Olá mundo')
})</code></pre><p>Agora, reinicie seu servidor fazendo o seguinte:</p><ol><li>Pare o servidor atual pressionando <code>CTRL + C</code> na linha de comando.</li><li>Execute <code>node server.js</code> novamente.</li></ol><p>Em seguida, navegue até <code>localhost:3000</code> em seu navegador. Você deverá ver uma <em>string</em> que diz "Hello World" (Olá Mundo).</p><figure class="kg-card kg-image-card"><img src="https://cdn-media-1.freecodecamp.org/images/0*jBDbdhi2v2N82RvP.png" class="kg-image" alt="0jBDbdhi2v2N82RvP" width="800" height="130" loading="lazy"></figure><p>Ótimo. Vamos mudar nossa aplicação para que sirva uma página <code>index.html</code> de volta para o navegador. Para fazer isso, usamos o método <em>sendFile</em> que é fornecido pelo objeto <code>res</code>.</p><pre><code>app.get('/', (req, res) =&gt; {
  res.sendFile(__dirname + '/index.html')
}) // Observação: __dirname é o caminho para o seu diretório de trabalho atual. Tente registrá-lo e veja o que você obtém! O meu era '/Users/zellwk/Projects/demo-repos/crud-express-mongo' para esta aplicação.</code></pre><p>No método <code>sendFile()</code> acima, dissemos ao Express para servir um arquivo index.html que pode ser encontrado na raiz da pasta do seu projeto. Ainda não temos esse arquivo. Vamos criá-lo agora.</p><pre><code>touch index.html</code></pre><p>Vamos colocar algum texto em nosso arquivo <code>index.html</code> também:</p><pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
	&lt;head&gt;
	  &lt;meta charset="UTF-8"&gt;
	  &lt;title&gt;MEU APP&lt;/title&gt;&lt;/head&gt;
	&lt;/head&gt;
	&lt;body&gt;
		Que o Node e o Express estejam com você.
	&lt;/body&gt;
&lt;/html&gt;</code></pre><p>Reinicie seu servidor e atualize seu navegador. Você deverá ver os resultados do seu arquivo HTML agora.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_oisDzT819Ex3FtDs.png" class="kg-image" alt="0_oisDzT819Ex3FtDs" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_oisDzT819Ex3FtDs.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_oisDzT819Ex3FtDs.png 696w" width="696" height="159" loading="lazy"><figcaption>Você deve ver <em>May Node and Express be with you</em>/Que o Node e o Express estejam com você!</figcaption></figure><p>É assim que o Express lida com uma solicitação <strong>GET</strong> (operação <strong>LER</strong>) em poucas palavras.</p><p>Neste ponto, você provavelmente percebeu que precisa reiniciar seu servidor sempre que fizer uma alteração em <code>server.js</code>. Esse processo é incrivelmente tedioso. Por isso, vamos fazer um pequeno desvio e otimizá-lo usando um pacote chamado <a href="http://nodemon.io/">nodemon</a>.</p><h3 id="apresentando-o-nodemon">Apresentando o Nodemon</h3><p><strong>O Nodemon reinicia o servidor automaticamente</strong> sempre que você salva um arquivo que o servidor usa. Podemos instalar o Nodemon usando o seguinte comando:</p><pre><code>$ npm install nodemon --save-dev</code></pre><p>Observação: o motivo pelo qual estamos usando uma <em>flag</em> <code>--save-dev</code> aqui é porque estamos usando o Nodemon apenas quando estamos desenvolvendo. Essa <em>flag </em>salvaria o Nodemon como uma devDependency em seu arquivo <code>package.json</code>.</p><p>Continuando, o Nodemon se comporta exatamente da mesma maneira que o node, o que significa que podemos executar nosso servidor chamando <code>nodemon server.js</code>. No entanto, não podemos fazer isso na linha de comando agora porque o Nodemon não está instalado com uma <em>flag</em> <code>-g</code>.</p><p>Há outra maneira de executar o Nodemon — podemos executá-lo a partir da pasta node_modules. O código se parece com isto:</p><pre><code>$ ./node_modules/.bin/nodemon server.js</code></pre><p>Isso é muito para digitar. Uma maneira de simplificar é criar uma chave de script em <code>package.json</code>.</p><pre><code>{  
	// ...
   "scripts": {
		"dev": "nodemon server.js"
	}
    // ...
}</code></pre><p>Agora, você pode executar <code>npm run dev</code> para acionar <code>nodemon server.js</code>.</p><p>De volta ao tópico principal. Vamos cobrir a operação <strong>CRIAR</strong> em seguida.</p><h3 id="crud-criar">CRUD — CRIAR</h3><p>A operação <strong>CRIAR</strong> é realizada apenas pelo navegador se uma solicitação <strong>POST</strong> for enviada ao servidor. Essa solicitação POST pode ser acionada com JavaScript ou por meio de um elemento <code>&lt;form&gt;</code>.</p><p>Vamos descobrir como usar um elemento <code>&lt;form&gt;</code> para criar entradas para nossa aplicação de citações de Star Wars para esta parte do tutorial.</p><p>Para fazer isso, você primeiro precisa criar um elemento <code>&lt;form&gt;</code> e adicioná-lo ao seu arquivo <code>index.html</code>. Você precisa ter três coisas nesse elemento de formulário:</p><ol><li>Um atributo <code>action</code></li><li>Um atributo <code>method</code></li><li>Atributos <code>name</code> em todos os elementos <code>&lt;input&gt;</code> dentro do formulário</li></ol><pre><code>&lt;form action="/quotes" method="POST"&gt;
	&lt;input type="text" placeholder="nome" name="nome"&gt;
	&lt;input type="text" placeholder="citação" name="citação"&gt;
	&lt;button type="submit"&gt;Enviar&lt;/button&gt;
&lt;/form&gt;</code></pre><p>O atributo <code>action</code> informa ao navegador para onde navegar em nossa aplicação Express. Neste caso, estamos navegando para <code>/quotes</code>. O atributo <code>method</code> informa ao navegador qual solicitação enviar. Neste caso, é uma solicitação POST.</p><p>Em nosso servidor, podemos lidar com essa solicitação POST com um método post que o Express fornece. Ele recebe os mesmos argumentos que o método GET:</p><pre><code>app.post('/quotes', (req, res) =&gt; {  console.log('Oláááááááááááááá!')})</code></pre><p>Reinicie seu servidor (espero que você tenha configurado o Nodemon para que ele reinicie automaticamente) e atualize seu navegador. Em seguida, insira algo em seu elemento de formulário. Você deverá ver Oláááááááááááááá! em sua linha de comando.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_qsLmf8vEhBlhIfJj.png" class="kg-image" alt="0_qsLmf8vEhBlhIfJj" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_qsLmf8vEhBlhIfJj.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_qsLmf8vEhBlhIfJj.png 712w" width="712" height="76" loading="lazy"><figcaption>Você deverá ver <em>Helloooooooooooooooo!</em> ou Oláááááááááá</figcaption></figure><p>Ótimo, sabemos que o Express está lidando com o formulário para nós agora. A próxima pergunta é: como obtemos os valores de entrada com o Express?</p><p>Acontece que o Express não lida com a leitura de dados do elemento <code>&lt;form&gt;</code> por conta própria. Temos que adicionar outro pacote chamado <code>body-parser</code> para obter essa funcionalidade.</p><pre><code>$ npm install body-parser --save</code></pre><p>O Express nos permite adicionar <em>middlewares </em>como <code>body-parser</code> à nossa aplicação com o método <code>use</code>. Você ouvirá muito o termo <em>middleware</em> ao lidar com o Express. Essas coisas são basicamente <em>plug-ins</em> que alteram o objeto de solicitação ou resposta antes que eles sejam tratados por nossa aplicação. <strong>Certifique-se de colocar o <em>body-parser</em> antes de seus manipuladores CRUD!</strong></p><pre><code>const express = require('express')
const bodyParser= require('body-parser')
const app = express()
app.use(bodyParser.urlencoded({extended: true}))
// Todos os outros manipuladores aqui...</code></pre><p>O método <code>urlencoded</code> dentro do <code>body-parser</code> informa ao <code>body-parser</code> para extrair dados do elemento <code>&lt;form&gt;</code> e adicioná-los à propriedade <code>body</code> no objeto de solicitação.</p><blockquote>Nota da tradução: nas versões mais recentes, é possível usar <code>express.json</code> no lugar de <code>body-parser</code> para fazer o <em>parsing</em> do documento, tornando desnecessária a requisição deste último. </blockquote><p>Agora, você deverá ver tudo no campo do formulário dentro do objeto <code>req.body</code>. Tente fazer um <code>console.log</code> e veja o que é!</p><pre><code>app.post('/quotes', (req, res) =&gt; {
  console.log(req.body)
})</code></pre><p>Você deverá obter um objeto semelhante ao seguinte em sua linha de comando:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_cmNU6GQhNS7BYsLT.png" class="kg-image" alt="0_cmNU6GQhNS7BYsLT" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_cmNU6GQhNS7BYsLT.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_cmNU6GQhNS7BYsLT.png 800w" sizes="(min-width: 720px) 720px" width="800" height="70" loading="lazy"></figure><p>Hmmm. Mestre Yoda falou! Vamos garantir que nos lembremos das palavras de Yoda. É importante. Queremos poder recuperá-las na próxima vez que carregarmos nossa página inicial.</p><p>É aqui que entra o banco de dados, o MongoDB.</p><h3 id="mongodb">MongoDB</h3><p>Primeiro, temos que instalar o MongoDB através do <code>npm</code> se quisermos usá-lo como nosso banco de dados.</p><pre><code>npm install mongodb --save</code></pre><p>Depois de instalado, podemos nos conectar ao MongoDB através do método connect do Mongo.Client, conforme mostrado no código abaixo:</p><pre><code>const MongoClient = require('mongodb').MongoClient</code></pre><pre><code>MongoClient.connect('link-para-o-mongodb', (err, database) =&gt; {
  // ... inicie o servidor
})</code></pre><p>A próxima parte é obter o link correto para nosso banco de dados. A maioria das pessoas armazenam seus bancos de dados em serviços em nuvem como o <a href="https://mongolab.com/">MongoLab</a>. Faremos o mesmo também.</p><p>Então, vá em frente e crie uma conta no MongoLab. (É grátis). Depois de terminar, crie uma nova implantação do MongoDB e defina o plano como <em>sandbox</em>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_YujCEhVovfSgPH_j.png" class="kg-image" alt="0_YujCEhVovfSgPH_j" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_YujCEhVovfSgPH_j.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_YujCEhVovfSgPH_j.png 777w" sizes="(min-width: 720px) 720px" width="777" height="1266" loading="lazy"></figure><p>Depois de terminar de criar a implantação, vá até ela e crie um usuário de banco de dados e uma senha de banco de dados. <strong>Lembre-se do usuário e da senha do banco de dados</strong> porque você os usará para conectar o banco de dados que acabou de criar.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_pPeHMc1EqlQRAqKU.png" class="kg-image" alt="0_pPeHMc1EqlQRAqKU" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_pPeHMc1EqlQRAqKU.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_pPeHMc1EqlQRAqKU.png 800w" sizes="(min-width: 720px) 720px" width="800" height="162" loading="lazy"></figure><p>Finalmente, pegue o URL do MongoDB e adicione-a ao seu método <code>MongoClient.connect</code>. Certifique-se de usar seu usuário e senha do banco de dados!</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_x5a1AplcCRyq712P.png" class="kg-image" alt="0_x5a1AplcCRyq712P" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_x5a1AplcCRyq712P.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_x5a1AplcCRyq712P.png 800w" sizes="(min-width: 720px) 720px" width="800" height="121" loading="lazy"></figure><pre><code>MongoClient.connect('seu-url-do-mongodb', (err, database) =&gt; {
  // ... faça algo aqui
})</code></pre><p>Em seguida, queremos iniciar nossos servidores apenas quando o banco de dados estiver conectado. Portanto, vamos mover <code>app.listen</code> para dentro do método <code>connect()</code>. Também vamos criar uma variável <code>db</code> para nos permitir usar o banco de dados quando lidarmos com solicitações do navegador.</p><pre><code>var db</code></pre><pre><code>MongoClient.connect('sua-url-do-mongodb', (err, database) =&gt; {
  if (err) return console.log(err)
  db = database  
  app.listen(3000, () =&gt; {
    console.log('escutando na porta 3000')
  })
})</code></pre><p>Terminamos de configurar o MongoDB. Agora, vamos criar uma coleção de citações para armazenar citações para nossa aplicação.</p><p>A propósito, <strong>uma coleção é um local nomeado para armazenar coisas</strong>. Você pode criar quantas coleções quiser. Podem ser coisas como "produtos", "citações", "mantimentos" ou quaisquer outros rótulos que você escolher.</p><p>Podemos criar a coleção de citações usando a <em>string </em><code>quotes</code> ao chamar o método <code>db.collection()</code> do MongoDB. Ao criar a coleção de citações, também podemos salvar nossa primeira entrada no MongoDB com o método save simultaneamente.</p><p><strong>Depois de terminarmos de salvar, temos que redirecionar o usuário para algum lugar</strong> (ou ele ficará preso esperando para sempre que nosso servidor se mova). Nesse caso, vamos redirecioná-los de volta para <code>/</code>, o que faz com que seus navegadores recarreguem.</p><pre><code>app.post('/quotes', (req, res) =&gt; {
  db.collection('quotes').save(req.body, (err, result) =&gt; {
    if (err) return console.log(err)
    console.log('salvo no banco de dados')
    res.redirect('/')
    })
})</code></pre><p>Agora, se você inserir algo no elemento, poderá ver uma entrada em sua coleção do MongoDB.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_XEGKefxWJP6SlQpM.png" class="kg-image" alt="0_XEGKefxWJP6SlQpM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_XEGKefxWJP6SlQpM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_XEGKefxWJP6SlQpM.png 792w" sizes="(min-width: 720px) 720px" width="792" height="218" loading="lazy"></figure><p>Uhuuu! Já que já temos algumas citações na coleção, por que não tentar mostrá-las ao nosso usuário quando ele acessar nossa página?</p><h3 id="mostrando-cita-es-aos-usu-rios">Mostrando citações aos usuários</h3><p>Temos que fazer duas coisas para mostrar as citações armazenadas no MongoLab aos nossos usuários.</p><ol><li>Obter citações do MongoLab</li><li>Usar um mecanismo de template para exibir as citações</li></ol><p>Vamos passo a passo.</p><p>Podemos obter as citações do MongoLab usando o método find que está disponível no método <code>collection</code>.</p><pre><code>app.get('/', (req, res) =&gt; {
	var cursor = db.collection('quotes').find()
})</code></pre><p>O método <code>find</code><em> </em>retorna um cursor (um objeto do Mongo) que provavelmente não faz sentido se você fizer console.log dele.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_IQHvKZ7Bd5mIlxT0.png" class="kg-image" alt="0_IQHvKZ7Bd5mIlxT0" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_IQHvKZ7Bd5mIlxT0.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_IQHvKZ7Bd5mIlxT0.png 800w" sizes="(min-width: 720px) 720px" width="800" height="362" loading="lazy"></figure><p>A boa notícia é que esse objeto cursor contém todas as citações do nosso banco de dados. Ele também contém várias outras propriedades e métodos que nos permitem trabalhar com dados facilmente. Um desses métodos é o método <code>toArray()</code>.</p><p><strong>O método toArray</strong> recebe uma função de <em>callback</em> que nos permite fazer coisas com as citações que recuperamos do MongoLab. Vamos tentar fazer um <code>console.log()</code> para os resultados e ver o que obtemos!</p><pre><code>db.collection('quotes').find().toArray(function(err, results) {
	console.log(results)  // enviar arquivo HTML preenchido com citações aqui
})</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_6McLqpFyG1xA5of1.png" class="kg-image" alt="0_6McLqpFyG1xA5of1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_6McLqpFyG1xA5of1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_6McLqpFyG1xA5of1.png 782w" sizes="(min-width: 720px) 720px" width="782" height="78" loading="lazy"></figure><p>Ótimo! Agora, você vê um <em>array</em> de citações (eu só tenho uma agora). Concluímos a primeira parte — obter dados do MongoLab. A próxima parte é gerar um HTML que contenha todas as nossas citações.</p><p>Não podemos servir nosso arquivo <code>index.html</code> e esperar que as citações apareçam magicamente porque não há como adicionar conteúdo dinâmico a um arquivo HTML. O que podemos fazer em vez disso é usar mecanismos de template para nos ajudar. Alguns mecanismos de <em>template</em> populares incluem Jade, Embedded JavaScript e Nunjucks.</p><p>Escrevi extensivamente sobre o como e o porquê dos mecanismos de <em>template </em>em uma <a href="https://zellwk.com/blog/nunjucks-with-gulp/">artigo separado</a> (em inglês). Você pode querer dar uma olhada se não tiver ideia do que são mecanismos de <em>template</em>. Eu pessoalmente uso (e recomendo) Nunjucks como meu mecanismo de <em>template </em>de escolha. Sinta-se à vontade para conferir o artigo para descobrir o porquê.</p><p>Para este tutorial, vamos usar <a href="https://ejs.co/">Embedded JavaScript - ejs</a> como nosso mecanismo de <em>template </em>porque é o mais fácil para começar. Você o achará familiar desde o início, pois já conhece HTML e JavaScript.</p><p>Podemos usar o EJS primeiro instalando-o e, em seguida, definindo o mecanismo de visualização no Express como ejs.</p><pre><code>$ npm install ejs --save</code></pre><pre><code>app.set('view engine', 'ejs')</code></pre><p>Depois que o mecanismo de visualização for definido, podemos começar a gerar o HTML com nossas citações. Esse processo também é chamado de <strong>renderização</strong>. Podemos usar o objeto render integrado ao objeto de resposta render para fazer isso. Ele tem a seguinte sintaxe:</p><pre><code>res.render(view, locals)</code></pre><p><strong>O primeiro parâmetro, views</strong>, é o nome do arquivo que estamos renderizando. Esse arquivo deve ser colocado dentro de uma pasta views.</p><p><strong>O segundo parâmetro, locals</strong>, é um objeto que passa dados para a visualização.</p><p>Vamos primeiro criar um arquivo <code>index.ejs</code> dentro da pasta views para que possamos começar a preencher os dados.</p><pre><code>$ mkdir views$ touch views/index.ejs</code></pre><p>Agora, coloque o seguinte código dentro de <code>index.ejs</code>.</p><pre><code>&lt;ul class="quotes"&gt;
	&lt;% for(var i=0; i&lt;quotes.length; i++) {%&gt;
		&lt;li class="quote"&gt;
      		&lt;span&gt;&lt;%= quotes[i].name %&gt;&lt;/span&gt;
      		&lt;span&gt;&lt;%= quotes[i].quote %&gt;&lt;/span&gt;
    	&lt;/li&gt;
	&lt;% } %&gt;
&lt;/ul&gt;</code></pre><p>Viu o que eu quis dizer quando disse que você o acharia familiar? No EJS, você pode escrever JavaScript dentro de tags <code>&lt;% e %&gt;</code>. Você também pode gerar JavaScript como strings se usar as tags <code>&lt;%= e %&gt;</code>.</p><p>Aqui, você pode ver que estamos basicamente percorrendo o array <em>quotes</em> e criando strings com <code>quotes[i].name</code> e <code>quotes[i].quote</code>.</p><p>Mais uma coisa a fazer antes de prosseguirmos com o arquivo <code>index.ejs</code>. Lembre-se de copiar o elemento <code>&lt;form&gt;</code> do arquivo <code>index.html</code> para esse arquivo também. O arquivo <code>index.ejs</code> completo até agora deve ser:</p><pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
	&lt;head&gt;
    	&lt;meta charset="UTF-8"&gt;
        &lt;title&gt;MEU APP&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
    	Que o Node e o Express estejam com você.
        &lt;ul class="quotes"&gt;
        	&lt;% for(var i=0; i&lt;quotes.length; i++) {%&gt;
            	&lt;li class="quote"&gt;
                	&lt;span&gt;&lt;%= quotes[i].name %&gt;&lt;/span&gt;
                    &lt;span&gt;&lt;%= quotes[i].quote %&gt;&lt;/span&gt;
                &lt;/li&gt;
            &lt;% } %&gt;
        &lt;/ul&gt;
        &lt;form action="/quotes" method="POST"&gt;
        	&lt;input type="text" placeholder="nome" name="nome"&gt;
            &lt;input type="text" placeholder="citação" name="citação"&gt;
            &lt;button type="submit"&gt;Enviar&lt;/button&gt;
        &lt;/form&gt;
     &lt;/body&gt;
&lt;/html&gt;</code></pre><p>Finalmente, temos que renderizar esse arquivo index.ejs ao lidar com a solicitação <strong>GET</strong>. Aqui, estamos definindo os resultados (um array) como o array <em>quotes</em> que usamos em index.ejs acima.</p><pre><code>app.get('/', (req, res) =&gt; {
	db.collection('quotes').find().toArray((err, result) =&gt; {
    	if (err) return console.log(err)    // renderiza index.ejs
        res.render('index.ejs', {quotes: result})
    })
})</code></pre><p>Agora, atualize seu navegador e você deverá ver as citações do Mestre Yoda.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_Wy8S2Yag15rpIOlt.png" class="kg-image" alt="0_Wy8S2Yag15rpIOlt" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/08/0_Wy8S2Yag15rpIOlt.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/08/0_Wy8S2Yag15rpIOlt.png 800w" sizes="(min-width: 720px) 720px" width="800" height="199" loading="lazy"></figure><p>Ah, você pode ter apenas uma citação se seguiu o tutorial passo a passo até esse ponto. O motivo pelo qual tenho várias citações é porque adicionei mais silenciosamente enquanto trabalhava na aplicação.</p><h3 id="conclus-o">Conclusão</h3><p>Cobrimos muito terreno em apenas 3 mil palavras! Aqui estão alguns marcadores para resumir tudo. Você...</p><ul><li>Criou um servidor Express</li><li>Aprendeu a executar operações CRIAR (CREATE) e LER (READ)</li><li>Aprendeu a salvar e ler no MongoDB</li><li>Aprendeu a usar um mecanismo de <em>template</em> como o Embedded JS.</li></ul><p>Este artigo apareceu pela primeira vez no <a href="https://zellwk.com/blog/1/">blog do autor</a> (em inglês). Confira o blog se quiser ver mais artigos como este.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Node.js: o que é, quando, como e por que usar ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Pablo Regen Você, provavelmente, já leu essas frases antes… > O Node.js é um ambiente de tempo de execução de JavaScript criado usando a engine de JavaScript do Chrome, a V8 > O Node.js usa um modelo assíncrono e não bloqueador da E/S, orientado a eventos > O ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/node-js-o-que-e-quando-como-e-por-que-usar/</link>
                <guid isPermaLink="false">66297d0228986303fd725c89</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Thu, 25 Apr 2024 14:10:26 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_DF0g7bNW5e2z9XS9N2lAiw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/node-js-what-when-where-why-how-ab8424886e2/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Node.js: what it is, when and how to use it, and why you should</a>
      </p><p>Escrito por: Pablo Regen</p><p>Você, provavelmente, já leu essas frases antes…</p><blockquote>O Node.js é um ambiente de tempo de execução de JavaScript criado usando a engine de JavaScript do Chrome, a V8</blockquote><blockquote>O Node.js usa um modelo assíncrono e não bloqueador da E/S, orientado a eventos</blockquote><blockquote>O Node.js opera em um loop de eventos em thread única</blockquote><p>Se já, você pode ter se perguntado o significado de tudo isso. Ao final deste artigo, espero que você tenha uma compreensão melhor dessas frases e saiba o que o Node é, como ele funciona e por que e quando é uma boa ideia usá-lo.</p><p>Vamos começar examinando a terminologia.</p><h4 id="e-s-entrada-e-sa-da-em-ingl-s-i-o-ou-input-output-"><strong>E/S (entrada e saída – em inglês I/O, ou input/output)</strong></h4><p>E/S é a abreviação para (dispositivos de) entrada/saída. <strong>E<strong>/</strong>S</strong> (ou I/O) tem a ver primordialmente com a interação do programa com o disco e com a rede do sistema. Exemplos de operações de E/S incluem a leitura/gravação de dados de/para uma unidade de disco, a realização de solicitações de HTTP e a comunicação com um banco de dados. São dispositivos muito lentos se comparados com o acesso à memória (RAM) ou com a realização de tarefas pela CPU.</p><h4 id="s-ncrono-x-ass-ncrono"><strong><strong>Síncrono<strong> </strong>x<strong> As</strong>síncrono</strong></strong></h4><p>Execução <strong><a href="https://stackoverflow.com/questions/10570246/what-is-non-blocking-or-asynchronous-i-o-in-node-js">síncrona</a> </strong>(ou "sync") geralmente se refere ao código sendo executado em sequência. Na programação síncrona, o programa é executado linha a linha, uma linha de cada vez. Sempre que uma função é chamada, a execução do programa aguarda até que aquela função retorne um resultado antes de continuar na próxima linha do código.</p><p>Execução <strong>assíncrona </strong>(ou "async") é a execução que não é feita na mesma sequência em que aparece no código. Na programação assíncrona, o programa não aguarda até que a tarefa seja concluída, podendo seguir para a próxima tarefa.</p><p>No exemplo a seguir, a operação síncrona faz com que os alertas sejam disparados em sequência. Na operação assíncrona, embora <code>alert(2)</code> pareça ser o segundo a ser executado, não é isso que acontece.</p><pre><code class="language-js">// Operação síncrona: 1,2,3
alert(1);
alert(2);
alert(3);

// Operação assíncrona: 1,3,2
alert(1);
setTimeout(() =&gt; alert(2), 0);
alert(3);</code></pre><p>Uma operação assíncrona é frequentemente relacionada a E/S, embora <code>setTimeout</code> seja um exemplo de algo que não tenha a ver com E/S, mas ainda seja assíncrono. De um modo geral, qualquer coisa relacionada à computação é sincronizada e qualquer coisa relacionada à entrada/saída/tempo é assíncrona. A razão para as operações de E/S serem feitas de maneira assíncrona é que elas são muito lentas e bloqueariam a execução adicional do código do contrário.</p><h4 id="bloqueador-x-n-o-bloqueador"><strong><strong><strong>Blo</strong></strong>queador<strong><strong> </strong></strong>x<strong><strong> </strong></strong>não bloqueador</strong></h4><p>O modelo <strong>bloqueador</strong> se refere a operações que bloqueiam/impedem o resto da execução até que aquela operação esteja concluída. <strong>Não bloqueador</strong>, por sua vez, se refere ao código que não impede o resto da execução. Conforme vemos na documentação do <a href="https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/#blocking" rel="noopener">Node.js</a>, operações bloqueadoras ocorrem quando a execução de JavaScript adicional no processo do Node.js deve aguardar até que uma operação não relacionada ao JavaScript seja concluída.</p><p>Métodos bloqueadores executam de modo síncrono, enquanto métodos não bloqueadores executam de modo assíncrono.</p><pre><code class="language-js">// Bloqueador
const fs = require('fs');
const dados = fs.readFileSync('/arquivo.md'); // há um bloqueio aqui até que o arquivo seja lido
console.log(dados);
maisTarefas(); // será executado após o console.log

// Não bloqueador
const fs = require('fs');
fs.readFile('/arquivo.md', (err, dados) =&gt; {
  if (err) throw err;
  console.log(dados);
});
maisTarefas(); // será executado antes do console.log</code></pre><p>No primeiro exemplo, <code>console.log</code> será chamado antes de <code>maisTarefas()</code>. No segundo exemplo, <code>fs.readFile()</code> é não bloqueador, o que faz com que a execução do JavaScript possa continuar e chamar <code>maisTarefas()</code> primeiro.</p><p>No Node, não bloqueador tem primordialmente a ver com operações de E/S e com JavaScript de baixo desempenho em função de demandar demais da CPU, enquanto aguardar por uma operação que não seja do JavaScript, como as operações de E/S, não é tipicamente considerado bloqueador.</p><p>Todos os métodos de E/S na biblioteca padrão do Node.js fornecem versões assíncronas – e, portanto, não bloqueadoras – e que aceitam funções de <em>callback</em>. Alguns métodos também têm equivalentes bloqueadores, cujos nomes terminam em "Sync" (veja os exemplos de readFile e readFileSync acima).</p><p>Operações de E/S não bloqueadores permitem que um único processo sirva diversas solicitações ao mesmo tempo. Em vez de o processo ser bloqueado e ficar esperando que operações de E/S sejam concluídas, as operações de E/S são delegadas ao sistema. Assim, o processo pode executar a parte seguinte do código. Operações de E/S não bloqueadoras fornecem uma função de <em>callback, </em>que é chamada quando a operação é concluída.</p><h4 id="callbacks"><strong><strong><strong><em>Callbacks</em></strong></strong></strong></h4><p><strong>C<strong>allback</strong>s</strong> são funções passadas como argumento de uma outra função, e que, então, podem ser invocadas (chamadas novamente, ou, em inglês, <em>called back</em>) dentro da função externa para concluir algum tipo de ação na hora em que for conveniente. A chamada pode ser imediata (<em>callback</em> síncrona) ou pode acontecer mais tarde (<em>callback </em>assíncrona).</p><pre><code class="language-js">// Callback síncrona
function saudacao(callback) {
  callback();
}
saudacao(() =&gt; { console.log('Olá'); });
maisTarefas(); // será executado após o console.log

// Callback assíncrona
const fs = require('fs');
fs.readFile('/arquivo.md', function callback(err, dados) { // fs.readFile é um método assíncrono fornecido pelo Node
  if (err) throw err;
  console.log(dados);
});
maisTarefas(); // será executado antes do console.log
</code></pre><p>No primeiro exemplo, a função de <em>callback</em> é chamada imediatamente dentro da função externa <code>saudacao</code> e faz o registro no console antes que <code>maisTarefas()</code> seja executada.</p><p>No segundo exemplo, <code>fs.readFile</code> (um método assíncrono fornecido pelo Node) lê o arquivo e, quando termina, chama a função de <em>callback</em> com um erro ou o conteúdo do arquivo. Enquanto isso, o programa pode continuar a execução do código.</p><p>Uma função de <em>callback</em> assíncrona pode ser chamada quando um evento acontece ou quando uma tarefa é concluída. Ela evita o bloqueio, permitindo que outro código seja executado enquanto isso.</p><p>Em vez de o código ser lido de cima para baixo de modo procedural, os programas assíncronos podem executar funções diferentes em momentos diferentes com base na ordem e velocidade em que funções anteriores, como solicitações de http ou leituras do sistema de arquivos, acontecem. Eles são usados quando você não sabe quando alguma operação assíncrona será concluída.</p><p>É preciso, no entanto, evitar o chamado "<strong>inferno das callbacks</strong>", situação na qual as <em>callbacks</em> são aninhadas dentro de outras <em>callbacks</em> por vários níveis, tornando o código de difícil compreensão, além de difícil de manter e depurar.</p><h4 id="eventos-e-programa-o-orientada-a-eventos"><strong>Eventos e programação orientada a eventos</strong></h4><p><strong><strong>Event</strong>o<strong>s</strong></strong> são ações geradas pelo usuário ou pelo sistema, como um clique, um download de arquivo concluído ou um erro de hardware ou software.</p><p><strong>A programação orientada a eventos</strong> é um paradigma de programação no qual o fluxo do programa é determinado por eventos. Um programa orientado a eventos executa ações em resposta a eventos. Quando ocorre um evento, ele dispara uma função de <em>callback</em>.</p><p>Agora, vamos tentar entender o Node e ver como tudo isso se relaciona com ele.</p><h3 id="node-js-o-que-por-que-foi-criado-e-como-funciona"><strong><strong><strong>Node.js: </strong></strong>o que é<strong><strong>, </strong></strong>por que foi criado e como funciona<strong><strong>?</strong></strong></strong></h3><p>Colocado de maneira simples, o <strong><strong>Node.js</strong></strong> é uma plataforma que executa programas em JavaScript do lado do servidor que pode se comunicar com fontes de E/S, como redes e arquivos de sistemas.</p><p>Quando <a href="https://www.youtube.com/watch?v=ztspvPYybIY" rel="noopener">Ryan Dahl</a> criou o Node em 2009, ele disse que a E/S vinha sendo manipulada incorretamente, bloqueando todo o processo devido à programação síncrona.</p><p>Técnicas de servir conteúdo para a web tradicionais usavam o modelo de <em>threads</em>, ou seja, usavam uma <em>thread</em> para cada solicitação. Como, em uma operação de E/S, a solicitação passa a maior parte do tempo aguardando até ser concluída, cenários com uso intenso de E/S incorporam uma grande quantidade de recursos não utilizados (como a memória) associados a essas <em>threads</em>. Portanto, o modelo de "uma <em>thread</em> por solicitação" para um servidor é um modelo que não dimensiona muito bem.</p><p>Dahl argumentou que o software deveria ser capaz de realizar várias tarefas e propôs eliminar o tempo gasto aguardando que os resultados de E/S retornassem. Em vez do modelo de <em>threads</em>, ele disse que a maneira certa de lidar com várias conexões simultâneas era ter uma <em>thread </em>única, um <em>loop</em> de eventos e E/S sem bloqueio. Por exemplo, quando você faz uma consulta a um banco de dados, em vez de aguardar a resposta, você dá a ele uma função de <em>callback</em> para que sua execução possa rodar essa instrução e continuar fazendo outras coisas. Quando os resultados retornam, você pode executar a <em>callback</em>.</p><p>O <a href="https://nodejs.org/de/docs/guides/event-loop-timers-and-nexttick/#what-is-the-event-loop"><em>loop </em>de eventos</a> é o que permite que o Node.js execute operações de E/S sem bloqueio, apesar do fato de que o JavaScript é de <em>thread </em>única. O loop, que é executado na mesma <em>thread </em>que o código em JavaScript, pega uma tarefa do código e a executa. Se a tarefa for assíncrona ou uma operação de E/S, o <em>loop </em>a delegará para o <em>kernel </em>do sistema, como no caso de novas conexões com o servidor, ou para um <em>pool </em>de <em>threads</em>, como operações relacionadas ao sistema de arquivos. O <em>loop</em>, então, pega a próxima tarefa e a executa.</p><p>Como a maioria dos kernels modernos têm várias <em>threads</em>, eles podem lidar com várias operações em execução em segundo plano. Quando uma dessas operações é concluída (este é um evento), o <em>kernel </em>informa a Node.js para que a <em>callback</em> apropriada (aquela que dependia da conclusão da operação) possa ser adicionada à fila para, por fim, ser executada.</p><p>O nó controla as operações assíncronas inacabadas, enquanto o loop de eventos continua em loop para verificar se elas estão concluídas até que todas elas estejam.</p><p>Para acomodar o loop de eventos de <em>thread</em> única, o Node.js usa a biblioteca <a href="https://libuv.org/">libuv</a>, que, por sua vez, usa um <em>pool </em>de <em>threads </em>de tamanho fixo que lida com a execução de algumas das operações de E/S assíncronas não bloqueadoras em paralelo. As funções de chamada da <em>thread </em>principal lançam tarefas na fila de tarefas compartilhadas, que as <em>threads </em>no <em>pool </em>de <em>threads</em> resgatam e executam.</p><p>Funções do sistema inerentemente sem bloqueio, como a rede, são convertidas em soquetes sem bloqueio do lado do <em>kernel</em>, enquanto funções do sistema inerentemente bloqueadas, como E/S de arquivos, são executadas de maneira bloqueada em suas próprias <em>threads</em>. Quando uma <em>thread </em>no <em>pool </em>de <em>threads</em> conclui uma tarefa, ela informa a <em>thread </em>principal sobre isso, que, por sua vez, ativa e executa a <em>callback</em> registrada.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_pIEFRBvMqxpDipMnqkVprA.jpeg" class="kg-image" alt="1_pIEFRBvMqxpDipMnqkVprA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/1_pIEFRBvMqxpDipMnqkVprA.jpeg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_pIEFRBvMqxpDipMnqkVprA.jpeg 800w" sizes="(min-width: 720px) 720px" width="800" height="437" loading="lazy"><figcaption>Imagem da apresentação de Phillip Roberts na JSConf EU: <a href="https://www.youtube.com/watch?v=8aGhZQkoFbQ" rel="noopener">What the heck is the event loop anyway?</a></figcaption></figure><p>A imagem acima é retirada da apresentação de Philip Roberts na JSConf EU: <a href="https://www.youtube.com/watch?v=8aGhZQkoFbQ" rel="noopener">What the heck is the event loop anyway?</a> ("O que diabos é esse o <em>loop </em>de eventos?", em português). Recomendo assistir o vídeo inteiro (em inglês) para se ter uma ideia geral de como funciona o <em>loop </em>de eventos.</p><p>O diagrama explica como o <em>loop </em>de eventos funciona com o navegador, mas sua aparência é basicamente idêntica à do Node. Em vez de APIs da Web, teríamos APIs do Node.</p><p>De acordo com a apresentação, a pilha de chamadas (também conhecida como pilha de execução, "call stack" ou, simplesmente, "a stack") é uma estrutura de dados que registra onde no programa estamos. Se entrarmos em uma função, colocamos algo na pilha. Se retornarmos de uma função, nós a tiramos do topo da pilha.</p><p>É assim que o código no diagrama é processado quando o executamos:</p><ol><li>Colocamos <code>main()</code> na pilha (o próprio arquivo)</li><li>Colocamos <code>console.log('Hi');</code> na pilha, que é executado imediatamente, registrando "Hi" ("Olá") no console e sendo removido da pilha</li><li>Colocamos <code>setTimeout(cb, 5000)</code> na pila. <code>setTimeout</code> é uma API fornecida pelo navegador (no <em>back-end</em>, seria uma API do Node). Quando <code>setTimeout</code> é chamada com a função de <em>callback</em> e com os argumentos de atraso, o navegador aciona um temporizador com o tempo de atraso (no caso, 5 mil milissegundos)</li><li>A chamada de <code>setTimeout</code> é concluída e ela é removida da pilha</li><li>Colocamos <code>console.log(‘JSConfEU’);</code> na pilha, que executa imediatamente, registrando "JSConfEU" no console e é removida da pilha</li><li><code>main()</code> é removida da pilha</li><li>Após 5 mil milissegundos, o temporizador da API conclui e a função de <em>callback</em> é movida para a fila de tarefas</li><li>O <em>loop </em>de eventos verifica se a pilha está vazia, já que o JavaScript, por ser de <em>thread </em>única, só consegue fazer uma coisa por vez (<code>setTimeout</code> não é garantido, apenas um tempo mínimo para a execução). Se a pilha estiver vazia, ele pega a primeira coisa que estiver na fila e a envia para a pilha. Assim, o <em>loop</em> coloca a <em>callback</em> na pilha</li><li>A <em>callback </em>é executada, registra "there" (no final, temos a expressão "<em>Hi there</em>", algo como "Olá, pessoal!", registrado) no console e é removida da pilha. Isso encerra o processo</li></ol><p>Se quiser se aprofundar ainda mais nos detalhes de como o Node.js, a libuv, o <em>loop</em> de eventos e o <em>pool</em> de <em>threads </em>funcionam, sugiro conferir os recursos na seção se referências do final – em especial <a href="https://www.youtube.com/watch?v=cCOL7MC4Pl0" rel="noopener">esta</a>, <a href="https://www.youtube.com/watch?v=PNa9OMajw9w" rel="noopener">esta</a> e <a href="https://www.youtube.com/watch?v=sGTRmPiXD4Y" rel="noopener">esta</a> referências, juntamente com a <a href="https://nodejs.org/de/docs/guides/event-loop-timers-and-nexttick/#what-is-the-event-loop" rel="noopener">documentação do Node</a> (texto e vídeos em inglês).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_GYkdiL25aLDgkSW0phpAag.jpeg" class="kg-image" alt="1_GYkdiL25aLDgkSW0phpAag" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/1_GYkdiL25aLDgkSW0phpAag.jpeg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_GYkdiL25aLDgkSW0phpAag.jpeg 800w" sizes="(min-width: 720px) 720px" width="600" height="400" loading="lazy"><figcaption>O <em>loop</em> de eventos. Imagem da apresentação de Bert Belder: <a href="https://www.youtube.com/watch?v=PNa9OMajw9w" rel="noopener">Everything You Need to Know About Node.js Event Loop</a></figcaption></figure><h3 id="node-js-por-que-e-onde-us-lo"><strong>Node.js: por que e onde usá-lo<strong><strong>?</strong></strong></strong></h3><p>Como quase nenhuma função no Node executa diretamente a E/S, o processo nunca bloqueia (as operações de E/S são descarregadas e executadas de maneira assíncrona no sistema), tornando-se uma boa opção para desenvolver sistemas altamente escaláveis.</p><p>Devido ao seu <em>loop</em> de eventos orientado a eventos, <em>thread</em> única e modelo de E/S assíncrono sem bloqueio, o Node.js tem melhor desempenho em aplicações de uso intenso de E/S que exigem velocidade e escalabilidade com muitas conexões simultâneas, como <em>streaming </em>de vídeo e áudio, aplicações em tempo real, bate-papos ao vivo, aplicações de jogos, ferramentas de colaboração ou <em>software </em>de bolsa de valores.</p><p>O Node.js pode não ser a escolha certa para operações que exigem muito da CPU. Em vez disso, o modelo de <em>thread </em>tradicional pode ter um desempenho melhor.</p><h3 id="npm"><strong><strong><strong>npm</strong></strong></strong></h3><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_Qj1OTPHk-djj2C1Nnkn4VQ.png" class="kg-image" alt="1_Qj1OTPHk-djj2C1Nnkn4VQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2024/04/1_Qj1OTPHk-djj2C1Nnkn4VQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2024/04/1_Qj1OTPHk-djj2C1Nnkn4VQ.png 800w" sizes="(min-width: 720px) 720px" width="600" height="400" loading="lazy"></figure><p>O <strong><strong>npm</strong></strong> é o gerenciador de pacotes padrão do Node.js e é instalado no sistema quando o Node.js é instalado. Ele pode gerenciar pacotes que são dependências locais de um projeto específico, bem como ferramentas do JavaScript instaladas de modo global.</p><p>O site <a href="http://www.npmjs.com/" rel="noopener">www.npmjs.com</a> hospeda milhares de bibliotecas gratuitas para baixar e usar em seu programa para tornar o desenvolvimento mais rápido e eficiente. No entanto, como qualquer pessoa pode criar bibliotecas e não há processo de verificação para o envio, você deve ter cuidado com as de baixa qualidade, inseguras ou maliciosas. O npm depende de relatórios de usuários para remover pacotes se eles violarem as políticas e, para ajudar você a decidir, inclui estatísticas como número de <em>downloads</em> e número de pacotes dependentes.</p><h3 id="como-executar-c-digo-no-node-js"><strong>Como executar código no<strong><strong> Node.js</strong></strong></strong></h3><p>Comece instalando o Node no seu computador, se você ainda não o tiver. A maneira mais fácil é visitar <a href="https://nodejs.org/" rel="noopener">nodejs.org</a> e clicar no botão para fazer o <em>download</em>. A menos que você queira ou precise ter acesso aos recursos mais recentes, baixe a versão LTS (<em>Long Term Support</em> – em português, suporte de longa duração) para seu sistema operacional.</p><p>Você executa uma aplicação do Node a partir do terminal do seu computador. Por exemplo, faça um arquivo chamado "app.js" e adicione <code>console.log('Olá');</code> a ele. No seu terminal, mude o diretório para a pasta onde se encontra o arquivo e execute o comando <code>node app.js</code>. Você verá "Olá" no console. 🙂</p><h3 id="refer-ncias"><strong>Referências</strong></h3><p>Aqui temos alguns recursos interessantes que eu revisei durante a composição deste artigo.</p><p>Apresentações do Node.js feitas pelo criador (em inglês):</p><ul><li><a href="https://www.youtube.com/watch?v=ztspvPYybIY" rel="noopener">Apresentação original do Node.js</a>, feita por Ryan Dahl na JSConf 2009</li><li><a href="https://www.youtube.com/watch?v=M3BM9TB-8yA" rel="noopener">10 coisas das quais me arrependo com o Node.js</a>, feita por Ryan Dahl na JSConf EU 2018</li></ul><p>Apresentações sobre o Node, o <em>loop</em> de eventos e a biblioteca libuv (em inglês):</p><ul><li><a href="https://www.youtube.com/watch?v=8aGhZQkoFbQ" rel="noopener">What the heck is the event loop anyway?</a>, feita por Philip Roberts na JSConf EU</li><li><a href="https://www.youtube.com/watch?v=L0pjVcIsU6A" rel="noopener">Node.js Explained</a>, por Jeff Kunkle</li><li><a href="https://www.youtube.com/watch?v=cCOL7MC4Pl0" rel="noopener">In The Loop</a>, feita por Jake Archibald na JSConf Asia 2018</li><li><a href="https://www.youtube.com/watch?v=PNa9OMajw9w" rel="noopener">Everything You Need to Know About Node.js Event Loop</a>, por Bert Belder</li><li><a href="https://www.youtube.com/watch?v=sGTRmPiXD4Y" rel="noopener">A deep dive into libuv</a>, por Saul Ibarra Coretge na NodeConf EU 2016</li></ul><p>Documentação do Node (em inglês):</p><ul><li><a href="https://nodejs.org/en/about/" rel="noopener">About Node.js</a></li><li><a href="https://nodejs.org/de/docs/guides/event-loop-timers-and-nexttick/" rel="noopener">The Node.js Event Loop, Timers, and process.nextTick()</a></li><li><a href="https://nodejs.org/en/docs/guides/blocking-vs-non-blocking/" rel="noopener">Overview of Blocking vs Non-Blocking</a></li></ul><p>Recursos adicionais (em inglês, exceto os recursos da Wikipédia):</p><ul><li><a href="https://github.com/maxogden/art-of-node" rel="noopener">Art of Node</a>, por Max Ogden</li><li><a href="http://callbackhell.com/" rel="noopener">Callback hell</a>, por Max Ogden</li><li><a href="https://stackoverflow.com/questions/10570246/what-is-non-blocking-or-asynchronous-i-o-in-node-js" rel="noopener">What is non-blocking or asynchronous I/O in Node.js?</a>, no Stack Overflow</li><li><a href="https://pt.wikipedia.org/wiki/Programa%C3%A7%C3%A3o_orientada_a_eventos">Programação orientada a eventos</a> na Wikipédia</li><li><a href="https://pt.wikipedia.org/wiki/Node.js">Node.js</a> na Wikipédia</li><li><a href="https://pt.wikipedia.org/wiki/Thread_(computa%C3%A7%C3%A3o)">Thread</a> na Wikipédia</li><li><a href="https://libuv.org/" rel="noopener">libuv</a></li></ul><p>Obrigado pela leitura.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Aprenda a lidar com a autenticação com o Node usando o Passport.js ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Antonio Erdeljac > Ajude o autor lendo o texto no original: ORIGINAL [https://www.signet.hr/learn-how-to-handle-authentication-with-node-using-passport-js/]  (em inglês) Neste artigo, você aprenderá a lidar com a autenticação para um servidor do Node usando o Passport.js. O artigo não tratará da autenticação no front-end. Use-o para configurar a autenticação no back-end ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/aprenda-a-lidar-com-a-autenticacao-com-o-node-usando-o-passport-js/</link>
                <guid isPermaLink="false">6527f9f1b73e2e03f70ce3b1</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Thu, 12 Oct 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_OUk_mC8ojHhStMEURjbI8g.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/learn-how-to-handle-authentication-with-node-using-passport-js-4a56ed18e81e/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Learn how to handle authentication with Node using Passport.js</a>
      </p><p>Escrito por: Antonio Erdeljac</p><blockquote>Ajude o autor lendo o texto no original: <a href="https://www.signet.hr/learn-how-to-handle-authentication-with-node-using-passport-js/" rel="noopener"><strong><strong>ORIGINAL</strong></strong></a> (em inglês)</blockquote><p>Neste artigo, você aprenderá a lidar com a <strong><strong>autentica</strong>ção</strong> para um servidor do Node usando o <strong><strong>Passport.js. </strong></strong>O artigo <strong>não tratará da autenticação no<strong> </strong>f<strong>ront</strong>-<strong>end. </strong></strong>Use-o para configurar a <strong><strong>autentica</strong>ção no back-end</strong> (geração de token para cada usuário e proteção das rotas).</p><p>Lembre-se de que, <strong>se tiver problemas em alguma das etapas<strong>, </strong>é possível consultar a qualquer momento o <a href="https://github.com/AntonioErdeljac/passport-tutorial">repositório do <strong>GitHub</strong></a></strong>.</p><h3 id="neste-artigo-ensinarei-o-seguinte-"><strong>Neste artigo, ensinarei o seguinte:</strong></h3><ul><li>Tratamento de rotas protegidas</li><li>Tratamento de tokens do JWT</li><li>Tratamento de respostas não autorizadas</li><li>Criação de uma API básica</li><li>Criação de modelos e esquemas</li></ul><h3 id="introdu-o"><strong>Introdução</strong></h3><h4 id="o-que-o-passport-js"><strong>O que é o Passport.js?</strong></h4><p>O Passport é um <em>middleware </em>de autenticação para o <a href="https://nodejs.org/" rel="noopener">Node.js</a>. Por ser extremamente flexível e modular, o Passport pode ser colocado sem problemas em qualquer aplicação para a web baseada no <a href="https://expressjs.com/" rel="noopener">Express</a>. Um conjunto extenso de estratégias dá suporte à autenticação usando um <a href="http://www.passportjs.org/docs/username-password/" rel="noopener">nome de usuário e senha</a>, <a href="http://www.passportjs.org/docs/facebook/" rel="noopener">Facebook</a>, <a href="http://www.passportjs.org/docs/twitter/" rel="noopener">Twitter</a> e <a href="http://www.passportjs.org/packages/" rel="noopener">muito mais</a>. Saiba mais sobre o Passport <a href="http://www.passportjs.org/" rel="noopener">aqui</a> (documentação em inglês).</p><h3 id="tutorial"><strong>Tutorial</strong></h3><h4 id="cria-o-do-servidor-do-node-desde-o-in-cio"><strong>Criação do servidor do Node desde o início</strong></h4><p>Crie um diretório com este arquivo "app.js"<strong><strong> </strong></strong>dentro dele:</p><figure class="kg-card kg-code-card"><pre><code>const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const session = require('express-session');
const cors = require('cors');
const mongoose = require('mongoose');
const errorHandler = require('errorhandler');

//Configure mongoose's promise to global promise
mongoose.promise = global.Promise;

//Configure isProduction variable
const isProduction = process.env.NODE_ENV === 'production';

//Initiate our app
const app = express();

//Configure our app
app.use(cors());
app.use(require('morgan')('dev'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({ secret: 'passport-tutorial', cookie: { maxAge: 60000 }, resave: false, saveUninitialized: false }));

if(!isProduction) {
  app.use(errorHandler());
}

//Configure Mongoose
mongoose.connect('mongodb://localhost/passport-tutorial');
mongoose.set('debug', true);

//Error handlers &amp; middlewares
if(!isProduction) {
  app.use((err, req, res) =&gt; {
    res.status(err.status || 500);

    res.json({
      errors: {
        message: err.message,
        error: err,
      },
    });
  });
}

app.use((err, req, res) =&gt; {
  res.status(err.status || 500);

  res.json({
    errors: {
      message: err.message,
      error: {},
    },
  });
});

app.listen(8000, () =&gt; console.log('Server running on http://localhost:8000/'));</code></pre><figcaption>app.js</figcaption></figure><p>Instalaremos o <a href="https://github.com/JakRowan/nodenom/blob/master/package.json" rel="noopener">nodemon</a> para facilitar o desenvolvimento.</p><pre><code>npm install -g nodemon</code></pre><p>Em seguida, vamos executar nosso "app.js" com ele.</p><pre><code class="language-bash">$ nodemon app.js</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_6kdVzksHWBymrCL20pNyzA.png" class="kg-image" alt="1_6kdVzksHWBymrCL20pNyzA" width="600" height="400" loading="lazy"><figcaption>Resultado esperado após executar o comando acima</figcaption></figure><h4 id="cria-o-do-modelo-de-usu-rio"><strong>Criação do modelo de usuário</strong></h4><p>Crie uma pasta chamada "models"<strong> </strong>e um arquivo "Users.js" dentro dessa pasta.<strong><strong> </strong></strong>É aí que definiremos nosso "UsersSchema", ou esquema de usuário. Usaremos <code>JWT</code> e <code>Crypto</code> para gerar o <code>hash</code> e o <code>salt</code> da string <code>password</code> recebida. Isso será usado mais tarde para a validação do usuário.</p><figure class="kg-card kg-code-card"><pre><code>const mongoose = require('mongoose');
const crypto = require('crypto');
const jwt = require('jsonwebtoken');

const { Schema } = mongoose;

const UsersSchema = new Schema({
  email: String,
  hash: String,
  salt: String,
});

UsersSchema.methods.setPassword = function(password) {
  this.salt = crypto.randomBytes(16).toString('hex');
  this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
};

UsersSchema.methods.validatePassword = function(password) {
  const hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
  return this.hash === hash;
};

UsersSchema.methods.generateJWT = function() {
  const today = new Date();
  const expirationDate = new Date(today);
  expirationDate.setDate(today.getDate() + 60);

  return jwt.sign({
    email: this.email,
    id: this._id,
    exp: parseInt(expirationDate.getTime() / 1000, 10),
  }, 'secret');
}

UsersSchema.methods.toAuthJSON = function() {
  return {
    _id: this._id,
    email: this.email,
    token: this.generateJWT(),
  };
};

mongoose.model('Users', UsersSchema);</code></pre><figcaption>Users.js</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_updLloBs1oJyVGplMGG4lQ.png" class="kg-image" alt="1_updLloBs1oJyVGplMGG4lQ" width="600" height="400" loading="lazy"><figcaption>Esta deve ser a estrutura de momento</figcaption></figure><p>Vamos adicionar nosso modelo recém-criado ao "app.js".</p><p>Adicione a linha seguinte ao "app.js" após configurar o <code>Mongoose</code>:</p><pre><code class="language-js">require('./models/Users');</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_YDxu9Xcr1SqDjQLzTVI9MA.png" class="kg-image" alt="1_YDxu9Xcr1SqDjQLzTVI9MA" width="600" height="400" loading="lazy"></figure><h4 id="configura-o-do-passport"><strong>Configuração do Passport</strong></h4><p>Crie uma pasta "config" com o arquivo "passport.js" dentro dela:</p><figure class="kg-card kg-code-card"><pre><code>const mongoose = require('mongoose');
const passport = require('passport');
const LocalStrategy = require('passport-local');

const Users = mongoose.model('Users');

passport.use(new LocalStrategy({
  usernameField: 'user[email]',
  passwordField: 'user[password]',
}, (email, password, done) =&gt; {
  Users.findOne({ email })
    .then((user) =&gt; {
      if(!user || !user.validatePassword(password)) {
        return done(null, false, { errors: { 'email or password': 'is invalid' } });
      }

      return done(null, user);
    }).catch(done);
}));</code></pre><figcaption>passport.js</figcaption></figure><p>Nesse arquivo, usamos o método <code>validatePassword</code> que definimos no <code>modelo de usuário</code>. Com base no resultado, retornamos um resultado diferente a partir da <code>LocalStrategy</code> (estratégia local) do Passport.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_TxTXHZEmeZoEff1TeW9hDA.png" class="kg-image" alt="1_TxTXHZEmeZoEff1TeW9hDA" width="600" height="400" loading="lazy"><figcaption>A estrutura agora deve ser esta</figcaption></figure><p>Vamos conectar o "passport.js" ao arquivo "app.js". Adicione a linha a seguir <strong>abaixo de todos os </strong><code>models</code>:</p><pre><code class="language-js">require('./config/passport');</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1__Uem3m6YuPSnhx9DZsJ5sA.png" class="kg-image" alt="1__Uem3m6YuPSnhx9DZsJ5sA" width="600" height="400" loading="lazy"><figcaption>A linha do <em>require </em>do Passport deve estar abaixo de todos os modelos</figcaption></figure><h4 id="roas-e-op-es-de-autentica-o"><strong>Roas e opções de autenticação</strong></h4><p>Crie uma pasta chamada "routes" com o arquivo "auth.js" dentro dela.</p><p>Nesse arquivo, usaremos a função <code>getTokenFromHeaders</code> para obter um <strong>token do J<strong>WT </strong></strong>que será enviado do <strong>lado do c<strong>lient </strong></strong>nos <strong>cabeçalhos (headers) da <strong>s</strong>olicitação</strong>. Também criaremos um objeto <code>auth</code> com as propriedades <code>optional</code> e <code>required</code>. Nós as usaremos mais tarde em nossas rotas.</p><figure class="kg-card kg-code-card"><pre><code>const jwt = require('express-jwt');

const getTokenFromHeaders = (req) =&gt; {
  const { headers: { authorization } } = req;

  if(authorization &amp;&amp; authorization.split(' ')[0] === 'Token') {
    return authorization.split(' ')[1];
  }
  return null;
};

const auth = {
  required: jwt({
    secret: 'secret',
    userProperty: 'payload',
    getToken: getTokenFromHeaders,
  }),
  optional: jwt({
    secret: 'secret',
    userProperty: 'payload',
    getToken: getTokenFromHeaders,
    credentialsRequired: false,
  }),
};

module.exports = auth;</code></pre><figcaption>auth.js</figcaption></figure><p>Na mesma pasta "routes", criamos um arquivo "index.js":</p><figure class="kg-card kg-code-card"><pre><code>const express = require('express');
const router = express.Router();

router.use('/api', require('./api'));

module.exports = router;</code></pre><figcaption>index.js da pasta routes</figcaption></figure><p>Agora, precisamos de uma pasta "api" dentro da pasta "routes", com outro arquivo "index.js" dentro dela.</p><figure class="kg-card kg-code-card"><pre><code>const express = require('express');
const router = express.Router();

router.use('/users', require('./users'));

module.exports = router;</code></pre><figcaption>index.js da pasta api</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_xT-bMD4RPNbS0trhqltHQQ.png" class="kg-image" alt="1_xT-bMD4RPNbS0trhqltHQQ" width="600" height="400" loading="lazy"><figcaption>Esta deve ser a estrutura de momento</figcaption></figure><p>Agora, criaremos o arquivo "users.js" que solicitamos em "api/index.js".</p><p>Primeiro, criaremos uma rota de <strong>autorização opcional</strong> <code>"/"</code>, que será usada para a criação de um modelo (registro).</p><pre><code class="language-js">router.post('/', auth.optional, (req, res, next) ...</code></pre><p>Depois disso, criaremos outra rota de <strong>autorização opcional</strong> <code>"/login"</code>. Ela será usada para ativar nossa configuração do Passport e validar uma senha recebida com e-mail.</p><pre><code class="language-js">router.post('/login', auth.optional, (req, res, next) ...</code></pre><p>Por fim, criaremos uma rota de <strong>autorização obrigatória</strong>, que será usada para retornar o usuário que está logado atualmente. Somente usuários logados (usuários com o token enviado com sucesso por meio dos cabeçalhos de solicitação) têm acesso a essa rota.</p><pre><code class="language-js">router.get('/current', auth.required, (req, res, next) ...</code></pre><figure class="kg-card kg-code-card"><pre><code>const mongoose = require('mongoose');
const passport = require('passport');
const router = require('express').Router();
const auth = require('../auth');
const Users = mongoose.model('Users');

//POST new user route (optional, everyone has access)
router.post('/', auth.optional, (req, res, next) =&gt; {
  const { body: { user } } = req;

  if(!user.email) {
    return res.status(422).json({
      errors: {
        email: 'is required',
      },
    });
  }

  if(!user.password) {
    return res.status(422).json({
      errors: {
        password: 'is required',
      },
    });
  }

  const finalUser = new Users(user);

  finalUser.setPassword(user.password);

  return finalUser.save()
    .then(() =&gt; res.json({ user: finalUser.toAuthJSON() }));
});

//POST login route (optional, everyone has access)
router.post('/login', auth.optional, (req, res, next) =&gt; {
  const { body: { user } } = req;

  if(!user.email) {
    return res.status(422).json({
      errors: {
        email: 'is required',
      },
    });
  }

  if(!user.password) {
    return res.status(422).json({
      errors: {
        password: 'is required',
      },
    });
  }

  return passport.authenticate('local', { session: false }, (err, passportUser, info) =&gt; {
    if(err) {
      return next(err);
    }

    if(passportUser) {
      const user = passportUser;
      user.token = passportUser.generateJWT();

      return res.json({ user: user.toAuthJSON() });
    }

    return status(400).info;
  })(req, res, next);
});

//GET current route (required, only authenticated users have access)
router.get('/current', auth.required, (req, res, next) =&gt; {
  const { payload: { id } } = req;

  return Users.findById(id)
    .then((user) =&gt; {
      if(!user) {
        return res.sendStatus(400);
      }

      return res.json({ user: user.toAuthJSON() });
    });
});

module.exports = router;</code></pre><figcaption>users.js</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_FhlHO36q_NTY73Qhw2Vfiw.png" class="kg-image" alt="1_FhlHO36q_NTY73Qhw2Vfiw" width="600" height="400" loading="lazy"><figcaption>Esta deve ser a estrutura atual</figcaption></figure><p>Vamos adicionar nossa pasta "routes" ao "app.js".<strong><strong> </strong></strong>Adicione esta linha <strong>abaixo do<strong> </strong></strong><code>require</code> <strong>do Passport</strong>:</p><pre><code class="language-js">app.use(require('./routes'));</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_B44dNEd8f0Ii5GDkNJ0fLQ.png" class="kg-image" alt="1_B44dNEd8f0Ii5GDkNJ0fLQ" width="600" height="400" loading="lazy"></figure><h3 id="teste-das-rotas"><strong>Teste das rotas</strong></h3><p>Usaremos o <a href="https://www.getpostman.com/" rel="noopener">Postman</a><strong><strong> </strong></strong>para enviar solicitações ao nosso servidor.</p><p>Nosso servidor aceita o <em>body </em>(corpo da solicitação) seguinte:</p><pre><code class="language-json">{
  "user": {
    "email": String,
    "password": String
  }
}</code></pre><h4 id="cria-o-de-uma-solicita-o-de-post-para-a-cria-o-de-um-usu-rio"><strong>Criação de uma solicitação de POST para a criação de um usuário</strong></h4><p><code>body</code> do teste:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_e_U1SfVcGty_8XAZ8gWuSQ.png" class="kg-image" alt="1_e_U1SfVcGty_8XAZ8gWuSQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/1_e_U1SfVcGty_8XAZ8gWuSQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_e_U1SfVcGty_8XAZ8gWuSQ.png 800w" sizes="(min-width: 720px) 720px" width="600" height="400" loading="lazy"></figure><p>Resposta:</p><pre><code class="language-json">{
    "user": {
        "_id": "5b0f38772c46910f16a058c5",
        "email": "erdeljac.antonio@gmail.com",
        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImVyZGVsamFjLmFudG9uaW9AZ21haWwuY29tIiwiaWQiOiI1YjBmMzg3NzJjNDY5MTBmMTZhMDU4YzUiLCJleHAiOjE1MzI5MDgxNTEsImlhdCI6MTUyNzcyNDE1MX0.4TWc1TzY6zToHx_O1Dl2I9Hf9krFTqPkNLHI5U9rn8c"
    }
}</code></pre><p>Agora, usaremos este token e o adicionaremos aos nossos "Headers" na configuração do Postman.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_3TqFAWgy1bULj-ECJRyKKw.png" class="kg-image" alt="1_3TqFAWgy1bULj-ECJRyKKw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/10/1_3TqFAWgy1bULj-ECJRyKKw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_3TqFAWgy1bULj-ECJRyKKw.png 800w" sizes="(min-width: 720px) 720px" width="600" height="400" loading="lazy"></figure><p>Vamos, agora, testar nossa rota acessível <strong>somente por autorização</strong>.</p><h4 id="cria-o-de-uma-solicita-o-de-get-para-retornar-o-usu-rio-logado-atualmente"><strong>Criação de uma solicitação de <strong><strong>GET </strong></strong>para retornar o usuário logado atualmente</strong></h4><p>URL de solicitação:</p><pre><code>GET http://localhost:8000/api/users/current</code></pre><p>Resposta:</p><pre><code class="language-json">{
    "user": {
        "_id": "5b0f38772c46910f16a058c5",
        "email": "erdeljac.antonio@gmail.com",
        "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImVyZGVsamFjLmFudG9uaW9AZ21haWwuY29tIiwiaWQiOiI1YjBmMzg3NzJjNDY5MTBmMTZhMDU4YzUiLCJleHAiOjE1MzI5MDgzMTgsImlhdCI6MTUyNzcyNDMxOH0.5UnA2mpS-_puPwwxZEb4VxRGFHX6qJ_Fn3pytgGaJT0"
    }
}</code></pre><p>Vamos tentar fazer o mesmo <strong>sem o <strong>token </strong>nos "<strong>Headers</strong>"</strong>.</p><p>Resposta:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/10/1_ggNxOl_DMzg6dklIJAKG3g.png" class="kg-image" alt="1_ggNxOl_DMzg6dklIJAKG3g" width="600" height="400" loading="lazy"></figure><h3 id="conclus-o"><strong>Conclusão</strong></h3><p>Agradeço a leitura deste tutorial. Se perceber erros, informe-os ao autor. <strong>Se tiver problemas em qualquer uma das etapas<strong>, </strong></strong>consulte <a href="https://github.com/AntonioErdeljac/passport-tutorial" rel="noopener">este repositório do GitHub</a>.</p><p>Você também pode entrar em contato com o autor por:</p><ul><li><a href="mailto: erdeljac.antonio@gmail.com">E-mail</a></li><li><a href="https://www.linkedin.com/in/antonio-erdeljac/" rel="noopener">Linkedin</a></li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Aprenda a usar variáveis de ambiente no Node ]]>
                </title>
                <description>
                    <![CDATA[ As variáveis de ambiente são uma parte fundamental do desenvolvimento em Node. Por alguma razão, porém, nunca fui atrás de como usá-las adequadamente. O motivo é, possivelmente, o fato de elas serem chamadas de "variáveis de ambiente". A expressão "variáveis de ambiente" por si só é um gatilho para o ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/aprenda-a-usar-variaveis-de-ambiente-no-node/</link>
                <guid isPermaLink="false">64ee693b78917103e8a16cac</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ João Eduardo Gomes ]]>
                </dc:creator>
                <pubDate>Wed, 27 Sep 2023 20:00:53 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/1_akTd5oP32aXargVxiCOB8g.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/heres-how-you-can-actually-use-node-environment-variables-8fdf98f53a0a/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Here’s how you can actually use Node environment variables</a>
      </p><p>As variáveis de ambiente são uma parte fundamental do desenvolvimento em Node. Por alguma razão, porém, nunca fui atrás de como usá-las adequadamente.</p><p>O motivo é, possivelmente, o fato de elas serem chamadas de "variáveis de ambiente".</p><p>A expressão "variáveis de ambiente" por si só é um gatilho para o meu trauma de tentar adicionar o caminho correto para o diretório Home do Java no Windows. Devo usar PATH ou JAVA_HOME? Ou ambos? Preciso colocar ponto e vírgula no final? POR QUE RAIOS ESTOU USANDO JAVA?</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/ALjN6DcPA7VdZAcLA1vpTCzYLdx1lU3NtbOW.png" class="kg-image" alt="ALjN6DcPA7VdZAcLA1vpTCzYLdx1lU3NtbOW" width="357" height="155" loading="lazy"><figcaption>SOCORRO</figcaption></figure><p>No Node, as variáveis de ambiente podem ser globais (como no Windows), mas geralmente são usadas em um processo específico que você deseja executar. Por exemplo, se você tiver uma aplicação para a web, talvez tenha variáveis de ambiente que definem:</p><ul><li>A porta HTTP a ser monitorada</li><li>A string que conecta ao banco de dados</li><li>O JAVA_HOME... espere... isso não — desculpe. Ainda estou me recuperando do trauma.</li></ul><p>Em contextos assim, as variáveis de ambiente são realmente mais como "ajustes de configuração". Viu como soa melhor dessa maneira?</p><p>Se você tem alguma experiência com .NET, talvez esteja familiarizado com o arquivo <code>web.config</code>. As variáveis de ambiente do Node funcionam de um jeito parecido com os ajustes feitos no <code>web.config</code> — são, basicamente, um modo de passar informações que você não quer deixar no código fonte.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/lPJ7qP4TxdCmfuP6yYy5vnHuoUa8WH23RSqh.png" class="kg-image" alt="lPJ7qP4TxdCmfuP6yYy5vnHuoUa8WH23RSqh" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/lPJ7qP4TxdCmfuP6yYy5vnHuoUa8WH23RSqh.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/lPJ7qP4TxdCmfuP6yYy5vnHuoUa8WH23RSqh.png 634w" width="634" height="581" loading="lazy"><figcaption>Citar a si mesmo é o auge da loucura</figcaption></figure><p>Como <strong>usar </strong>essas variáveis na sua aplicação do Node? Foi difícil encontrar esse conteúdo com a dose necessária de piadas com Java. Portanto, decidi criar eu mesmo. Aqui estão algumas maneiras de definir e de ler variáveis de ambiente nas suas aplicações do Node.</p><h4 id="passando-no-terminal">Passando no terminal</h4><p>Você pode passar variáveis de ambiente diretamente no terminal como parte do processo da sua aplicação do Node. Por exemplo: se você estiver rodando uma aplicação com o framework Express e se quiser passar um conteúdo para a porta 65534, pode fazer da seguinte maneira...</p><pre><code class="language-bash">PORT=65534 node bin/www</code></pre><p>Curiosidade: a porta 65535 é o maior valor de rede TCP/IP disponível. Como eu sei disso? <a href="https://stackoverflow.com/questions/113224/what-is-the-largest-tcp-ip-network-port-number-allowable-for-ipv4">StackOverflow, é claro</a> (texto em inglês). De que outra maneira as pessoas sabem das coisas? Só podemos, no entanto, chegar à porta 65534 para uma aplicação da web porque essa é a maior porta a qual o Chrome se conecta. Como eu sei <strong>isso? </strong>O <a href="https://www.freecodecamp.org/news/heres-how-you-can-actually-use-node-environment-variables-8fdf98f53a0a/undefined">Liran Tal</a> me disse nos comentários. Recomendo segui-lo. Diferente de mim, ele sabe o que está fazendo.</p><p>Para o caso de usar a variável no seu código, você poderia usar o objeto <code>process.env</code>.</p><pre><code class="language-js">var port = process.env.PORT;</code></pre><p>Aí, a coisa pode ficar feia. Se você tivesse uma string de conexão, provavelmente não gostaria de passar um monte variáveis no terminal. Isso faria parecer que você está acumulando diversos valores de configuração. Uma pessoa que se importa com você poderia organizar uma intervenção; o que seria constrangedor para todos os envolvidos.</p><pre><code>PORT=65534
DB_CONN="mongodb://react-cosmos-db:swQOhAsVjfHx3Q9VXh29T9U8xQNVGQ78lEQaL6yMNq3rOSA1WhUXHTOcmDf38Q8rg14NHtQLcUuMA==@react-cosmos-db.documents.azure.com:10255/?ssl=true&amp;replicaSet=globaldb"
SECRET_KEY="b6264fca-8adf-457f-a94f-5a4b0d1ca2b9"</code></pre><p>Isso não escala – e todo mundo quer escalar. De acordo com todos os arquitetos que conheci, a aplicação "escalar" é mais importante do que a aplicação funcionar.</p><p>Sendo assim, vamos tentar outra abordagem: os arquivos .env.</p><h4 id="usando-um-arquivo-env">Usando um arquivo .env</h4><p>O que os arquivos .env fazem é nos permitir armazenar nossas variáveis em um arquivo à parte. Você só precisa criar um arquivo <code>.env</code> no seu projeto e colocar as variáveis nele em linhas separadas.</p><pre><code>PORT=65534

DB_CONN="mongodb://react-cosmos-db:swQOhAsVjfHx3Q9VXh29T9U8xQNVGQ78lEQaL6yMNq3rOSA1WhUXHTOcmDf38Q8rg14NHtQLcUuMA==@react-cosmos-db.documents.azure.com:10255/?ssl=true&amp;replicaSet=globaldb"

SECRET_KEY="b6264fca-8adf-457f-a94f-5a4b0d1ca2b9"</code></pre><p>Existem diferentes maneiras de se ler esses valores, mas a opção mais simples é usar o pacote <code>dotenv</code> via npm.</p><pre><code class="language-bash">npm install dotenv --save</code></pre><p>Feito isso, você só precisa fazer uma requisição desse pacote no seu projeto sempre que precisar usar suas variáveis de ambiente. O pacote <code>dotenv</code> vai pegar o respectivo arquivo e carregar suas configurações no Node.</p><pre><code class="language-js">// Usando o dotenv para ler variáveis de um arquivo .env no Node:
require('dotenv').config();
var MongoClient = require('mongodb').MongoClient;

// Referenciando variáveis .env fora do objeto process.env:
MongoClient.connect(process.env.DB_CONN, function(err, db) {
  if(!err) {
    console.log("Conectado");
  }
});</code></pre><p>Dica importante: Não suba seus arquivos .env para o Github. Os valores armazenados ali devem ser mantidos em sigilo. O próprio Github vai enviar a você um e-mail alertando sobre isso. Não faça a mesma besteira que eu.</p><p>Certo — bacana. Isso, porém, é meio chato. Você precisa colocar esse código em cada arquivo em que deseja usar variáveis de ambiente <strong>E</strong> você deve enviar o <code>dotenv</code> para o ambiente de produção, onde não é exatamente necessário. Não sou muito fã de fazer <em>deploy </em>de código inútil, mas acho que isso descreve a minha carreira como um todo.</p><p>Felizmente, você está usando o <a href="https://code.visualstudio.com/?wt.mc_id=dotenv-medium-buhollan">VS Code</a> (você <strong>está usando </strong>o VS Code, certo?). Então, você tem algumas outras opções.</p><h4 id="trabalhando-com-arquivos-env-no-vs-code">Trabalhando com arquivos .env no VS Code</h4><p>Primeiramente, saiba que você pode <a href="https://marketplace.visualstudio.com/items?itemName=mikestead.dotenv&amp;wt.mc_id=dotenv-medium-buhollan">instalar a extensão DotENV</a> no seu VS Code. Ela vai fornecer um destaque visual na sintaxe dos seus arquivos .env.</p><p><a href="https://marketplace.visualstudio.com/items?itemName=mikestead.dotenv&amp;WT.mc_id=dotenv-medium-buhollan"><strong>DotENV - Visual Studio Marketplace</strong></a></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/5TqqPI4CyihReGrXCaFqLDEAADqD-AJtHS4Y.png" class="kg-image" alt="5TqqPI4CyihReGrXCaFqLDEAADqD-AJtHS4Y" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/5TqqPI4CyihReGrXCaFqLDEAADqD-AJtHS4Y.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/5TqqPI4CyihReGrXCaFqLDEAADqD-AJtHS4Y.png 800w" sizes="(min-width: 720px) 720px" width="800" height="590" loading="lazy"><figcaption>Do lixo ao luxo com o VS Code</figcaption></figure><p>O depurador do VS Code também oferece algumas opções mais convenientes para carregar valores de arquivos .env. Isso <strong>se</strong> você estiver usando o depurador do VS Code.</p><h4 id="configura-es-de-execu-o-do-vs-code">Configurações de execução do VS Code</h4><p>O depurador do Node para o VS Code (que já está presente nele – não precisa instalar nada para usá-lo) tem suporte para carregamento em arquivos .env por meio de configurações de execução. <a href="https://code.visualstudio.com/docs/nodejs/nodejs-debugging?WT.mc_id=dotenv-medium-buhollan">Leia mais sobre configurações de execução aqui</a> (texto em inglês).</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/f6NKkdg6vZOubtIzh4k4EGEVUWtvC7ZC88SK.gif" class="kg-image" alt="f6NKkdg6vZOubtIzh4k4EGEVUWtvC7ZC88SK" width="800" height="450" loading="lazy"></figure><p>Quando você cria uma configuração de execução básica do Node (clique na engrenagem e selecione "Node"), você pode fazer uma ou as duas seguintes ações:</p><p>A primeira é você simplesmente passar as variáveis para a configuração de execução.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/OKoRgCmVBQJG3p2ZQ9em6NaMIYwNauEwp6Wd.png" class="kg-image" alt="OKoRgCmVBQJG3p2ZQ9em6NaMIYwNauEwp6Wd" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/OKoRgCmVBQJG3p2ZQ9em6NaMIYwNauEwp6Wd.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/OKoRgCmVBQJG3p2ZQ9em6NaMIYwNauEwp6Wd.png 800w" sizes="(min-width: 720px) 720px" width="800" height="450" loading="lazy"></figure><p>É bacana e tal, mas, aqui, todos os valores precisam ser strings. Isso me incomoda um pouco. É um número, não uma string. O JavaScript só tem 3 tipos. Não quero perder um deles.</p><p>Existe um caminho mais fácil. Nós já aprendemos a amar os arquivos <code>.env</code>. Então, ao invés de passar os seus valores, podemos simplesmente informar ao VS Code o nome do arquivo .env em questão.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/5mkXYjMBORiWKSTBZzCcZTK33ubGUTFy7SuZ.png" class="kg-image" alt="5mkXYjMBORiWKSTBZzCcZTK33ubGUTFy7SuZ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/5mkXYjMBORiWKSTBZzCcZTK33ubGUTFy7SuZ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/5mkXYjMBORiWKSTBZzCcZTK33ubGUTFy7SuZ.png 800w" sizes="(min-width: 720px) 720px" width="800" height="450" loading="lazy"></figure><p>Desse modo, contanto que iniciemos nosso processo a partir do VS Code, os arquivos de variáveis de ambiente serão carregados. Não precisamos "mutilar" os números transformando-os em strings. Também não estamos enviando código inútil para o ambiente de produção. Ou, pelo menos, <strong>você</strong> não está.</p><h4 id="come-ando-com-o-npm-ao-inv-s-do-node">Começando com o NPM ao invés do Node</h4><p>Você pode ter chegado aqui pensando: "Burke, eu nunca rodei nada com o comando <code>node</code>. É sempre um script do npm como <code>npm start</code>".</p><p>Para casos assim, também é possível usar as configurações de execução do VS Code. Ao invés de usar um processo de execução padrão do Node, você adiciona a configuração "Launch Via NPM" (Executar via NPM).</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/7tUmGEn-i6T30kHkzfXYj5qzAK8rB6qMTZir.gif" class="kg-image" alt="7tUmGEn-i6T30kHkzfXYj5qzAK8rB6qMTZir" width="800" height="450" loading="lazy"></figure><p>Agora, você pode adicionar novamente seu arquivo .env na linha <code>envFile</code> e ajustar a linha <code>runtimeArgs</code> para rodar o script correto. Isso <em>normalmente </em>é feito com um comando "start" ou "debug".</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/bkDqIcWImMhXbMrGry73ABhvBWCG2x5Sy92k.png" class="kg-image" alt="bkDqIcWImMhXbMrGry73ABhvBWCG2x5Sy92k" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/bkDqIcWImMhXbMrGry73ABhvBWCG2x5Sy92k.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/bkDqIcWImMhXbMrGry73ABhvBWCG2x5Sy92k.png 800w" sizes="(min-width: 720px) 720px" width="800" height="450" loading="lazy"></figure><p><strong>Lembre-se de adicionar a <em>flag</em><strong> <code>--inspect</code> </strong>ao seu script npm para que o VS Code possa vincular o depurador a ele</strong>. Do contrário, a tarefa até vai ser executada, mas o depurador do VS Code vai desistir de continuar – assim como eu, tentando arranjar um encontro no ensino médio.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/tGcPy6sdBlu9sR1OD07VdHD9MuSgj9-uDb7K.gif" class="kg-image" alt="tGcPy6sdBlu9sR1OD07VdHD9MuSgj9-uDb7K" width="800" height="450" loading="lazy"></figure><h3 id="vari-veis-de-ambiente-em-produ-o">Variáveis de ambiente em produção</h3><p>Até agora, vimos como definir variáveis para o ambiente de desenvolvimento. Você provavelmente não vai usar arquivos .env em produção. As configurações de execução do VS Code não vão ser muito úteis em um servidor.</p><p>Em produção, as variáveis serão definidas de acordo com a sua plataforma escolhida. Se for a Azure, existem 3 maneiras diferentes de definir e gerenciar suas variáveis de ambiente.</p><p>A primeira maneira é usar o <a href="https://docs.microsoft.com/en-us/cli/azure/webapp/config/appsettings?view=azure-cli-latest&amp;wt.mc_id=dotenv-medium-buhollan">Azure CLI</a>.</p><pre><code class="language-bash">az webapp config appsettings set -g MyResourceGroup -n MyApp --settings PORT=65534</code></pre><p>Até funciona, mas... eca.</p><p>Outra maneira é usar o Azure Web Portal. Eu nem sempre uso um portal da web, mas, quando uso, é para definir variáveis de ambiente.</p><p>Na nomenclatura da Azure, elas são chamadas de "Application Settings" (Configurações da aplicação).</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/prz52i4eiyXapzYAPqEIQ9ggSnCYwFGTYWzi.png" class="kg-image" alt="prz52i4eiyXapzYAPqEIQ9ggSnCYwFGTYWzi" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/09/prz52i4eiyXapzYAPqEIQ9ggSnCYwFGTYWzi.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/09/prz52i4eiyXapzYAPqEIQ9ggSnCYwFGTYWzi.png 800w" sizes="(min-width: 720px) 720px" width="800" height="577" loading="lazy"></figure><p>Porém, como você está usando o VS Code, pode instalar a extensão Azure App Service para gerenciar todas as configurações da aplicação <a href="https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azureappservice&amp;WT.mc_id=dotenv-medium-buhollan">diretamente do seu editor</a>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/09/4L4UwQ0TYob3wz--qcO2AQfmjFIxhMQ6ecax.gif" class="kg-image" alt="4L4UwQ0TYob3wz--qcO2AQfmjFIxhMQ6ecax" width="800" height="450" loading="lazy"></figure><p>Adoro não precisar sair do VS Code. Eu escreveria e-mails no VS Code, se pudesse.</p><p>UM MOMENTO!</p><p><a href="https://marketplace.visualstudio.com/items?itemName=ccccly.markdown-mail&amp;WT.mc_id=dotenv-medium-buhollan"><strong>markdown-mail - Visual Studio Marketplace</strong></a></p><h3 id="agora-voc-j-sabe">Agora você já sabe</h3><p>Agora você já sabe o que eu sei — o que não é muito, diga-se de passagem — e sinto que cumpri meu objetivo de fornecer uma pitada de piadas com Java ao longo do caminho. Porém, caso eu não tenha conseguido, aqui vai uma:</p><blockquote>Java é uma ferramenta muito poderosa para transformar XML em traços de erro.<br><br>- Autor desconhecido</blockquote><p><em>Observação: a maior parte das piadas é apenas uma tentativa ruim de fazer humor, parte dessa tentativa feita às custas do Java. Sei que não é legal fazer isso, mas, com o Java, é bem fácil. Afinal, as piadas não se escrevem sozinhas.</em></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como instalar o Node em um MacOS, Linux ou Windows usando o NVM ]]>
                </title>
                <description>
                    <![CDATA[ > Nota da tradução: no momento desta tradução, a versão mais recente do Node é a versão 18.17.1. Se você quiser utilizar a versão mais recente do Node, substitua "12.18.1" sempre que aparecer em alguma instrução do texto por "18.17.1". > A versão mais recente do script "nvm-sh" é a ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-instalar-o-node-em-um-macos-linux-ou-windows-usando-o-nvm/</link>
                <guid isPermaLink="false">64e4228f78917103e8a161ab</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Giálisson Rocha ]]>
                </dc:creator>
                <pubDate>Tue, 22 Aug 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/08/5f9c9a1a740569d1a4ca238a.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-install-node-in-your-machines-macos-linux-windows/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Install Node on a MacOS, Linux, or Windows Machine Using NVM</a>
      </p><blockquote><strong>Nota da tradução:</strong> no momento desta tradução, a versão mais recente do Node é a versão 18.17.1. Se você quiser utilizar a versão mais recente do Node, substitua "12.18.1" sempre que aparecer em alguma instrução do texto por "18.17.1".</blockquote><blockquote>A versão mais recente do script "nvm-sh" é a 'v0.39.5'. Caso queira utilizar essa versão, substitua 'v0.35.3' pelo 'v0.39.5' no comando utilizado durante a instalação no Mac OS e Linux.</blockquote><p>Antes de começar a criar aplicações incríveis com o NodeJS, você precisa instalá-lo. Felizmente, a instalação do NodeJS é muito simples.</p><p>Neste tutorial, abordaremos como instalar o NodeJS/NPM no</p><ul><li>macOS/Linux</li><li>Windows</li></ul><p>Depois de instalar o NodeJS/NPM, você pode facilmente fazer o <em>upgrade</em>/<em>downgrade </em>para qualquer versão do Node com um comando. O tutorial em vídeo a seguir mostra como fazer o download do NodeJS em sua máquina.</p><h2 id="guia-de-instala-o-para-mac-os-e-linux">Guia de instalação para Mac OS e Linux</h2><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 75%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="150" src="https://www.youtube.com/embed/TmT_CGFnUuM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="Install NodeJS/NPM on your macOS/Linux machines with NVM (node version manager)" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><p>Abra um novo terminal. Digite o seguinte e pressione Enter:</p><pre><code>curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
</code></pre><p>Feche seu terminal, abra um novo e digite o seguinte:</p><pre><code>nvm ls
</code></pre><p>Você verá algo parecido com isto:</p><pre><code>system
iojs -&gt; N/A (default)
node -&gt; stable (-&gt; N/A) (default)
unstable -&gt; N/A (default)
nvm_list_aliases:36: no matches found: /Users/adeelimran/.nvm/alias/lts/*
</code></pre><p>Em seguida, em seu terminal, digite:</p><pre><code>nvm install 12.18.1
</code></pre><p>Depois de instalado, ele estará pronta para ser usado. Para usar essa versão, basta digitar isto em seu terminal:</p><pre><code>nvm use 12.18.1
</code></pre><p>Agora que ele está instalado, vamos verificá-lo fazendo o seguinte:</p><figure class="kg-card kg-code-card"><pre><code>node --v</code></pre><figcaption>O resultado será "v12.18.1" (que é a versão do NodeJS que você acabou de instalar)</figcaption></figure><p>É isso! Você terminou. Divirta-se.</p><p>Agora, se no futuro, por algum motivo, você quiser desinstalar o NVM (do inglês, <em>Node Version Manager</em>), basta abrir o terminal e digitar o seguinte:</p><pre><code>rm -rf $NVM_DIR ~/.npm ~/.bower
</code></pre><h2 id="guia-de-instala-o-para-windows">Guia de instalação para Windows</h2><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/QWdSDo9V1Ho?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="Install NodeJS/NPM on your Windows machines with NVM (node version manager)" name="fitvid1"></iframe>
          </div>
        </div>
      </figure><p>Primeiro, acesse a área de versões no repositório do <code>nvm-windows</code> <a href="https://github.com/coreybutler/nvm-windows/releases">https://github.com/coreybutler/nvm-windows/releases</a>.</p><p>Em seguida, escolha o arquivo <code>nvm-setup.zip</code> e faça o download.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/news/content/images/2020/06/tempsnip.png" class="kg-image" alt="tempsnip" width="600" height="400" loading="lazy"></figure><p>Depois que o arquivo for baixado, descompacte-o, clique no instalador e siga as etapas (estou usando o <a href="https://www.7-zip.org/">7zip</a> para extração de arquivos .zip, porque ele é GRATUITO).</p><p>Em seguida, para verificar se o <code>nvm</code> está instalado corretamente, abra um novo terminal de prompt de comando e digite <code>nvm</code>. Quando for verificado que ele está instalado, você poderá passar para a próxima etapa.</p><p>Instale o NodeJS usando o <code>nvm</code> desta maneira:</p><pre><code>nvm install &lt;numero_da_versao&gt; // Vamos supor que seja a versão 12.18.1</code></pre><p>A versão pode ser uma versão do NodeJS ou "latest" (para a versão mais recente e estável).</p><p>Para usar a versão específica do node que você acabou de instalar, basta digitar o seguinte no terminal:</p><pre><code>nvm use 12.18.1;</code></pre><p>Verifique a versão do node com node -v. Isso deve mostrar a versão 12.18.1 em seu terminal.</p><p>Se você quiser instalar outra versão do Node, repita as etapas com uma versão diferente.</p><p>Agora, você deve ter uma versão funcional do NodeJS em execução em sua máquina. Boa programação, pessoal. 🙂</p><p>Se você achou este guia útil, envie uma mensagem para o autor no <a href="https://twitter.com/adeelibr">Twitter</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como fazer o deploy da sua aplicação para a web usando Express.js e Heroku ]]>
                </title>
                <description>
                    <![CDATA[ Se você é novo no mundo do desenvolvimento para a web, provavelmente passará bastante tempo aprendendo a construir sites estáticos, com HTML, CSS e JavaScript. Você pode, então, começar a aprender como usar frameworks populares, como React, VueJS ou Angular. Porém, depois de experimentar algumas ideias novas e executar alguns ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-fazer-o-deploy-da-sua-aplicacao-para-a-web-usando-o-express-js-e-o-heroku/</link>
                <guid isPermaLink="false">648e17a9d1454605b613ff08</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Viviane Martini ]]>
                </dc:creator>
                <pubDate>Mon, 21 Aug 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/08/5f9c9c56740569d1a4ca317c.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-deploy-your-site-using-express-and-heroku/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to deploy your app to the web using Express.js and Heroku</a>
      </p><p>Se você é novo no mundo do desenvolvimento para a web, provavelmente passará bastante tempo aprendendo a construir sites estáticos, com HTML, CSS e JavaScript.</p><p>Você pode, então, começar a aprender como usar <em>frameworks </em>populares, como React, VueJS ou Angular.</p><p>Porém, depois de experimentar algumas ideias novas e executar alguns sites localmente, você pode se perguntar como realmente implantar ou fazer o<em> deploy</em> de seu site ou aplicação. Ocorre que, às vezes, pode ser difícil saber por onde começar.</p><p>Pessoalmente, acho que executar um servidor do Express hospedado no Heroku é uma das maneiras mais simples de começar. Este artigo mostrará como fazer isso.</p><p>O Heroku é uma plataforma de nuvem que suporta diversas linguagens de programação e <em>frameworks </em>diferentes.</p><p>Este não é um artigo patrocinado – é claro que existem muitas outras soluções disponíveis, como:</p><ul><li><a href="https://www.digitalocean.com/">Digital Ocean</a></li><li><a href="https://aws.amazon.com/">Amazon Web Services</a></li><li><a href="https://azure.microsoft.com/en-gb/">Azure</a></li><li><a href="https://cloud.google.com/">Google Cloud Platform</a></li><li><a href="https://www.netlify.com/">Netlify</a></li><li><a href="https://zeit.co/">ZEIT Now</a></li></ul><p>Confira todos eles e veja qual se adapta melhor às suas necessidades.</p><p>Pessoalmente, achei o Heroku o mais rápido e fácil de usar. Ele é "pronto para uso". A versão gratuita é um pouco limitada em termos de recursos. No entanto, posso recomendar com confiança para testes.</p><blockquote>Nota da tradução: ao final de 2022, o Heroku encerrou o <em><strong>tier</strong> </em>gratuito para implantação. Os planos mensais básicos por lá, no momento desta tradução, custam 5 dólares ao mês.</blockquote><p>Este exemplo hospedará um site simples usando um servidor do Express. Aqui estão os passos principais:</p><ol><li>Configurar o Heroku, o Git e o npm</li><li>Criar um servidor do Express.js</li><li>Criar arquivos estáticos</li><li>Implantar no Heroku</li></ol><p>Deve levar cerca de 25 minutos no total (ou mais, se você quiser gastar mais tempo nos arquivos estáticos).</p><p>Este artigo pressupõe que você já saiba:</p><ul><li>O básico de HTML, CSS e JavaScript </li><li>Uso básico da linha de comando</li><li>Git de nível iniciante para controle de versão</li></ul><p>Você pode encontrar todo o código <a href="https://github.com/pg0408/lorem-ipsum-demo">neste repositório</a>.</p><h3 id="configurando">Configurando</h3><p>O primeiro passo em qualquer projeto é configurar todas as ferramentas que você sabe que vai precisar.</p><p>Você vai precisar ter:</p><ul><li>Node e npm instalados em sua máquina local (leia como fazer isso <a href="https://nodejs.org/en/download">aqui</a> – em inglês)</li><li>Git instalado (<a href="https://www.atlassian.com/git/tutorials/install-git">leia este guia</a> – em inglês)</li><li>O CLI do Heroku instalado (<a href="https://devcenter.heroku.com/articles/heroku-cli#download-and-install">aqui está como fazer isso</a> – em inglês)</li></ul><p><strong><strong>1.</strong> Crie um diretório e inicialize um repositório Git</strong></p><p>A partir da linha de comando, crie um diretório de projeto e entre nesse diretório.</p><pre><code>$ mkdir lorem-ipsum-demo
$ cd lorem-ipsum-demo</code></pre><p>Agora que você está na pasta do projeto, inicialize um novo repositório do Git.</p><p>⚠️Esse passo é importante porque o <a href="https://devcenter.heroku.com/articles/how-heroku-works#deploying-applications">Heroku depende do Git</a> (texo em inglês) para implantar o código da sua máquina local em seus servidores na nuvem. ⚠️</p><pre><code>$ git init</code></pre><p>Como etapa final, você pode criar um arquivo README.md para editar posteriormente.</p><pre><code>$ echo "Edit me later" &gt; README.md</code></pre><p><strong><strong>2. </strong>Faça login na CLI do Heroku e crie um projeto</strong></p><p>Você pode fazer login no Heroku usando a CLI (interface de linha de comando) do Heroku. Você precisará ter uma conta no Heroku para fazer isso.</p><p>Existem duas opções aqui. Por padrão, o Heroku permite que você faça login por meio do navegador da web. Adicionar a flag <code>-i</code> permite que você faça login por meio da linha de comando.</p><pre><code>$ heroku login -i</code></pre><p>Agora, você pode criar um projeto no Heroku. Eu chamei o meu de <code>lorem-ipsum-demo</code>.</p><pre><code>$ heroku create lorem-ipsum-demo</code></pre><p>Nomeando seu projeto:</p><ul><li>O Heroku gerará um nome aleatório para o seu projeto se você não especificar um no comando.</li><li>O nome fará parte do URL que você pode usar para acessar seu projeto. Assim, escolha um de que você goste.</li><li>Isso também significa que você precisa escolher um nome de projeto único que ninguém mais tenha usado.</li><li>É possível renomear seu projeto posteriormente (não se preocupe muito em encontrar o nome perfeito agora).</li></ul><p><strong><strong>3. </strong>Inicialize um novo projeto com o npm e instale o Express.js</strong></p><p>Em seguida, você pode inicializar um novo projeto com o npm criando um arquivo <code>package.json</code>. Use o comando abaixo para fazer isso.</p><p>⚠️Essa etapa é crucial. O Heroku depende de você fornecer um arquivo package.json para saber que este é um projeto do Node.js ao criar sua aplicação.⚠️</p><pre><code>$ npm init -y</code></pre><p>Em seguida, instale o Express. O Express é um <em>framework </em>de servidor amplamente utilizado para o NodeJS.</p><pre><code>$ npm install express --save</code></pre><p>Finalmente, você está pronto para começar a programar!</p><h3 id="criando-um-servidor-do-express-simples">Criando um servidor do Express simples</h3><p>O próximo passo é criar um arquivo chamado <code>app.js</code>, que executa um servidor do Express localmente.</p><pre><code>$ touch app.js</code></pre><p>Esse arquivo será o ponto de entrada para a aplicação quando estiver pronta. Isso significa que o único comando necessário para iniciar a aplicação será:</p><pre><code>$ node app.js</code></pre><p>Primeiro, no entanto, você precisa escrever algum código no arquivo.</p><p><strong><strong>4.</strong> Edite o conteúdo do app.js</strong></p><p>Abra o <code>app.js</code> no seu editor favorito. Escreva o código mostrado abaixo e clique em salvar.</p><pre><code class="language-javascript">// Crie uma aplicação do express
const express = require("express")
const app = express()

// Use o middleware express-static
app.use(express.static("public"))

// Defina a primeira rota
app.get("/", function (req, res) {
  res.send("&lt;h1&gt;Hello World!&lt;/h1&gt;")
})

// Inicie o servidor escutando por solicitações
app.listen(process.env.PORT || 3000, 
	() =&gt; console.log("Server is running..."));</code></pre><p>Os comentários devem ajudar a indicar o que está acontecendo. Vamos, porém, dividir rapidamente o código para entendê-lo melhor:</p><ul><li>As primeiras duas linhas simplesmente requerem o módulo do Express e criam uma instância da aplicação.</li><li>A próxima linha requer o uso do middleware <code>express.static</code>. Ele permite que você sirva arquivos estáticos (como HTML, CSS e JavaScript) do diretório que você especificar. Nesse caso, os arquivos serão servidos de uma pasta chamada <code>public</code>.</li><li>A próxima linha usa <code>app.get()</code> para definir uma rota de URL. Quaisquer solicitações de URL para o URL raiz serão respondidas com uma mensagem de HTML simples.</li><li>A parte final inicia o servidor. Ele verifica qual porta o Heroku usará ou, se você estiver executando localmente, a porta padrão será 3000.</li></ul><p>⚠️O uso de <code>process.env.PORT || 3000</code> na última linha é importante para implantar sua aplicação com sucesso. ⚠️</p><p>Salve <code>app.js</code> e inicie o servidor com:</p><pre><code>$ node app.js</code></pre><p>Você, então, pode visitar <a href="http://localhost:3000/">localhost:3000</a> em seu navegador e verificar se o servidor está em execução.</p><h3 id="crie-seus-arquivos-est-ticos">Crie seus arquivos estáticos</h3><p>O próximo passo é criar seus arquivos estáticos. Esses são os arquivos HTML, CSS e JavaScript que você fornecerá sempre que um usuário visitar seu projeto.</p><p>Lembre-se de que, no <code>app.js</code>, você informou ao middleware <code>express.static</code> para servir arquivos estáticos a partir do diretório <code>public</code>.</p><p>O primeiro passo, é claro, é criar esse diretório e os arquivos que ele conterá.</p><pre><code>$ mkdir public
$ cd public
$ touch index.html styles.css script.js</code></pre><p><strong><strong>5. Edit</strong>e<strong> </strong>o arquivo<strong> HTML </strong></strong></p><p>Abra o arquivo <code>index.html</code> no seu editor de texto preferido. Essa será a estrutura básica da página que você fornecerá aos seus visitantes.</p><p>O exemplo abaixo cria uma página inicial simples para um gerador de <a href="https://en.wikipedia.org/wiki/Lorem_ipsum">Lorem Ipsum</a>, mas você pode ser tão criativo quanto quiser aqui.</p><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;head&gt;
	&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"&gt;&lt;/script&gt;
	&lt;link href="https://fonts.googleapis.com/css?family=Alegreya|Source+Sans+Pro&amp;display=swap" rel="stylesheet"&gt;
	&lt;link rel="stylesheet" type="text/css" href="styles.css"&gt;
&lt;/head&gt;
&lt;html&gt;
&lt;body&gt;
&lt;h1&gt;Lorem Ipsum generator&lt;/h1&gt;
  &lt;p&gt;How many paragraphs do you want to generate?&lt;/p&gt;
  &lt;input type="number" id="quantity" min="1" max="20" value="1"&gt;
  &lt;button id="generate"&gt;Generate&lt;/button&gt;
  &lt;button id="copy"&gt;Copy!&lt;/button&gt;
&lt;div id="lorem"&gt;
&lt;/div&gt;
&lt;script type="text/javascript" src="script.js"&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><p><strong><strong>6. Edit</strong>e<strong> </strong>o arquivo<strong> CSS</strong></strong></p><p>A próxima etapa é editar o arquivo <code>styles.css</code>. Certifique-se de que ele esteja vinculado ao seu arquivo HTML.</p><p>O CSS abaixo é para o exemplo do Lorem Ipsum. Novamente, sinta-se à vontade para ser tão criativo quanto desejar.</p><pre><code class="language-css">h1 {
	font-family: 'Alegreya' ;
}

body {
	font-family: 'Source Sans Pro' ;
	width: 50%;
	margin-left: 25%;
	text-align: justify;
	line-height: 1.7;
	font-size: 18px;
}

input {
	font-size: 18px;
	text-align: center;
}

button {
	font-size: 18px;
	color: #fff;
}

#generate {
	background-color: #09f;
}

#copy {
	background-color: #0c6;
}</code></pre><p><strong><strong>7. Edit</strong>e o arquivo<strong> JavaScript</strong></strong></p><p>Por fim, você pode querer editar o arquivo JavaScript <code>script.js</code>. Isso permitirá tornar sua página mais interativa.</p><p>O código abaixo define duas funções básicas para o gerador de Lorem Ipsum. Sim, eu usei <a href="https://jquery.com/">JQuery</a> - é rápido e fácil de trabalhar.</p><pre><code class="language-javascript">$("#generate").click(function(){
	var lorem = $("#lorem");
	lorem.html("");
	var quantity = $("#quantity")[0].valueAsNumber;
	var data = ["Lorem ipsum", "quia dolor sit", "amet", "consectetur"];
	for(var i = 0; i &lt; quantity; i++){
		lorem.append("&lt;p&gt;"+data[i]+"&lt;/p&gt;");
	}
})

$("#copy").click(function() {
	var range = document.createRange();
	range.selectNode($("#lorem")[0]);
	window.getSelection().removeAllRanges();
	window.getSelection().addRange(range);
	document.execCommand("copy");
	window.getSelection().removeAllRanges();
	}
)</code></pre><p>Observe que, aqui, a lista de <code>data</code> foi cortada para facilitar a exibição. Na aplicação real, é uma lista muito mais longa de parágrafos completos. Você pode ver o arquivo completo no repositório ou consultar <a href="http://www.thelatinlibrary.com/cicero/fin1.shtml">aqui a fonte original</a>.</p><p><strong>Implantando sua aplicação</strong></p><p>Após escrever seu código estático e verificar se tudo funciona conforme o esperado, você pode se preparar para implantar no Heroku.</p><p>No entanto, há mais algumas coisas a fazer.</p><p><strong><strong>8. Cr</strong>ie um<strong> Procfile</strong></strong></p><p>O Heroku precisará de um Procfile para saber como executar sua aplicação.</p><p>Um Procfile é um "arquivo de processo" que informa ao Heroku qual comando executar para gerenciar um determinado processo. Neste caso, o comando dirá ao Heroku como iniciar seu servidor na web.</p><p>Use o comando abaixo para criar o arquivo.</p><p>⚠️Este é um passo importante, pois sem um Procfile, o Heroku não pode colocar seu servidor on-line. ⚠️</p><pre><code>$ echo "web: node app.js" &gt; Procfile</code></pre><p>Observe que o Procfile não possui uma extensão de arquivo (e.g., ".txt", ".json").</p><p>Além disso, observe como o comando <code>node app.js</code> é o mesmo usado localmente para executar o servidor.</p><p><strong><strong>9. </strong>Adicione e faça <em>commit </em>dos arquivos no Git</strong></p><p>Lembre-se de que você iniciou um repositório Git ao configurar. Talvez você já tenha adicionado e feito <em>commit </em>dos arquivos conforme avançava.</p><p>Antes de implantar no Heroku, certifique-se de adicionar todos os arquivos relevantes e fazer <em>commit </em>deles.</p><pre><code>$ git add .
$ git commit -m "pronto para o deploy"</code></pre><p>O último passo é fazer <em>push </em>para a <em>branch </em><code>master</code> do Heroku.</p><pre><code>$ git push heroku master</code></pre><p>Você deve ver a linha de comando imprimir uma série de informações enquanto o Heroku cria e implanta sua aplicação.</p><p>A linha a ser procurada é: <code>Verifying deploy... done.</code></p><p>Isso mostra que a criação foi bem-sucedida.</p><p>Agora você pode abrir o navegador e visitar nome-do-seu-projeto.herokuapp.com. Sua aplicação será hospedada na web para todos visitarem!</p><h3 id="breve-resumo">Breve resumo</h3><p>Abaixo estão os passos a serem seguidos para implantar uma aplicação do Express simples no Heroku:</p><ol><li>Crie um diretório e inicialize um repositório do Git</li><li>Faça login na CLI do Heroku e crie um projeto</li><li>Inicialize um novo projeto com o npm e instale o Express.js</li><li>Edite o conteúdo de app.js</li><li>Edite os arquivos estáticos HTML, CSS e JavaScript</li><li>Crie um Procfile</li><li>Adicione e faça <em>commit </em>no Git, depois faça <em>push </em>para a <em>branch </em><code>master</code> do Heroku</li></ol><h3 id="o-que-verificar-se-a-aplica-o-n-o-estiver-funcionando">O que verificar se a aplicação não estiver funcionando</h3><p>Às vezes, apesar das melhores intenções, os tutoriais na Internet não funcionam exatamente como você esperava.</p><p>Os passos abaixo devem ajudar a depurar alguns erros comuns que você pode encontrar:</p><ul><li>Você inicializou um repositório do Git na pasta do seu projeto? Verifique se você executou <code>git init</code>. O Heroku depende do Git para implantar o código da sua máquina local.</li><li>Você criou um arquivo <code>package.json</code>? Verifique se você executou <code>npm init -y</code>. O Heroku requer um arquivo <code>package.json</code> para reconhecer que é um projeto do Node.js.</li><li>O servidor está sendo executado? Verifique se seu <code>Procfile</code> usa o nome de arquivo correto para iniciar o servidor. Verifique se você tem: <code>web: node app.js</code> em vez de <code>web: node index.js</code>.</li><li>O Heroku sabe em qual porta escutar? Verifique se você usou <code>app.listen(process.env.PORT || 3000)</code> em seu arquivo <code>app.js</code>.</li><li>Seus arquivos estáticos têm erros? Verifique-os executando localmente e veja se há algum <em>bug</em>.</li></ul><p>Agradeço por ter chegado até aqui. Boa programação para você!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como usar o MongoDB e o Mongoose com o Node.js – melhores práticas para devs de back-end ]]>
                </title>
                <description>
                    <![CDATA[ O MongoDB é, sem dúvida, uma das opções de banco de dados NoSQL mais populares atualmente, tendo uma grande comunidade e um grande ecossistema. Neste artigo, analisaremos algumas das práticas recomendadas a serem seguidas ao configurar o MongoDB e o Mongoose com o Node.js. Pré-requisitos para este artigo Este artigo ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-usar-o-mongodb-e-o-mongoose-com-o-node-js-melhores-praticas-para-devs-de-back-end/</link>
                <guid isPermaLink="false">64d57869802b5c066d51a9d3</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Fri, 11 Aug 2023 01:07:51 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/08/node-mongodb-fundamentals.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/mongodb-mongoose-node-tutorial/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Use MongoDB + Mongoose with Node.js – Best Practices for Back End Devs</a>
      </p><p>O MongoDB é, sem dúvida, uma das opções de banco de dados NoSQL mais populares atualmente, tendo uma grande comunidade e um grande ecossistema.</p><p>Neste artigo, analisaremos algumas das práticas recomendadas a serem seguidas ao configurar o MongoDB e o Mongoose com o Node.js.</p><h2 id="pr-requisitos-para-este-artigo">Pré-requisitos para este artigo</h2><p>Este artigo é um dos <a href="https://codedamn.com/learning-paths/backend">caminhos de aprendizado de <em>back-end</em> da codedamn</a> (em inglês), onde começamos com os conceitos básicos de <em>back-end</em> e os abordamos em detalhes. Portanto, presumo que você já tenha alguma experiência com JavaScript (e Node.js).</p><p>Atualmente, estamos aqui:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/08/Screenshot-2020-10-20-at-9.29.47-PM.png" class="kg-image" alt="Screenshot-2020-10-20-at-9.29.47-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/08/Screenshot-2020-10-20-at-9.29.47-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/08/Screenshot-2020-10-20-at-9.29.47-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/08/Screenshot-2020-10-20-at-9.29.47-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/08/Screenshot-2020-10-20-at-9.29.47-PM.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1275" loading="lazy"></figure><p>Se você tem pouca experiência com Node.js/JavaScript ou <em>back-end</em> em geral, <a href="https://codedamn.com/learning-paths/backend">este é, provavelmente, um bom lugar para começar</a> (em inglês). Você também pode encontrar um <a href="https://codedamn.com/learn/node-mongodb-fundamentals">curso sobre Mongoose, MongoDB e Node.js aqui</a> (em inglês). Vamos lá!</p><h2 id="por-que-precisaremos-do-mongoose"><strong>Por que precisaremos do Mongoose?</strong></h2><p>Para entender por que precisamos do Mongoose, vamos entender como o MongoDB (e um banco de dados) funciona no nível da arquitetura.</p><ul><li>Você tem um servidor de banco de dados (servidor da comunidade do MongoDB, por exemplo)</li><li>Você tem um script do Node.js em execução (como um processo)</li></ul><p>O servidor do MongoDB escuta em um soquete TCP (normalmente) e o processo do Node.js pode se conectar a ele usando uma conexão TCP.</p><p>Além do TCP, o MongoDB também tem seu próprio protocolo para entender o que exatamente o <em>client</em> (nosso processo do Node.js) quer que o banco de dados faça.</p><p>Para essa comunicação, em vez de aprender as mensagens que temos que enviar na camada TCP, abstraímos isso com a ajuda de um software de "driver", chamado de <em>MongoDB driver</em>, neste caso. O <em>MongoDB driver</em> está disponível como um <a href="https://www.npmjs.com/package/mongodb">pacote do npm aqui</a>.</p><p>Agora, lembre-se, o <em>MongoDB driver</em> é responsável por conectar e abstrair para você as solicitações/respostas de comunicação de baixo nível – é até aí que você consegue ir sendo um desenvolvedor.</p><p>Como o MongoDB é um banco de dados sem esquema, ele oferece muito mais poder do que você precisa como iniciante. Mais potência significa mais área de superfície para erros. Você precisa reduzir sua área de superfície para gerar menos bugs e erros em seu código. Você precisa de algo mais.</p><p>Conheça o Mongoose. O Mongoose é uma abstração sobre o driver nativo do MongoDB (o pacote npm que mencionei acima).</p><p>A regra geral com abstrações (do jeito que eu entendo) é que, a cada abstração, você perde algum poder de operação de baixo nível. Isso, contudo, não significa necessariamente que seja ruim. Às vezes, isso aumenta a produtividade em mais de mil vezes, pois você nunca precisa realmente ter acesso total à API subjacente, de todo modo.</p><p>Uma boa maneira de pensar sobre isso é tecnicamente criar uma aplicação de bate-papo em tempo real, tanto em C, quanto em Python.</p><p>O exemplo do Python seria muito mais fácil e rápido para você, como desenvolvedor, implementar com maior produtividade.</p><p>O C <em>pode ser</em> mais eficiente, mas terá um custo enorme em produtividade/velocidade de desenvolvimento/bugs/travamentos. Além disso, na maioria das vezes, você não precisa ter o poder que o C oferece para implementar <em>websockets</em>.</p><p>Do mesmo modo, com o Mongoose, você pode limitar sua área de superfície de acesso à API de nível inferior, mas desbloquear muitos ganhos potenciais e uma boa DX (<em>Developer Experience</em>, ou, em português, experiência de desenvolvedor – em contraste com a experiência do usuário, ou UX).</p><h2 id="como-conectar-o-mongoose-e-o-mongodb"><strong>Como conectar o Mongoose e o MongoDB</strong></h2><p>Para começar, mostraremos rapidamente como conectar o banco de dados do MongoDB com o Mongoose:</p><pre><code class="language-js">mongoose.connect(DB_CONNECTION_STRING, {
	useNewUrlParser: true,
	useUnifiedTopology: true,
	useCreateIndex: true,
	useFindAndModify: false
})</code></pre><p>Esse formato de conexão garante que você esteja usando o novo <em>parser</em> de URL do Mongoose e que não esteja usando práticas já preteridas (do inglês, <em>deprecated</em>). Você pode ler em profundidade sobre todas essas mensagens de preterimento <a href="https://mongoosejs.com/docs/deprecations.html">aqui</a> (em inglês), se quiser.</p><h2 id="como-realizar-opera-es-com-o-mongoose"><strong>Como realizar operações com o Mongoose</strong></h2><p>Agora, discutiremos rapidamente as operações com o Mongoose e como devemos realizá-las.</p><p>O Mongoose traz opções para dois modos:</p><ol><li><em>Query </em>(em português, consulta) baseada no cursor</li><li><em>Query </em>de busca completa (em inglês, <em>full fetching query</em>)</li></ol><h3 id="query-baseada-no-cursor"><strong><em>Query </em>baseada no cursor</strong></h3><p>A <em>query</em> baseada no cursor significa que você trabalha com um único registro de cada vez enquanto busca um único ou um lote de documentos de cada vez no banco de dados. Esta é uma maneira eficiente de se trabalhar com grandes quantidades de dados em um ambiente de memória limitada.</p><p>Imagine que você tenha que fazer o <em>parsing</em> documentos de 10 GB em um servidor em nuvem de 1 GB/1 núcleo. Você não pode buscar toda a coleção, pois não caberá no seu sistema. O cursor é uma boa (e, talvez, a única) opção aqui.</p><h3 id="query-de-busca-completa"><strong><em>Query </em>de busca completa</strong></h3><p>Esse é o tipo de consulta em que você obtém a resposta completa da consulta de uma só vez. Na maioria das vezes, é isso que você vai usar. Portanto, vamos nos concentrar principalmente nesse método aqui.</p><h2 id="como-usar-os-modelos-do-mongoose"><strong>Como usar os modelos do Mongoose</strong></h2><p>Os modelos são o superpoder de Mongoose. Eles ajudam você a impor regras de "esquema" e fornecem uma integração perfeita do código do Node em chamadas de banco de dados.</p><p>O primeiro passo é definir um bom modelo:</p><pre><code>import mongoose from 'mongoose'

const CompletedSchema = new mongoose.Schema(
	{
		type: { type: String, enum: ['course', 'classroom'], required: true },
		parentslug: { type: String, required: true },
		slug: { type: String, required: true },
		userid: { type: String, required: true }
	},
	{ collection: 'completed' }
)

CompletedSchema.index({ slug: 1, userid: 1 }, { unique: true })

const model = mongoose.model('Completed', CompletedSchema)
export default model
</code></pre><p>Este é um exemplo cortado diretamente da base de código da codedamn. Algumas coisas interessantes que você deve observar aqui:</p><ol><li>Tente manter <code>required: true</code> em todos os campos que são obrigatórios. Isso pode poupar muitos problemas para você se você não usar um sistema de verificação de tipo estático como o TypeScript para ajudá-lo com nomes de propriedade corretos ao criar um objeto. Além disso, a validação gratuita também é muito legal.</li><li>Defina índices e campos exclusivos. A propriedade <code>unique</code> (exclusivo) também pode ser adicionada a um esquema. Os índices são um tema amplo, por isso não vou me aprofundar aqui. Em grande escala, porém, eles podem realmente ajudá-lo a acelerar muito suas consultas.</li><li>Defina um nome de coleção explicitamente. Embora o Mongoose possa dar, automaticamente, um nome à coleção com base no nome do modelo (aqui, por exemplo, <code>Completed</code>), isso é muita abstração na minha opinião. Você deve pelo menos saber sobre seus nomes de banco de dados e coleções em sua base de código.</li><li>Restrinja os valores, se puder, usando <em>enums</em>.</li></ol><h2 id="como-realizar-opera-es-do-crud"><strong>Como realizar operações do CRUD</strong></h2><p>CRUD significa <strong><strong>C</strong></strong>reate, <strong><strong>R</strong></strong>ead, <strong><strong>U</strong></strong>pdate e <strong><strong>D</strong></strong>elete (criar, ler, atualizar e excluir, respectivamente, em português). Essas são as quatro opções fundamentais com as quais você pode executar qualquer tipo de manipulação de dados em um banco de dados. Vamos ver rapidamente alguns exemplos dessas operações.</p><h3 id="a-opera-o-create"><strong>A operação <em>Create</em></strong></h3><p>Isso significa simplesmente criar um registro em um banco de dados. Vamos usar o modelo que definimos acima para criar um registro:</p><pre><code class="language-js">try {
    const res = await CompletedSchema.create(registro)
} catch(erro) {
	console.error(erro)
    // tratamento do erro
}</code></pre><p>Mais uma vez, algumas coisas a apontar aqui:</p><ol><li>Use <em>async-await</em> em vez de <em>callbacks </em>(é mais bonito – e não há muito benefício em termos de desempenho em se usar a outra opção)</li><li>Use blocos <em>try-catch</em> ao redor das <em>queries</em>, pois a <em>query </em><em>pode</em> falhar por diversas razões (registro duplicado, valor incorreto e assim por diante)</li></ol><h3 id="a-opera-o-read"><strong>A operação <em>Read</em></strong></h3><p>Isso significa ler os valores existentes do banco de dados. É simples como parece, mas há algumas coisas que você deve saber com relação ao Mongoose:</p><pre><code>const res = await CompletedSchema.find(info).lean()</code></pre><ol><li>Você percebeu a função <code>lean()</code>? Ela é muito útil para o desempenho. Por padrão, o Mongoose processa os documentos retornados do banco de dados e adiciona seus métodos <em>mágicos </em>a eles (por exemplo, <code>.save</code>)</li><li>Ao usar <code>.lean()</code>, o Mongoose retorna objetos em JSON simples em vez de documentos pesados em termos de memória e recursos. Isso torna as <em>queries</em> mais rápidas e faz com que pesem menos na CPU.</li><li>Porém, é possível omitir o <code>.lean()</code> se estiver, de fato, pensando em atualizar os dados (o que veremos a seguir)</li></ol><h3 id="a-opera-o-update"><strong>A operação <em>Update</em></strong></h3><p>Se você já tem um documento do Mongoose com você (sem utilizar o <code>.lean()</code>), pode simplesmente modificar a propriedade do objeto e salvá-lo usando <code>object.save()</code>:</p><pre><code>const doc = await CompletedSchema.findOne(info)
doc.slug = 'outra-coisa'
await doc.save()</code></pre><p>Lembre-se de que, aqui, duas chamadas ao banco de dados estão sendo feitas. A primeira é no <code>findOne</code> e a segunda é no <code>doc.save</code>.</p><p>Se puder, você deve sempre reduzir o número de solicitações que atingem o banco de dados (porque, se você estiver comparando memória, rede e disco, a rede é quase sempre a mais lenta).</p><p>No outro caso, você pode usar uma <em>query</em> como esta:</p><pre><code>const res = await CompletedSchema.updateOne(&lt;condição&gt;, &lt;consulta&gt;).lean()</code></pre><p>Assim, teríamos apenas uma chamada ao banco de dados.</p><h3 id="a-opera-o-delete"><strong>A operação <em>Delete</em></strong></h3><p><em>Delete</em> também é direto com relação ao Mongoose. Vejamos como podemos excluir um único documento:</p><pre><code class="language-js">const res = await CompletedSchema.deleteOne(&lt;condição&gt;)</code></pre><p>Assim como <code>updateOne</code>, <code>deleteOne</code> também aceita o primeiro argumento como condição de correspondência para o documento.</p><p>Há também outro método chamado <code>deleteMany</code>, que deve ser usado apenas quando você sabe que deseja excluir vários documentos.</p><p>Em qualquer outro caso, use sempre <code>deleteOne</code> para evitar várias exclusões acidentais, especialmente quando você estiver tentando executar <em>queries</em> por conta própria.</p><h2 id="conclus-o"><strong>Conclusão</strong></h2><p>Este artigo foi uma introdução simples ao mundo do Mongoose e do MongoDB para desenvolvedores do Node.js.</p><p>Se gostou dele, você pode tentar aprimorar ainda mais suas habilidades como desenvolvedor seguindo o <a href="https://codedamn.com/learning-paths/backend">caminho de aprendizagem de <em>back-end</em> da codedamn</a> (em inglês). Fique à vontade para entrar em contato com o autor pelo <a href="https://twitter.com/mehulmpt">Twitter</a> para fornecer seu <em>feedback</em>!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como programar seu próprio emissor de eventos em Node.js: um guia passo a passo ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Rajesh Pillai Entenda o funcionamento do Node programando pequenos pacotes/módulos Se você é novo no Node.js, há muitos tutoriais aqui no freeCodeCamp e em outros lugares. Você pode conferir meu artigo All about Core Node.JS [https://codeburst.io/all-about-core-nodejs-part-1-b9f4b0a83278] (em inglês), por exemplo. Sem mais delongas, vamos ao assunto em discussão: ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-programar-seu-proprio-emissor-de-eventos-no-node-js-um-guia-passo-a-passo/</link>
                <guid isPermaLink="false">643c4d1b84d2fb0595fd64a0</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Renato Almeida ]]>
                </dc:creator>
                <pubDate>Tue, 20 Jun 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/0_R0F_SNqsLvxWG99J.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-code-your-own-event-emitter-in-node-js-a-step-by-step-guide-e13b7e7908e1/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to code your own event emitter in Node.js: a step-by-step guide</a>
      </p><p>Escrito por: Rajesh Pillai</p><h3 id="entenda-o-funcionamento-do-node-programando-pequenos-pacotes-m-dulos">Entenda o funcionamento do Node programando pequenos pacotes/módulos</h3><p>Se você é novo no Node.js, há muitos tutoriais aqui no freeCodeCamp e em outros lugares. Você pode conferir meu artigo <a href="https://codeburst.io/all-about-core-nodejs-part-1-b9f4b0a83278">All about Core Node.JS</a> (em inglês), por exemplo.</p><p>Sem mais delongas, vamos ao assunto em discussão: "Emissores de Eventos". Os emissores de eventos desempenham um papel muito importante no ecossistema do Node.js.</p><p>O EventEmitter (Emissor de Eventos) é um módulo que facilita a comunicação/interação entre objetos no Node. O EventEmitter está no centro da arquitetura orientada a eventos assíncrona do Node. Muitos dos módulos internos do Node são herdados do EventEmitter, incluindo <em>frameworks</em> proeminentes, como o Express.js.</p><p>O conceito é bastante simples: objetos emissores emitem eventos nomeados, que fazem com que ouvintes (em inglês, <em>listeners</em>) previamente registrados sejam chamados. Assim, um objeto emissor possui basicamente duas funcionalidades principais:</p><ul><li>Emitir eventos nomeados.</li><li>Registrar e cancelar o registro de funções do ouvinte.</li></ul><p>É meio como um padrão de desenho pub/sub ou observador (embora não exatamente).</p><h3 id="o-que-criaremos-neste-tutorial">O que criaremos neste tutorial</h3><ul><li>classe EventEmitter</li><li>método on/addEventListener</li><li>método off/removeEventListener</li><li>método once</li><li>método emit</li><li>método rawListeners</li><li>método listenerCount</li></ul><p>Os recursos básicos acima são suficientes para implementar um sistema completo usando o modelo de eventos.</p><p>Antes de entrarmos na programação, vamos dar uma olhada em como usaremos a classe EventEmitter. Observe que nosso código imitará a API exata do módulo "events" do Node.js.</p><p>Na verdade, se você substituir nosso EventEmitter pelo módulo "events" integrado do Node.js, você obterá o mesmo resultado.</p><h3 id="exemplo-1-crie-uma-inst-ncia-de-emissor-de-evento-e-registre-algumas-fun-es-de-retorno">Exemplo 1 - Crie uma instância de emissor de evento e registre algumas funções de retorno</h3><pre><code>const myEmitter = new EventEmitter();

function c1() {
   console.log('Ocorreu um evento!');
}

function c2() {
   console.log('E mais outro!');
}

myEmitter.on('eventOne', c1); // Registro para eventOne
myEmitter.on('eventOne', c2); // Registro para eventOne</code></pre><p>Quando o evento "eventOne" é emitido, ambas as funções de retorno acima devem ser invocadas.</p><pre><code>myEmitter.emit('eventOne');</code></pre><p>A saída no console será a seguinte:</p><pre><code>Ocorreu um evento!
E mais outro!</code></pre><h3 id="exemplo-2-registrando-para-o-evento-ser-disparado-apenas-uma-vez-usando-once">Exemplo 2 - Registrando para o evento ser disparado apenas uma vez usando "once"</h3><pre><code>myEmitter.once('eventOnce', () =&gt; console.log('eventOnce disparado apenas uma vez')); </code></pre><p>Emitindo o evento "eventOnce":</p><pre><code>myEmitter.emit('eventOne');</code></pre><p>A seguinte saída deve aparecer no console:</p><pre><code>eventOnce disparado apenas uma vez</code></pre><p>Emitir eventos registrados com "once" novamente não terá impacto.</p><pre><code>myEmitter.emit('eventOne');</code></pre><p>Uma vez que o evento foi emitido apenas uma vez, a instrução acima não terá impacto.</p><h3 id="exemplo-3-registrando-se-para-o-evento-com-par-metros-de-fun-o-de-retorno">Exemplo 3 - Registrando-se para o evento com parâmetros de função de retorno</h3><pre><code>myEmitter.on('status', (code, msg)=&gt; console.log(`Obtive ${code} e ${msg}`));</code></pre><p>Emitindo o evento com parâmetros:</p><pre><code>myEmitter.emit('status', 200, 'ok');</code></pre><p>A saída no console será a seguinte:</p><pre><code>Obtive 200 e ok</code></pre><p>OBSERVAÇÃO: Você pode emitir eventos várias vezes (exceto os registrados com o método "once").</p><h3 id="exemplo-4-cancelando-o-registro-de-eventos">Exemplo 4 - Cancelando o registro de eventos</h3><pre><code>myEmitter.off('eventOne', c1);</code></pre><p>Agora, se você emitir o evento da seguinte forma, nada acontecerá e será um "noop":</p><pre><code>myEmitter.emit('eventOne');  // noop</code></pre><h3 id="exemplo-5-obtendo-contagem-de-ouvintes">Exemplo 5 - Obtendo contagem de ouvintes</h3><pre><code>console.log(myEmitter.listenerCount('eventOne'));</code></pre><p>OBSERVAÇÃO: Se o registro do evento foi cancelado usando o método "off" ou "removeListener", a contagem será 0.</p><h3 id="exemplo-6-obtendo-ouvintes-brutos">Exemplo 6 - Obtendo ouvintes brutos</h3><pre><code>console.log(myEmitter.rawListeners('eventOne'));</code></pre><h3 id="exemplo-7-exemplo-de-demonstra-o-ass-ncrona">Exemplo 7 - Exemplo de demonstração assíncrona</h3><pre><code>// Exemplo 2-&gt;Adaptado de um texto de Sameer Buna. Grato!
class WithTime extends EventEmitter {
  execute(asyncFunc, ...args) {
    this.emit('begin');
    console.time('execute');
    this.on('data', (data)=&gt; console.log('got data ', data));
    asyncFunc(...args, (err, data) =&gt; {
      if (err) {
        return this.emit('error', err);
      }
      this.emit('data', data);
      console.timeEnd('execute');
      this.emit('end');
    });
  }
}</code></pre><p>Usando o emissor de evento "withTime":</p><pre><code>const withTime = new WithTime();

withTime.on('begin', () =&gt; console.log('Prestes a executar'));
withTime.on('end', () =&gt; console.log('Execução encerrada'));

const readFile = (url, cb) =&gt; {
  fetch(url)
    .then((resp) =&gt; resp.json()) // Transformar os dados em json
    .then(function(data) {
      cb(null, data);
    });
}

withTime.execute(readFile, 'https://jsonplaceholder.typicode.com/posts/1');</code></pre><p>Verifique a saída no console. A lista de postagens será exibida junto com outros logs.</p><h3 id="o-padr-o-observador-para-nosso-emissor-de-evento">O padrão Observador para nosso emissor de evento</h3><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/image-2.png" class="kg-image" alt="image-2" width="532" height="649" loading="lazy"></figure><h3 id="diagrama-visual-1-m-todos-em-nosso-eventemitter-">Diagrama visual 1 (métodos em nosso EventEmitter)</h3><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/image-4.png" class="kg-image" alt="image-4" width="484" height="494" loading="lazy"></figure><p>Como agora entendemos a utilização da API, vamos programar o módulo.</p><h3 id="o-c-digo-de-exemplo-completo-para-a-classe-eventemitter">O código de exemplo completo para a classe EventEmitter</h3><p>Estaremos preenchendo os detalhes de modo incremental nas próximas seções.</p><pre><code>class EventEmitter {
  listeners = {};  // par chave-valor
  
  addListener(eventName, fn) {}
  on(eventName, fn) {}
  
  removeListener(eventName, fn) {}
  off(eventName, fn) {}
  
  once(eventName, fn) {}
  
  emit(eventName, ...args) { }
  
  listenerCount(eventName) {}
  
  rawListeners(eventName) {}
}</code></pre><p>Começamos criando o modelo para a classe EventEmitter junto com um objeto para armazenar os ouvintes. Os ouvintes serão armazenados como um par chave-valor. O valor pode ser uma lista (já que para o mesmo evento permitimos que vários ouvintes sejam cadastrados).</p><h3 id="1-o-m-todo-addlistener-">1. O método addListener()</h3><p>Vamos agora implementar o método addListener. Ele recebe um nome de evento e uma função de retorno para ser executada.</p><pre><code>addListener(event, fn) {
    this.listeners[event] = this.listeners[event] || [];
    this.listeners[event].push(fn);
    return this;
  }</code></pre><h3 id="uma-pequena-explica-o-">Uma pequena explicação:</h3><p>O evento addListener verifica se o evento já está registrado. Se estiver, retorna o array. Caso contrário, o array estará vazio.</p><pre><code>this.listeners[event] // retornará o array de eventos ou undefined (registro inicial)</code></pre><p>Por exemplo…</p><p>Vamos entender isso com um exemplo de uso. Vamos criar um eventEmitter e registrar um "test-event". Esta é a primeira vez que o "test-event" está sendo registrado.</p><pre><code>const eventEmitter = new EventEmitter();
eventEmitter.addListener('test-event', 
 ()=&gt; { console.log ("test one") } 
);</code></pre><p>Dentro do método addListener():</p><pre><code>this.listeners[event] =&gt;  this.listeners['test-event'] 
                  =&gt; undefined || []
                  =&gt; []</code></pre><p>O resultado será:</p><pre><code>this.listeners['test-event'] = [];  // empty array</code></pre><p>Espero que isso torne o método "addListener" muito claro para decifrar e entender.</p><p><strong>Uma observação: várias funções de retornos podem ser registradas para o mesmo evento.</strong></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/image-5.png" class="kg-image" alt="image-5" width="579" height="755" loading="lazy"></figure><h3 id="2-o-m-todo-on-">2. O método on()</h3><p>Este é apenas um apelido para o método "addListener". Usaremos o método "on" mais do que o método "addListener" por uma questão de conveniência.</p><pre><code>on(event, fn) {
  return this.addListener(event, fn);
}</code></pre><h3 id="3-o-m-todo-removelistener-event-fn-">3. O método <strong>removeListener(event, fn)</strong></h3><p>O método "removeListener" recebe um nome de evento e a função de retorno como parâmetros. Ele remove o ouvinte mencionado do array de eventos.</p><p>OBSERVAÇÃO: Se o evento tiver vários ouvintes, os outros ouvintes não serão afetados.</p><p>Primeiro, vamos dar uma olhada no código completo para "removeListener".</p><pre><code>removeListener (event, fn) {
    let lis = this.listeners[event];
    if (!lis) return this;
    for(let i = lis.length; i &gt; 0; i--) {
      if (lis[i] === fn) {
        lis.splice(i,1);
        break;
      }
    }
    return this;
}</code></pre><p>Aqui está o método "removeListener" explicado passo a passo:</p><ul><li>Obtém o array de ouvintes por evento.</li><li>Se nenhum for encontrado, retornar "this" para encadeamento.</li><li>Se encontrado, percorre todos os ouvintes. Se o ouvinte atual corresponde ao parâmetro "fn", usa o método "splice" do array para removê-lo. Depois, sai do laço.</li><li>Retorna "this" para continuar encadeando.</li></ul><h3 id="4-o-m-todo-off-event-fn-">4. O método off(event, fn)</h3><p>Este é apenas um apelido para o método "removeListener". Estaremos usando o método "off" mais do que o método "removeListener" por uma questão de conveniência.</p><pre><code>off(event, fn) {
    return this.removeListener(event, fn);
  }</code></pre><h3 id="5-o-m-todo-once-eventname-fn-">5. O método once(eventName, fn)</h3><p>Adiciona uma função de ouvinte única para o evento chamado "eventName". Na próxima vez que o nome do evento for acionado, esse ouvinte será removido e, em seguida, invocado.</p><p>Use para eventos do tipo configuração/inicialização.</p><p>Vamos dar uma olhada no código.</p><pre><code>once(eventName, fn) {
    this.listeners[event] = this.listeners[eventName] || [];
    const onceWrapper = () =&gt; {
      fn();
      this.off(eventName, onceWrapper);
    }
    this.listeners[eventName].push(onceWrapper);
    return this;
}</code></pre><p>Aqui está o método "once" explicado passo a passo:</p><ul><li>Obtém o objeto de array de eventos. Se for a primeira vez, o array estará vazio.</li><li>Cria uma função de invólucro chamada "onceWrapper", que invocará a função "fn" quando o evento for emitido e também removerá o ouvinte.</li><li>Adiciona a função de invólucro ao array.</li><li>Retorna "this" para encadeamento.</li></ul><h3 id="6-o-m-todo-emit-eventname-args-">6. O método emit(eventName, ..args)</h3><p>Chama de modo síncrono cada um dos ouvintes registrados para o evento com o nome "eventName", na ordem em que foram registrados, passando os argumentos fornecidos para cada um.</p><p>Retorna verdadeiro (true) se o evento tiver ouvintes ou falso (false), do contrário.</p><pre><code>emit(eventName, ...args) {
    let fns = this.listeners[eventName];
    if (!fns) return false;
    fns.forEach((f) =&gt; {
      f(...args);
    });
    return true;
}</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/05/image-1-1.png" class="kg-image" alt="image-1-1" width="553" height="761" loading="lazy"></figure><p>Aqui está o método "emit" explicado passo a passo:</p><ul><li>Obtém as funções registradas para o parâmetro nome do evento.</li><li>Se não houver ouvintes, retorna <code>false</code>.</li><li>Para todos os ouvintes de função, invoca a função com os argumentos fornecidos.</li><li>Retorna <code>true</code> quando termina.</li></ul><h3 id="7-o-m-todo-listenercount-eventname-">7. O método listenerCount(eventName)</h3><p>Retorna o número de ouvintes escutando o evento com o nome "eventName".</p><p>Aqui está o código-fonte:</p><pre><code>listenerCount(eventName) {
    let fns = this.listeners[eventName] || [];
    return fns.length;
}</code></pre><p>Aqui está o método "listenerCount" explicado passo a passo:</p><ol><li>Obtém as funções/ouvintes consideradas ou um array vazio se não houver nenhum.</li><li>Retorna o comprimento (desse array).</li></ol><h3 id="8-o-m-todo-rawlisteners-eventname-">8. O método rawListeners(eventName)</h3><p>Retorna uma cópia do array de ouvintes para o evento com o nome "eventName", incluindo quaisquer invólucros (como os criados por .once()). Os invólucros de .once() nesta implementação não estarão disponíveis se o evento tiver sido emitido uma vez.</p><pre><code>rawListeners(event) {
    return this.listeners[event];
}</code></pre><p>O código-fonte completo, para referência:</p><pre><code>class EventEmitter {
  listeners = {}
  
  addListener(eventName, fn) {
    this.listeners[eventName] = this.listeners[eventName] || [];
    this.listeners[eventName].push(fn);
    return this;
  }

  on(eventName, fn) {
    return this.addListener(eventName, fn);
  }

  once(eventName, fn) {
    this.listeners[eventName] = this.listeners[eventName] || [];
    const onceWrapper = () =&gt; {
      fn();
      this.off(eventName, onceWrapper);
    }
    this.listeners[eventName].push(onceWrapper);
    return this;
  }

  off(eventName, fn) {
    return this.removeListener(eventName, fn);
  }

  removeListener (eventName, fn) {
    let lis = this.listeners[eventName];
    if (!lis) return this;
    for(let i = lis.length; i &gt; 0; i--) {
      if (lis[i] === fn) {
        lis.splice(i,1);
        break;
      }
    }
    return this;
  }

  emit(eventName, ...args) {
    let fns = this.listeners[eventName];
    if (!fns) return false;
    fns.forEach((f) =&gt; {
      f(...args);
    });
    return true;
  }

  listenerCount(eventName) {
    let fns = this.listeners[eventName] || [];
    return fns.length;
  }

  rawListeners(eventName) {
    return this.listeners[eventName];
  }
}</code></pre><p>O código completo está disponível <a href="https://jsbin.com/gibofab/edit?js,console,output">aqui</a>.</p><p>Como exercício, sinta-se à vontade para implementar outras APIs de eventos da <a href="https://nodejs.org/api/events.html">documentação</a> (em inglês).</p><p>Se você gostou deste artigo e deseja ver mais artigos semelhantes, sinta-se à vontade para compartilhá-lo. :)</p><p>OBSERVAÇÃO: O código foi otimizado para legibilidade e não para desempenho. Talvez, como exercício, você possa otimizar o código e compartilhá-lo. Não testei completamente para casos extremos e algumas validações podem estar imprecisas, pois foi um rascunho rápido.</p><p>Este artigo faz parte de um curso em vídeo que criariei, chamado "Node.JS Master Class — Build Your Own ExpressJS-Like MVC Framework from scratch".</p><p>O título do curso, porém, ainda não é definitivo.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Você nunca deveria executar o Node.js diretamente em produção... será? ]]>
                </title>
                <description>
                    <![CDATA[ Às vezes, fico me perguntando se eu sei muito sobre poucas coisas.  Há algumas semanas, eu conversava com um amigo que mencionou despretensiosamente que "você nunca deveria rodar uma aplicação do Node diretamente em produção". Eu balancei minha cabeça vigorosamente em sinal de afirmação para demonstrar que eu também ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/voce-nunca-deveria-executar-o-node-js-diretamente-em-producao-sera/</link>
                <guid isPermaLink="false">63c6991291baea05fef70b0f</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Gustavo Goulart Baptista ]]>
                </dc:creator>
                <pubDate>Thu, 04 May 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_Lh8JaRfiqPj9bTrd8a3xgQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/you-should-never-ever-run-directly-against-node-js-in-production-maybe-7fdfaed51ec6/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">You should never ever run directly against Node.js in production. Maybe.</a>
      </p><p>Às vezes, fico me perguntando se eu sei muito sobre poucas coisas. </p><p>Há algumas semanas, eu conversava com um amigo que mencionou despretensiosamente que "você nunca deveria rodar uma aplicação do Node diretamente em produção".</p><p>Eu balancei minha cabeça vigorosamente em sinal de afirmação para demonstrar que eu <em>também </em>nunca rodaria Node em produção porque... hahaha... todo mundo sabe disso. Só que eu não sabia disso! &nbsp;Eu deveria saber disso? EU AINDA TENHO PERMISSÃO PARA PROGRAMAR?</p><p>Se eu fosse desenhar um Diagrama de Venn do que eu sei <em>em comparação </em>com o que eu acho que os outros sabem, seria algo assim...</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_ThJbM2JMjrnTuHczo0tLqw.png" class="kg-image" alt="1_ThJbM2JMjrnTuHczo0tLqw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/1_ThJbM2JMjrnTuHczo0tLqw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_ThJbM2JMjrnTuHczo0tLqw.png 800w" sizes="(min-width: 720px) 720px" width="800" height="801" loading="lazy"><figcaption>O que eu sei x o que eu acho que os outros sabem</figcaption></figure><p>A propósito, aquele pontinho bem pequeno ali fica cada vez menor conforme eu fico velho.</p><p>Existe um diagrama melhor criado por <a href="https://medium.com/counter-intuition/overcoming-impostor-syndrome-bdae04e46ec5" rel="noopener">Alicia Liu</a> que, de certo modo, mudou minha vida. Ela diz que, na verdade, seria mais parecido com isso...</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_N7vv39ri9yC0l6krsSFlQA.png" class="kg-image" alt="1_N7vv39ri9yC0l6krsSFlQA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/1_N7vv39ri9yC0l6krsSFlQA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_N7vv39ri9yC0l6krsSFlQA.png 800w" sizes="(min-width: 720px) 720px" width="800" height="300" loading="lazy"></figure><p>Eu amo esse diagrama porque eu quero muito que ele seja verdade. Eu não quero passar o resto da minha vida como um pontinho azul pequeno – e cada vez menor – e insignificante.</p><p>MUITO DRAMÁTICO. Ao menos, não estamos partindo da <a href="https://open.spotify.com/playlist/1aab5jZgKu90bQIpzbWYKv?si=13121037c7ee46bd">estakazero</a>. Eu não estou controlando qual a próxima música que vai tocar enquanto estou escrevendo, mas escrever artigos com <a href="https://open.spotify.com/track/3XA3NYOoFxiLQe0OLtQlNw?si=593f031b37204d1e">confidências</a> é viciante como uma droga</p><p>Bem, assumindo que o diagrama de Alicia seja verdade, eu gostaria de compartilhar com você o que eu sei <em>agora </em>sobre rodar aplicações do Node em produção. Talvez nossos Diagramas de Venn relativos não se sobreponham nesse tema.</p><p>Primeiro, vamos analisar a declaração "nunca rodar aplicações do Node diretamente em produção".</p><h4 id="nunca-rodar-o-node-diretamente-em-produ-o"><strong>Nunca rodar o Node diretamente em produção</strong></h4><p>Talvez, sim; talvez, não. Vamos falar sobre o raciocínio por trás dessa declaração. Primeiro, vamos dar uma olhada nos motivos contra fazermos isso.</p><p>Suponha que temos um simples servidor do Express. O servidor do Express mais simples que eu posso pensar...</p><pre><code class="language-js">const express = require("express");
const app = express();
const port = process.env.PORT || 3000;

// Visível em http://localhost:3000
app.get("/", function(req, res) {
  res.send("Again I Go Unnoticed"); //"De novo, ninguém me nota", em português 
});

app.listen(port, () =&gt; console.log(`Example app listening on port ${port}!`)); //"App de exemplo escutando na porta... ", em português </code></pre><p>Rodaríamos isso usando o script <code>start</code> no arquivo <code>package.json</code>.</p><pre><code>"scripts": {
  "dev": "npx supervisor index.js",
  "start": "node index.js"
}</code></pre><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_VceC98Qk5zKqzBmiu1szDQ.png" class="kg-image" alt="1_VceC98Qk5zKqzBmiu1szDQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/1_VceC98Qk5zKqzBmiu1szDQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_VceC98Qk5zKqzBmiu1szDQ.png 800w" sizes="(min-width: 720px) 720px" width="800" height="478" loading="lazy"></figure><p>Existem dois problemas aqui. O primeiro é um problema de desenvolvimento. O segundo é um problema de produção.</p><p>O problema de desenvolvimento: ao mudarmos o código, teremos que parar e começar a aplicação para termos nossas mudanças captadas.</p><p>Para solucionar isso, normalmente usamos algo como um gerenciador de processos do Node, como o <code>supervisor</code> ou o <code>nodemon</code>. Esses pacotes observarão nosso projeto e reiniciarão nosso servidor sempre que fizermos mudanças. Eu normalmente faço algo assim:</p><pre><code>"scripts": {  "dev": "npx supervisor index.js",  "start": "node index.js"}</code></pre><p>Então, eu rodo <code>npm run dev</code>. Note que eu estou rodando <code>npx supervisor</code> aqui, o que me permite usar o pacote <code>supervisor</code> sem ter de instalá-lo. Eu amo a modernidade (na maior parte do tempo).</p><p>Nosso outro problema é que ainda estamos rodando diretamente o Node e já dissemos que era algo ruim. Agora, estamos prestes a descobrir o porquê.</p><p>Adiciono outro roteador aqui, que tenta ler um arquivo do disco que não existe. Esse é um erro que poderia facilmente aparecer em qualquer aplicação do mundo real. </p><pre><code class="language-js">const express = require("express");
const app = express();
const fs = require("fs");
const port = process.env.PORT || 3000;

// viewed at http://localhost:3000
app.get("/", function(req, res) {
  res.send("Again I Go Unnoticed");
});

app.get("/read", function(req, res) {
  // Isso aqui não existe 
  fs.createReadStream("minha-autoestima.txt");
});

app.listen(port, () =&gt; console.log(`Example app listening on port ${port}!`));</code></pre><p>Se rodarmos diretamente o Node com o <code>npm start</code> e navegarmos até o <em>endpoint</em> <code>read</code>, vamos obter um erro, pois o arquivo não existe.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_pAUoJV-LRJwxs7MRegnuoA.png" class="kg-image" alt="1_pAUoJV-LRJwxs7MRegnuoA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/1_pAUoJV-LRJwxs7MRegnuoA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_pAUoJV-LRJwxs7MRegnuoA.png 800w" sizes="(min-width: 720px) 720px" width="800" height="478" loading="lazy"></figure><p>Não é um grande problema, certo? É um erro. Acontece.</p><p>É um grande problema, sim. Se você voltar ao seu terminal, verá que sua aplicação quebrou completamente.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_69LuEt53W2isIXP34vUlYA.png" class="kg-image" alt="1_69LuEt53W2isIXP34vUlYA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/1_69LuEt53W2isIXP34vUlYA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_69LuEt53W2isIXP34vUlYA.png 800w" sizes="(min-width: 720px) 720px" width="800" height="450" loading="lazy"></figure><p>Isso significa que, se você voltar ao navegador e se tentar acessar o URL raiz do site, terá a mesma mensagem de erro. Um erro em apenas um método quebrou sua aplicação para <strong>todos os usuários</strong>. </p><p>Isso é péssimo – muito ruim, mesmo. Essa é uma das razões principais porque as pessoas dizem <strong>"nunca rode o Node diretamente em produção"</strong>. </p><p>OK. Então, se nós não podemos rodar o Node diretamente em produção, qual seria a maneira certa de fazê-lo?</p><h4 id="op-es-para-o-node-em-produ-o">Opções para o Node em produção</h4><p>Temos algumas opções.</p><p>Uma delas seria simplesmente usar algo como o <code>supervisor</code> ou o <code>nodemon</code> em produção da mesma maneira que o usamos em ambiente de desenvolvimento. Isso poderia funcionar, mas essas ferramentas são muito pouco para um controle adequado. Uma opção melhor é chamada de pm2.</p><h4 id="resolva-com-o-pm2">Resolva com o pm2</h4><p>O pm2 é um gerenciador de processos do Node que tem muitos alertas. Assim como todo o resto em "JavaScript", você o instala (globalmente) através do <code>npm</code> — ou pode simplesmente usar o <code>npx</code> outra vez. Faça como você quiser.</p><p>Existem muitas maneiras de rodar sua aplicação com o pm2. A maneira mais simples possível seria apenas chamar <code>pm2 start</code> no seu ponto de entrada.</p><pre><code>"scripts": {
  "start": "pm2 start index.js",
  "dev": "npx supervisor index.js"
},</code></pre><p>Você verá algo mais ou menos assim no seu terminal…,</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_uvsnmQahRBHtnh0X7tt_xA.png" class="kg-image" alt="1_uvsnmQahRBHtnh0X7tt_xA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/1_uvsnmQahRBHtnh0X7tt_xA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_uvsnmQahRBHtnh0X7tt_xA.png 800w" sizes="(min-width: 720px) 720px" width="800" height="450" loading="lazy"></figure><p>Esse é o nosso processo rodando, monitorado pelo pm2 em segundo plano. Se você visitar o endpoint <code>read</code> e se a aplicação quebrar, o pm2 vai reinicializá-la automaticamente. Você não verá nada disso no terminal, pois está rodando em segundo plano. Se você quiser observar o pm2 fazendo o trabalho, precisará rodar <code>pm2 log 0</code>, sendo <code>0</code> o id do processo cujos relatórios desejamos ver.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_AbR1eyySpr2IllYtA4wE-Q.png" class="kg-image" alt="1_AbR1eyySpr2IllYtA4wE-Q" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/1_AbR1eyySpr2IllYtA4wE-Q.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_AbR1eyySpr2IllYtA4wE-Q.png 800w" sizes="(min-width: 720px) 720px" width="800" height="450" loading="lazy"></figure><p>Pronto, tudo certo! Você pode ver a reinicialização da aplicação quando ela cair devido ao nosso erro não tratado. </p><p>Podemos também colocar nosso comando <code>dev</code> e fazer com que o pm2 observe os arquivos para nós e os reinicialize em quaisquer mudanças.</p><pre><code>"scripts": {
  "start": "pm2 start index.js --watch",
  "dev": "npx supervisor index.js"
},</code></pre><p>Note que, em função de o pm2 rodar tudo em segundo plano, você não pode simplesmente apertar <code>ctrl+c</code> para terminar o processo do pm2. Você tem que pará-lo usando o ID ou o nome.</p><p><code>pm2 stop 0</code></p><p><code>pm2 stop index</code></p><p>Observe, também, que o pm2 retém uma referência para o processo para que você possa recomeçá-lo. </p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_Z4yLru6TmwUVQv84DkZDAQ.png" class="kg-image" alt="1_Z4yLru6TmwUVQv84DkZDAQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/1_Z4yLru6TmwUVQv84DkZDAQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_Z4yLru6TmwUVQv84DkZDAQ.png 800w" sizes="(min-width: 720px) 720px" width="800" height="450" loading="lazy"></figure><p>Se você quiser excluir a referência do processo, precisa executar <code>pm2 delete</code>. Você pode parar e excluir um processo em um comando com <code>delete</code>.</p><p><code>pm2 delete index</code></p><p>Também podemos usar o pm2 para rodar múltiplos processos da nossa aplicação. O pm2 automaticamente balanceará o carregamento através dessas instâncias.</p><h4 id="m-ltiplos-processos-com-pm2-no-modo-fork"><strong><strong>M</strong>ú<strong>ltipl</strong>os<strong> process</strong>o<strong>s</strong> com <strong>pm2 </strong>no modo <strong>fork</strong></strong></h4><p>O pm2 tem diversas opções de configuração e elas estão contidas em um arquivo de "ecossistema". Para criar um, execute <code>pm2 init</code>. Você vai obter um resultado parecido com esse...</p><pre><code class="language-js">module.exports = {
  apps: [
    {
      name: "Express App",
      script: "index.js",
      instances: 4,
      autorestart: true,
      watch: true,
      max_memory_restart: "1G",
      env: {
        NODE_ENV: "development"
      },
      env_production: {
        NODE_ENV: "production"
      }
    }
  ]
};</code></pre><p>Eu vou ignorar a seção "deploy" nesse artigo, pois não tenho a menor ideia do que ela faz. </p><p>A seção "apps" é onde você define as aplicações que você deseja que o pm2 rode e monitore. Você pode rodar mais de uma. Muitas dessas configurações do arquivo são, provavelmente, autoexplicativas. Eu quero me concentrar naquela configuração chamada <em>instances</em> (em português, <strong>instâncias</strong>).</p><p>O pm2 pode rodar múltiplas instâncias da sua aplicação. Você pode informar um número de <em>instances</em> que você deseja rodar e o pm2 fará o trabalho. Então, se queremos rodar 4 <em>instances</em>, podemos rodar o seguinte arquivo de configuração: </p><pre><code class="language-js">module.exports = {
  apps: [
    {
      name: "Express App",
      script: "index.js",
      instances: 4,
      autorestart: true,
      watch: true,
      max_memory_restart: "1G",
      env: {
        NODE_ENV: "development"
      },
      env_production: {
        NODE_ENV: "production"
      }
    }
  ]
};</code></pre><p>Então, tudo que precisamos é digitar <code>pm2 start</code>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1__rYp7NMQTCMmOfBV0w0RTw.png" class="kg-image" alt="1__rYp7NMQTCMmOfBV0w0RTw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/1__rYp7NMQTCMmOfBV0w0RTw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1__rYp7NMQTCMmOfBV0w0RTw.png 800w" sizes="(min-width: 720px) 720px" width="800" height="450" loading="lazy"></figure><p>O pm2 está agora rodando em um modo <em>cluster</em> (em português, "agrupamento"). Cada um desses processos está rodando em uma CPU diferente na minha máquina, dependendo de quantos núcleos de processamento (em inglês, <em>cores</em>)<em> </em>eu tiver. Se rodarmos um processo para cada <em>core, </em>sem saber quantos <em>cores</em> temos, precisamos apenas passar o parâmetro <code>max</code> para o valor <code>instances</code>.</p><pre><code>{
   ...
   instances: "max",
   ...
}</code></pre><p>Vamos descobrir quantos <em>cores </em>eu tenho nessa máquina.</p><figure class="kg-card kg-image-card"><img src="https://cdn-media-1.freecodecamp.org/images/1*nhjuG0xFsMgkYB382_xfyw.png" class="kg-image" alt="1*nhjuG0xFsMgkYB382_xfyw" width="800" height="450" loading="lazy"></figure><p>8 CORES! Nossa!!! Eu vou instalar <em>Subnautica</em> na minha máquina da Microsoft. Não diga a eles que eu disse isso.</p><p>A parte coisa sobre rodar processos em CPUs separadas é que, se você tiver um processo que perca o controle e tome 100% da CPU, os outros ainda funcionarão. Se você passar mais instâncias do que <em>cores</em>, o pm2 dobrará o número de processos em uma CPUs conforme for necessário.</p><p>Você pode fazer MUITO mais com o pm2, incluindo monitoramento e o tratamento daquelas <a href="https://medium.freecodecamp.org/">variáveis de ambiente</a> irritantes.</p><p>Um outro item a se observar: se, por alguma razão, você quiser executar seu script <code>npm start</code>, você pode fazer isso através do npm como processo e passar a bandeira <code>-- start</code>. O espaço antes de <em>start</em> (em português, "início") é super importante aqui.</p><pre><code>pm2 start npm -- start</code></pre><p>No <a href="https://docs.microsoft.com/en-us/azure/app-service/?WT.mc_id=medium-blog-buhollan" rel="noopener">Azure AppService</a>, incluímos o pm2 por padrão em segundo plano. Se você quiser usar o pm2 no Azure, não precisa incluí-lo em seu arquivo <code>package.json</code>. Você somente precisa adicionar um arquivo de ecossistema e está pronto para continuar.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_TYOm2q57lXad3te35tGwqg.png" class="kg-image" alt="1_TYOm2q57lXad3te35tGwqg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/1_TYOm2q57lXad3te35tGwqg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_TYOm2q57lXad3te35tGwqg.png 800w" sizes="(min-width: 720px) 720px" width="800" height="495" loading="lazy"></figure><p>Certo! Agora que aprendemos tudo sobre o pm2, vamos falar um pouco mais sobre o porquê você pode querer não usá-lo. Também veremos que pode, de fato, não haver problema em rodar o Node diretamente. </p><h4 id="rodando-o-node-diretamente-em-produ-o"><strong>Rodando o Node diretamente em produção</strong></h4><p>Eu tinha algumas dúvidas sobre isso. Então, falei com <a href="https://twitter.com/bitandbang" rel="noopener">Tierney Cyren</a>, que é uma parte enorme do círculo laranja de conhecimento, especialmente quando o assunto é o Node.</p><p>Tierney me apontou algumas desvantagens de se usar o Node baseado em gerenciadores de processos, como o pm2.</p><p>A principal delas é que você não deveria usar Node para monitorar a si mesmo. Você não quer usar a coisa que você está monitorando para monitorar a si mesma. Seria como pedir ao meu filho adolescente para tomar conta de si mesmo em uma sexta-feira à noite: isso acabaria mal? Pode ser que sim, pode ser que não, mas você não quer descobrir da pior maneira.</p><p>Tierney recomenda que você não tenha um gerenciador de processos do Node rodando em sua aplicação nunca. Ao invés disso, tenha algo em um nível mais alto que observe em conjunto as instâncias separadas de sua aplicação. Por exemplo, uma configuração ideal seria se você tivesse um agrupamento de Kubernetes com sua aplicação rodando em contêineres separados. O Kubernetes podem, então, monitorar aqueles contêineres e, se algum deles cair, pode trazê-lo de volta e registrar sua condição de integridade. </p><p>Nesse caso, você <strong>pode </strong>rodar o Node diretamente porque você o está monitorando um nível acima.</p><p>Acontece que o Azure já está fazendo isso. Se não subirmos um arquivo de ecossistema do pm2 para o Azure, a aplicação iniciará com nosso script <code>start</code> do nosso arquivo <code>package.json</code> e podemos, então, rodar diretamente o Node. </p><pre><code>"scripts": {
  "start": "node index.js"
}</code></pre><p>Nesse caso, estamos rodando diretamente o Node e não há problema. Se a aplicação quebrar, você notará que ela reinicializará. Isso acontece porque, no Azure, sua aplicação roda em um contêiner. O Azure está orquestrando o contêiner que sua aplicação está rodando e saberá quando ela tiver problemas.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_YSvtZOR4DIt1McSdDChVew.png" class="kg-image" alt="1_YSvtZOR4DIt1McSdDChVew" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/1_YSvtZOR4DIt1McSdDChVew.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/1_YSvtZOR4DIt1McSdDChVew.png 800w" sizes="(min-width: 720px) 720px" width="800" height="495" loading="lazy"></figure><p>Porém, você ainda tem apenas uma instância aqui. É necessário, ao contêiner, algum tempo para voltar a ficar on-line depois de quebrar, o que significa que, nesse tempo, sua aplicação estaria fora do ar para seus usuários.</p><p>Idealmente, você vai querer ter mais de um contêiner rodando. A solução para isso seria subir múltiplas <em>instances </em>de sua aplicação para múltiplos sites do <em>Azure AppService</em> e, então, usar o <em>Azure Front Door</em> para balancear a carga das aplicações por detrás de um único endereço de IP. O <em>Front Door</em> saberá quando um contêiner cair e roteará o tráfego para outras instâncias funcionais de sua aplicação.</p><p><strong>Saiba mais sobre o serviço Azure Front Door <a href="https://azure.microsoft.com/pt-br/products/frontdoor/?WT.mc_id=medium-blog-buhollan">aqui</a>.</strong></p><h4 id="systemd"><strong><strong>systemd</strong></strong></h4><p>Outra sugestão que o Tierney nos dá é rodar o Node com <code>systemd</code>. Eu não entendo muito (na verdade, não entendo nada) sobre <code>systemd</code> e já estraguei tudo parafraseando ele uma vez. Então, vamos deixar Tierney isso dizer com suas próprias palavras…</p><blockquote>Essa opção só é possível se você tiver acesso ao Linux na sua implementação (em inglês, <strong>deployment</strong>), e se você controlar o modo como o Node é inicializado em nível de serviço. Se você estiver rodando seu processo do Node.js em uma máquina virtual (em inglês, <strong>VM</strong>), Linux de longa duração, como as VMs do Azure, poderá rodar o Node.js com systemd sem problemas. Se você só estiver fazendo o deploy de seus arquivos para um serviço como o Azure AppService ou o Heroku ou rodando o Node dentro de um ambiente conteinerizado, como o Azure Container Instances, você provavelmente deverá evitar essa opção.</blockquote><p><strong><a href="https://nodesource.com/blog/running-your-node-js-app-with-systemd-part-1/"><strong>R</strong>odando seu App<strong> Node.js </strong>com<strong> Systemd - Part</strong>e<strong> 1</strong></a></strong> (texto em inglês sobre o assunto)</p><h4 id="worker-threads-do-node-js"><strong><strong>Worker Threads</strong> do <strong>Node.js</strong></strong></h4><p>Tierney também gostaria de informar que as Worker Threads estão chegando ao Node. Isso permitirá a você começar sua aplicação em múltiplos "trabalhadores" (em inglês, <em>workers</em>), evitando, desse modo, a necessidade de algo como o pm2. Talvez. Eu não sei. De fato, não li esse artigo. </p><p><strong><a href="https://nodejs.org/api/worker_threads.html#worker-threads">Documentação d0 <strong>Node.js </strong>sobre Worker Threads</a></strong></p><h4 id="seja-um-adulto">Seja um adulto</h4><p>A última sugestão de Tierney era apenas para lidar com o erro e escrever alguns testes (como um adulto faria), mas quem tem tempo para isso, não é mesmo?</p><h4 id="o-pequeno-c-rculo-permanece">O pequeno círculo permanece</h4><p>Agora você sabe a maior parte do que está no pequeno círculo azul. O restante tem a ver apenas com fatos inúteis sobre bandas e cerveja.</p><p>Para mais informações sobre o pm2, Node e Azure, confira os recursos a seguir:</p><ul><li><a href="https://nodejs.org/api/worker_threads.html#worker-threads"></a><a href="https://pm2.keymetrics.io/">Site do PM2</a></li><li><a href="https://code.visualstudio.com/docs/nodejs/nodejs-deployment">Implantação do Node.js com o VS Code</a></li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como fazer o deploy de uma aplicação em Node.js – do servidor à produção ]]>
                </title>
                <description>
                    <![CDATA[ Neste tutorial, vamos aprender tudo que é preciso para fazer o deploy de uma aplicação em Node para um servidor de produção. Para começar, vamos alugar um servidor na Digital Ocean. Depois disso, vamos configurar o servidor, fazer a conexão, instalar o Nginx e configurá-lo, extrair ou criar nossa aplicação ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-fazer-o-deploy-de-uma-aplicacao-em-node-js-do-servidor-a-producao/</link>
                <guid isPermaLink="false">640466277d24e505217385a2</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Renan Botasse ]]>
                </dc:creator>
                <pubDate>Mon, 24 Apr 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/603a54d9a675540a22924662.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/deploy-nodejs-app-server-to-production/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Deploy a Node.js App – From Server Setup to Production</a>
      </p><p>Neste tutorial, vamos aprender tudo que é preciso para fazer o deploy de uma aplicação em Node para um servidor de produção.</p><p>Para começar, vamos alugar um servidor na Digital Ocean. Depois disso, vamos configurar o servidor, fazer a conexão, instalar o Nginx e configurá-lo, extrair ou criar nossa aplicação do Node.js e executá-la como um processo.</p><p>Como você pode ver, há muito para ser feito e teremos várias opções. Então, vamos começar.</p><p>Você deve ter algum conhecimento básico de como o Terminal funciona e já ter trabalhado com Vi/Vim antes de iniciar o tutorial. Se você não estiver familiarizado com os comandos básicos, eu recomendo ler sobre eles. </p><p>Eu vou executar os comandos em um MacOS. Se você quiser seguir esse tutorial em um Windows, &nbsp;pode usar o Powershell ou algum tipo de emulador para Unix.</p><p>Embora eu esteja usando o Node.js como uma plataforma para o nosso exemplo de aplicação, muitas etapas são iguais para qualquer tipo de aplicação para a web.</p><h2 id="por-que-a-digital-ocean"><strong>Por que a Digital Ocean?</strong></h2><p>Eu escolhi a Digital Ocean pois é barata e a interface é muito fácil de usar, comparada a outras, como a da AWS. Além disso, junto com o pacote para estudantes do GitHub, você recebe US$ 100 de crédito. Desse modo, você não terá que pagar por nada durante alguns meses. É o ideal para um projeto ou um curso.</p><p>Ela posssui um conceito chamado <em>Droplets</em>, que é basicamente a sua parte do servidor. Você pode pensar no servidor como um apartamento em que você pode alugar um quarto. </p><p><em>Droplets</em> funcionam com a ajuda de máquinas virtuais que rodam dentro do servidor. Portanto um Droplet é a sua máquina virtual dentro do servidor dividido. Por ser uma máquina virtual, sua CPU e memória são compartilhados e podem ser facilmente aumentados. Isso pode ser feito através de um investimento em dinheiro junto ao provedor.</p><h2 id="como-criar-um-projeto-na-digital-ocean"><strong>Como criar um projeto na Digital Ocean</strong></h2><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-3.png" class="kg-image" alt="image-3" width="203" height="178" loading="lazy"></figure><p>Assumindo que você já se inscreveu e está logado na Digital Ocean, o primeiro passo é criar o projeto que conterá nosso <em>Droplets</em>. &nbsp;Clique no botão "New Project" no menu do lado esquerdo. Ele vai pedir que você dê um nome para o seu projeto.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/Screen-Shot-2021-02-22-at-13.35.06.png" class="kg-image" alt="Screen-Shot-2021-02-22-at-13.35.06" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/Screen-Shot-2021-02-22-at-13.35.06.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/Screen-Shot-2021-02-22-at-13.35.06.png 995w" width="995" height="785" loading="lazy"></figure><p>Coloque o nome que você quiser. Ele também vai perguntar se você quer mover algum recurso, mas por enquanto apenas clique em Skip (Ignorar). Mais tarde, nós vamos criar o <em>droplet</em>.</p><h2 id="como-criar-um-droplet-no-digital-ocean"><strong>Como criar um <em>droplet </em>no Digital Ocean</strong></h2><p>Vamos criar nosso <em>droplet </em>clicando no botão "Get Started" (Iniciar).</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-4-1024x593.png" class="kg-image" alt="image-4-1024x593" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/image-4-1024x593.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/04/image-4-1024x593.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-4-1024x593.png 1024w" width="1024" height="593" loading="lazy"></figure><p>Após clicar no botão, ele vai pedir para escolhermos uma imagem para a máquina virtual.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/Screen-Shot-2021-02-22-at-13.12.43-1024x567.png" class="kg-image" alt="Screen-Shot-2021-02-22-at-13.12.43-1024x567" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/Screen-Shot-2021-02-22-at-13.12.43-1024x567.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/04/Screen-Shot-2021-02-22-at-13.12.43-1024x567.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/Screen-Shot-2021-02-22-at-13.12.43-1024x567.png 1024w" width="1024" height="567" loading="lazy"><figcaption>Como selecionar uma imagem</figcaption></figure><p>Nesta parte, eu selecionei Ubuntu 20.04 pois é a versão mais atual e "LTS" no momento em que estava escrevendo. LTS significa "Long Term Support" (suporte de longo prazo), sendo a versão segura mais atual. É melhor usar a versão LTS para os projetos, porque isso garante que o provedor dará suporte e poderá ser mantida por muito tempo. Assim, você não terá problemas a longo prazo.</p><p>Eu escolhi o Ubuntu e recomendo a sua utilização, já que é o sistema Linux mais comum. Isso significa que também é o mais fácil para encontrar soluções para suas perguntas no futuro. </p><p>Você pode optar por ter uma CPU dedicada, se precisar. Se estiver criando uma startup ou qualquer tipo de negócio, eu recomento da leitura deste <a href="https://www.digitalocean.com/docs/droplets/resources/choose-plan/">artigo</a> (texto em inglês), que contém detalhes sobre como escolher a melhor opção para você.</p><p>Nesse caso, eu selecionei a opção mais barata.</p><p>Em seguida, você deve selecionar a região do <em>datacenter</em>. Você deve escolher a mais perto de você para diminuir o <em>delay</em> da rede.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-2-1024x519.png" class="kg-image" alt="image-2-1024x519" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/image-2-1024x519.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/04/image-2-1024x519.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-2-1024x519.png 1024w" width="1024" height="519" loading="lazy"><figcaption>Como selecionar um <em>datacenter</em></figcaption></figure><p>Em seguida, selecione "SSH Keys" como forma de autenticação, pois é a opção mais segura.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-5-1024x459.png" class="kg-image" alt="image-5-1024x459" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/image-5-1024x459.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/04/image-5-1024x459.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-5-1024x459.png 1024w" width="1024" height="459" loading="lazy"><figcaption>Método de autenticação</figcaption></figure><p>Para se conectar ao servidor, será preciso gerar uma nova chave SSH no seu próprio dispositivo e adicioná-la a Digital Ocean.</p><h2 id="como-gerar-uma-chave-ssh"><strong>Como gerar uma chave SSH</strong></h2><p>Eu vou gerar a chave através do meu macOS. Se você estiver usando o Windows, você pode verificar <a href="https://phoenixnap.com/kb/generate-ssh-key-windows-10">este artigo</a> (texto em inglês). Abra o terminal e crie uma pasta SSH:</p><pre><code>cd ~/.ssh</code></pre><p>Para criar sua chave SSH:</p><pre><code>ssh-keygen</code></pre><p>Se o seu computador disser que não reconhece esse comando, você deve instalá-lo através do brew.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-7-1024x140.png" class="kg-image" alt="image-7-1024x140" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/image-7-1024x140.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/04/image-7-1024x140.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-7-1024x140.png 1024w" width="1024" height="140" loading="lazy"></figure><p>Ele vai pedir que você nomeie o arquivo e acrescente uma senha. Não digite o seu nome. Apenas aperter Enter e continue com as definições padrão. Os arquivos devem ser gerados. Eu nomeei o meu como digital-ocean-ssh. Não se confunda com isso.</p><pre><code>❯ lsid_dsa      id_rsa      known_hosts</code></pre><p>Nossa chave pública é <code>id_dsa</code> e <code>id_rsa</code> é a nossa chave privada. Se você esquecer qual é a privada, você sempre pode fazer um print delas.</p><h2 id="como-adicionar-sua-chave-ssh-na-digital-ocean"><strong>Como adicionar sua chave SSH na Digital Ocean</strong></h2><p>Agora, vamos copiar nossa chave pública e fazer o upload dela na Digital Ocean. Assim, eles saberão qual é a chave usada para nossa autenticação.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-9-1024x149.png" class="kg-image" alt="image-9-1024x149" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/image-9-1024x149.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/04/image-9-1024x149.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-9-1024x149.png 1024w" width="1024" height="149" loading="lazy"></figure><p>Copie toda a chave, incluindo a parte ssh-rsa.</p><p>Clique em "New SSH Key":</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-10.png" class="kg-image" alt="image-10" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/image-10.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-10.png 645w" width="645" height="330" loading="lazy"></figure><p>Cole a chave na caixa de texto que aparece depois que você clica no botão. Desse modo, você verá sua chave SSH.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-11.png" class="kg-image" alt="image-11" width="455" height="231" loading="lazy"></figure><h2 id="como-conectar-ao-servidor"><strong>Como conectar ao servidor</strong></h2><p>Vamos usar o terminal para conectar ao nosso servidor através do SSH. Você também pode dar uma olhada no <em>Termius</em> para uma interface mais agradável, se você quiser.</p><p>Execute este comando no seu terminal após substituir IP_ADDRESS pelo IP do seu servidor (você pode procurar no painel da Digital Ocean).</p><pre><code>ssh root@IP_ADDRESS</code></pre><p>Se tudo der certo, agora, você deve estar no terminal do servidor. Estamos conectados ao servidor. Se você tiver qualquer tipo de erro, pode fazer o debug executando o comando com "-v" ou "-vv".</p><h2 id="como-configurar-o-seu-servidor"><strong>Como configurar o seu servidor</strong></h2><p>Precisamos fazer uma configuração inicial do servidor antes de fazer o <em>deploy </em>da aplicação no Node.</p><h3 id="atualize-o-software"><strong>Atualize o software</strong></h3><p>Precisamos fazer a atualização do software do servidor para ter certeza de que está com a versão mais recente.</p><p>Muitos servidores são vulneráveis a ataques, pois estão usando versões antigas do software, com vulnerabilidades já conhecidas. Os invasores buscam por vulnerabilidades no software e tentam explorar isso para ter acesso ao seu servidor.</p><p>Você pode atualizar o seu Ubuntu usando o comando <strong><strong>"apt update"</strong>.</strong></p><pre><code>apt updateHit:1 https://repos.insights.digitalocean.com/apt/do-agent main InReleaseGet:2 http://mirrors.digitalocean.com/ubuntu focal InRelease [265 kB]      Hit:3 http://mirrors.digitalocean.com/ubuntu focal-updates InRelease                Get:4 http://security.ubuntu.com/ubuntu focal-security InRelease [109 kB]Hit:5 http://mirrors.digitalocean.com/ubuntu focal-backports InReleaseFetched 374 kB in 1s (662 kB/s)                          Reading package lists... DoneBuilding dependency tree       Reading state information... Done96 packages can be upgraded. Run 'apt list --upgradable' to see them.</code></pre><p>Se a mensagem estiver dizendo "96 packages can be upgraded", significa que ainda não houve a instalação dos pacotes, apesar de eles terem sido encontrados para atualizar.</p><p>Para efetivar a atualização com a instalação dos pacotes encontrados, execute o comando:</p><pre><code>apt upgrade</code></pre><p>Digite "y" quando solicitado e isso fará a atualização do software.</p><h3 id="criando-um-usu-rio"><strong>Criando um usuário</strong></h3><p>Estamos conectados ao servidor como um usuário <em>root</em> (usuário com mais privilégios). Ser o usuário <em>root </em>pode ser perigoso e pode nos expor a mais vulnerabilidades.</p><p>Portanto, devemos criar um usuário para não executar os comandos como <em>root</em>. Substitua <code>$username</code> abaixo com o nome de usuário da sua preferência.</p><pre><code>whoamiroot</code></pre><pre><code>adduser $username</code></pre><p>Você vai criar uma senha para o usuário. Depois disso, ele fará várias perguntas. Para pular isso, digite "y" até que ele termine.</p><p>O novo usuário foi criado, mas ainda precisamos adicionar o novo usuário ao grupo "sudo" para que ele possa executar qualquer tipo de ação necessária.</p><pre><code>usermod -aG sudo $USERNAME</code></pre><p>Adicionamos o usuário ao grupo com o comando <code>-aG</code> (grupo a ser adicionado). Também devemos adicioná-lo ao grupo <code>sudo</code>.</p><p>Ainda estamos no usuário <em>root</em>. Então, vamos mudar para nosso novo usuário. Para isso, podemos usar o comando <code>su</code> (usuário a ser usado).</p><pre><code>su $USERNAME</code></pre><p>Após, se você executar o comando <code><strong><strong>whoami</strong></strong></code>, você deve ver o seu nome de usuário. Você pode verificar a existência do grupo <code>sudo</code>, através do seguinte comando:</p><pre><code>sudo cat /var/log/auth.log</code></pre><p>Apenas superusuários podem ver esse arquivo. A máquina pedirá a sua senha após executar o comando.</p><h3 id="copie-a-chave-ssh"><strong>Copie a chave SSH</strong></h3><p>Após criar o usuário, ainda devemos habilitar seu login através do SSH.</p><p>Portanto, devemos copiar a chave pública (criada anteriomente) e colá-la na pasta SSH desse usuário para que o SSH possa saber qual chave ele deve aceitar para autenticar esse usuário.</p><pre><code>mkdir -p ~/.ssh</code></pre><p>O comando <code>-p</code> cria um diretório, caso ele não exista.</p><pre><code>vi ~/.ssh/authorized_keys</code></pre><p>Temos que usar o vi ou vim para criar o arquivo chamado <strong><strong><code>authorized_keys</code></strong></strong>.</p><p>Copie a chave pública (arquivo <code>id_dsa</code>) e pressione "i" para ir para o modo de edição. Cole a chave no arquivo com CMD + V.</p><p>Pressione Esc para sair do modo de edição, digite <strong><strong>:wq</strong></strong> para salvar e sair.</p><p>Se tiver algum problema usando Vim/Vi, &nbsp;você pode dar uma olhada em algum dos<a href="https://www.freecodecamp.org/news/how-not-to-be-afraid-of-vim-anymore-ec0b7264b0ae/"> vários tutoriais</a> (texto em inglês) que explicam como eles funcionam.</p><h3 id="conecte-ao-servidor-com-o-novo-usu-rio"><strong>Conecte ao servidor com o novo usuário</strong></h3><p>Agora, devemos ser capazes de conectar ao servidor sem nenhum problema. Você pode usar o seguinte comando para conectar (mas lembre-se de alterar o <code>IP_ADDRESS</code> para o seu nome de usuário).</p><pre><code>ssh $USERNAME@IP_ADDRESS</code></pre><p>Se você tiver algum problema, pode excluir o <em>droplet </em>e iniciar novamente. Isso não deve tomar muito tempo, já que fazer o <em>debug</em> do servidor pode ser muito difícil.</p><h3 id="como-desabilitar-o-login-do-root"><strong>Como desabilitar o login do <em>root</em></strong></h3><p>Uma boa prática de segurança é desabilitar o login através do usuário root.</p><p>Para não termos problemas de permissão no futuro, é indicado alterar a permissão do arquivo.</p><pre><code>chmod 644 ~/.ssh/authorized_keys</code></pre><p>Agora abra o arquivo <code>sshd_config</code>:</p><pre><code>sudo vi /etc/ssh/sshd_config</code></pre><p>Encontre a linha abaixo e modifique <code>no</code> para <code>yes</code>. Isso deve ser feito através do Vim/Vi.</p><pre><code>PermitRootLogin no</code></pre><p>Salve e saia do Vim/Vi.</p><h2 id="como-instalar-o-node-js-e-o-git"><strong>Como instalar o Node.js e o Git</strong></h2><p>Agora, podemos seguir com a instalação do Node.js e do Git:</p><pre><code>sudo apt install nodejs npm</code></pre><pre><code>sudo apt install git</code></pre><p>Estamos prontos para criar nossa aplicação em Node e executá-la. Você pode extrair o seu projeto do Node do GitHub ou criar um projeto em Node aqui apenas para testar se funciona.</p><p>Vá para o diretório de sua escolha e crie o arquivo <strong><strong>"app.js"</strong></strong>:</p><pre><code>sudo vi app.js</code></pre><p>Você pode colar o seguinte texto em seu arquivo <strong><strong>app.js</strong></strong>:</p><pre><code>const express = require('express');const app = express();const port = 3000;app.get('/', (req, res) =&gt; {        res.send('Hello World');});app.listen(port, () =&gt; console.log(`Example app listening on port ${port}!`));</code></pre><p>Agora, execute isso com o comando:</p><pre><code>node app.js</code></pre><p>Você deve ser a seguinte mensagem no seu terminal: "Example app listening on port 3000!"</p><p>Podemos confirmar se está funcionando através de uma requisição:</p><pre><code>GET http://IP_ADDRESS:3000/</code></pre><p>Envie essa requisição de um client HTTP com o Postman ou de seu navegador. Você deve receber a seguinte mensagem: "Hello World".</p><p>Neste ponto, você deve ter percebido que alguma coisa está errada. Usuários comuns não sabem enviar uma requisição através da porta 3000.</p><p>Devemos redirecionar as requisições enviadas pelo nosso IP que chegam ao servidor para a Porta 3000. Podemos fazer isso com a ajuda do Nginx.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-16.png" class="kg-image" alt="image-16" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/image-16.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-16.png 762w" width="762" height="212" loading="lazy"></figure><h2 id="como-instalar-e-configurar-o-nginx"><strong>Como instalar e configurar o Nginx</strong></h2><p>Vamos usar o Nginx para fazer um proxy reverso para redirecionar as requisições para a nossa aplicação do Node.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-14-1024x531.png" class="kg-image" alt="image-14-1024x531" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/image-14-1024x531.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/04/image-14-1024x531.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-14-1024x531.png 1024w" width="1024" height="531" loading="lazy"><figcaption>Nginx como proxy reverso</figcaption></figure><p>Vamos instalar o Nginx:</p><pre><code>sudo apt install nginx</code></pre><p>Iniciando o serviço Nginx:</p><pre><code>sudo service nginx start</code></pre><p>Podemos testar enviando uma requisição ao nosso servidor através do navegador. Digite o endereço de IP do servidor em seu navegador e você deverá receber a seguinte mensagem:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-15-1024x231.png" class="kg-image" alt="image-15-1024x231" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/image-15-1024x231.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/04/image-15-1024x231.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-15-1024x231.png 1024w" width="1024" height="231" loading="lazy"></figure><p>É importante saber que o servidor do Nginx é executado do endereço <strong><strong>"/var/www/html"</strong></strong> por padrão e que você pode encontrar esse arquivo HTML nesse diretório.</p><p>Eu também aconselho a você criar uma pasta dentro de "/var/www", chamar a aplicação e mover a sua aplicação em Node para essa pasta, facilitando sua localização.</p><h3 id="como-configurar-o-proxy-reverso-do-nginx"><strong>Como configurar o proxy reverso do Nginx</strong></h3><p>Vamos editar a configuração do arquivo Nginx para configurar o proxy reverso:</p><pre><code>sudo vi /etc/nginx/sites-available/default</code></pre><p>Nesse arquivo, você deve encontrar o local/bloco e editá-lo da seguinte maneira:</p><pre><code>location / {                # First attempt to serve request as file, then                # as directory, then fall back to displaying a 404.                proxy_pass http://127.0.0.1:3000/;        }</code></pre><p>O <code>proxy_pass</code> faz o proxy da solicitação para uma porta específica. Vamos dar à porta o endereço em que nossa aplicação de Node está executando.</p><p>Agora, vamos reiniciar o Nginx para que as alterações tenham efeito:</p><pre><code>sudo service nginx reload</code></pre><p>Após essa etapa, devemos ser capazes de ver a mensagem quando enviamos a requisição ao servidor. </p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/Screen-Shot-2021-02-24-at-01.10.33-1024x67.png" class="kg-image" alt="Screen-Shot-2021-02-24-at-01.10.33-1024x67" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/Screen-Shot-2021-02-24-at-01.10.33-1024x67.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/04/Screen-Shot-2021-02-24-at-01.10.33-1024x67.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/Screen-Shot-2021-02-24-at-01.10.33-1024x67.png 1024w" width="1024" height="67" loading="lazy"></figure><p>Parabéns, nós completamos o mínimo de passos para fazer o <em>deploy </em>de uma aplicação em Node. Eu aconselho, no entanto, a concluir a parte de bônus, pois acredito que seja muito importante. Se você não conseguir ver a mensagem <code>Hello World!</code>, pode verificar se a sua aplicação e se o Nginx estão sendo executados e reiniciá-los.</p><h2 id="como-executar-sua-aplica-o-como-um-processo"><strong>Como executar sua aplicação como um processo</strong></h2><p>Não queremos ter que iniciar nossa aplicação manualmente todas as vezes que algo der errado e ele travar. Nós queremos que ela reinicie sozinha. Além disso, sempre que o servidor iniciar, a aplicação também deve iniciar.</p><p>Para fazer isso, podemos usar o PM2. Vamos instalá-lo e configurá-lo.</p><pre><code>sudo npm i -g pm2</code></pre><p>Estamos instalando o pm2 de modo global, usando a opção "-g". Isso faz com que ele seja acessível a todas as pastas.</p><pre><code>pm2 start app.js</code></pre><p>Isso garante que a aplicação será reiniciada se ocorrer algum erro.</p><p>Salve a lista de processos.</p><pre><code>pm2 save</code></pre><p>Também precisamos convertê-lo em um <em>daemon </em>que execute sempre que o sistemar iniciar:</p><pre><code>pm2 startup systemd</code></pre><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-17.png" class="kg-image" alt="image-17" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/04/image-17.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/04/image-17.png 834w" width="834" height="291" loading="lazy"></figure><p>Para lembrar, neste tutorial, estou usando os comandos para Ubuntu. Se você estiver usando outra distribuição do Linux, você deve substituir o comando <code>systemd</code>.</p><p>Podemos confirmar que está reiniciando o servidor corretamente enviando uma solicitação sem executar <code>app.js</code> manualmente:</p><pre><code>sudo reboot</code></pre><p>Depois de enviar a requisição, como fizemos anteriormente, você deve ver a mensagem <code>"Hello World!"</code>.</p><h2 id="conclus-o"><strong>Conclusão</strong></h2><p>Neste tutorial, começamos do zero, alugamos um servidor, conectamos a ele e o configuramos para a nossa aplicação do Node.js na porta 80.</p><p>Se você acompanhou e conseguiu concluir todas as etapas, parabéns! Você pode se orgulhar, pois não foi um tutorial fácil. Espero que você tenha aprendido muito. Agradeço pelo seu tempo.</p><p>Estou planejando explorar mais este tópico conectando o servidor ao domínio e, em seguida, conectando-o ao CircleCI para integração contínua. Também vou mostrar quais são as etapas necessárias para preparar sua aplicação em Node.js/React para produção. Este artigo já ficou longo. Então, esses tópicos estão reservados para outro artigo. 🙂</p><p>Se você gostou da leitura e quer se manter informado sobre futuros artigos do autor, pode se inscrever no <a href="https://erinc.io/">blog pessoal dele</a>. Se estiver interessado, lá você verá as publicações mais antigas do autor, que costuma escrever sobre desenvolvimento para a web.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Exportação de módulos do Node explicada – com exemplos de exportação de funções do JavaScript ]]>
                </title>
                <description>
                    <![CDATA[ Uma das coisas mais poderosas a respeito do desenvolvimento de software é a capacidade de reutilizar e criar com base naquilo que outras pessoas deixaram. È esse compartilhamento de código que acabou permitindo que o software avançasse imensamente. Um mecanismo tão fantástico é fundamental em um nível mais profundo em ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/exportacao-de-modulos-do-node-explicada-com-exemplos-de-exportacao-de-funcoes-do-javascript/</link>
                <guid isPermaLink="false">64258b5f86dbbe0599dba2fa</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Thu, 30 Mar 2023 23:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/cover-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/node-module-exports-explained-with-javascript-export-function-examples/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Node Module Exports Explained – With JavaScript Export Function Examples</a>
      </p><p>Uma das coisas mais poderosas a respeito do desenvolvimento de software é a capacidade de reutilizar e criar com base naquilo que outras pessoas deixaram. È esse compartilhamento de código que acabou permitindo que o software avançasse imensamente.</p><p>Um mecanismo tão fantástico é fundamental em um nível mais profundo em termos de projetos individuais e de equipes.</p><p>Para o Node.js, esse processo de compartilhamento de código – tanto em projetos individuais quanto em dependências externas do npm – é facilitado pelo uso de <code>module.exports</code> ou <code>exports</code>.</p><h1 id="como-funcionam-os-m-dulos-do-node"><strong>Como funcionam os módulos do Node</strong></h1><p>Como usamos as exportações de módulos para adicionar um módulo externo ou dividir nosso projeto de modo razoável em diversos arquivos (módulos)?</p><p>O sistema de módulos do Node.js foi criado porque os criadores não queriam passar pelo mesmo problema do escopo global quebrado, como ocorria com o equivalente no navegador. Eles implementaram <a href="https://en.wikipedia.org/wiki/CommonJS">a especificação do CommonJS</a> para conseguir isso.</p><p>As duas partes importantes do quebra-cabeças são o <code>module.exports</code> e a função <code>require</code>.</p><h2 id="como-o-module-exports-funciona"><strong>Como o module.exports funciona</strong></h2><p><code>module.exports</code> é, de fato, uma propriedade do objeto <code>module</code>. É esta a aparência do objeto <code>module</code> quando usamos <code>console.log(module)</code>:</p><pre><code class="language-bash">Module {
  id: '.',
  path: '/Users/stanleynguyen/Documents/Projects/blog.stanleynguyen.me',
  exports: {},
  parent: null,
  filename: '/Users/stanleynguyen/Documents/Projects/blog.stanleynguyen.me/index.js',
  loaded: false,
  children: [],
  paths: [
    '/Users/stanleynguyen/Documents/Projects/blog.stanleynguyen.me/node_modules',
    '/Users/stanleynguyen/Documents/Projects/node_modules',
    '/Users/stanleynguyen/Documents/node_modules',
    '/Users/stanleynguyen/node_modules',
    '/Users/node_modules',
    '/node_modules'
  ]
}
</code></pre><p>O objeto acima, basicamente, descreve um módulo encapsulado de um arquivo do JS, com <code>module.exports</code> sendo o componente exportado de todos os tipos – objeto, função, string e outros. A exportação padrão em um módulo do Node.js é simples assim:</p><pre><code class="language-js">module.exports = function umaFuncaoExportada() {
  return "Sim, é simples desse jeito.";
};
</code></pre><p>Existe uma outra forma de exportar a partir de um módulo do Node.js chamada "exportação nomeada". Em vez de atribuir todo o <code>module.exports</code> a um valor, atribuímos propriedades individuais do objeto <code>module.exports</code> padrão a valores. Algo assim:</p><pre><code class="language-js">module.exports.anExportedFunc = () =&gt; {};
module.exports.anExportedString = "Esta string é exportada.";

// ou empacotada juntamente em um objeto
module.exports = {
  anExportedFunc,
  anExportedString,
};
</code></pre><p>A exportação nomeada também pode ser feita de modo mais conciso com a variável predefinida <code>exports</code> de escopo dos módulos, assim:</p><pre><code class="language-js">exports.anExportedFunc = () =&gt; {};
exports.anExportedString = "Esta string é exportada.";
</code></pre><p>Porém, atribuir toda a variável <code>exports</code> a um novo valor não funcionará (discutiremos o motivo para isso na próxima seção), o que geralmente confunde os desenvolvedores do Node.js.</p><pre><code class="language-js">// Isto não funcionará como poderíamos esperar
exports = {
  anExportedFunc,
  anExportedString,
};
</code></pre><p>Imagine que as exportações dos módulos do Node.js estão enviando contêineres, com <code>module.exports</code> e <code>exports</code> agindo como a equipe no porto para quem diríamos qual "envio" (ou seja, quais valores) queremos enviar para um "porto estrangeiro" (outro módulo do projeto).</p><p>Bem, "a exportação padrão" diria a <code>module.exports</code> qual "envio" deveria ser enviado por navio, enquanto a "exportação nomeada" carregaria contêineres diferentes no navio que <code>module.exports</code> enviará para outro porto.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/ship-analogy.png" class="kg-image" alt="ship-analogy" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/ship-analogy.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/03/ship-analogy.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/ship-analogy.png 1600w" sizes="(min-width: 1200px) 1200px" width="1600" height="880" loading="lazy"><figcaption>Minha analogia de barcos para a função do module.exports do Node.js</figcaption></figure><p>Agora que enviamos o navio, como esses "portos estrangeiros" receberão os navios?</p><h2 id="como-funciona-a-palavra-chave-require-no-node-js"><strong>Como funciona a palavra-chave require no Node.js</strong></h2><p>No lado do receptor, os módulos do Node.js podem importar usando o valor exportado de <code>require</code>.</p><p>Imagine que escrevemos isto em <code>ship.js</code>:</p><pre><code class="language-js">...
module.exports = {
  containerA,
  containerB,
};
</code></pre><p>Podemos importar esse "envio" em nosso <code>receiving-port.js</code>:</p><pre><code class="language-js">// importando o ship.js inteiro como uma única variável
const ship = require("./ship.js");
console.log(ship.containerA);
console.log(ship.containerB);
// ou importando diretamente os contêineres por meio da desestruturação de objetos
const { containerA, containerB } = require("./ship.js");
console.log(containerA);
console.log(containerB);
</code></pre><p>Um ponto importante a ser observado sobre esse operador do porto estrangeiro – o <code>require</code> – é que a pessoa não muda de ideia quanto a receber envios <strong>que foram feitos pelo<strong> <code>module.exports</code> </strong>de outro porto qualquer</strong>. Isso nos leva à próxima seção, onde trataremos de um ponto que normalmente causa confusão.</p><h2 id="module-exports-x-exports-qual-a-diferen-a-e-por-que-usar-um-ou-outro"><strong><code>module.exports</code> x <code>exports</code> – Qual a diferença e por que usar um ou outro?</strong></h2><p>Agora que vimos o básico sobre exportação e requisição de módulos, é hora de tratar uma das fontes mais comuns de confusão nos módulos do Node.js.</p><p>Este é um erro de exportação de módulos que os iniciantes em Node.js geralmente cometem. Eles atribuem <code>exports</code> a um novo valor, achando que é a mesma coisa que a "exportação padrão" usando <code>module.exports</code>.</p><p>Isso, no entanto, não funciona porque:</p><ul><li><code>require</code> somente usará o valor de <code>module.exports</code></li><li><code>exports</code> é uma variável com escopo de módulo que faz referência inicialmente a <code>module.exports</code></li></ul><p>Assim, ao atribuir <code>exports</code> a um novo valor, estamos efetivamente apontando o valor de <code>exports</code> para outra referência que não é &nbsp;inicial do mesmo objeto <code>module.exports</code>.</p><p>Se quiser saber mais a respeito dessa explicação técnica, <a href="https://nodejs.org/api/modules.html#modules_exports_shortcut">a documentação oficial do Node.js</a> é um bom ponto de partida.</p><p>Voltando à analogia que fizemos anteriormente usando navios e operadores: exports são outra equipe portuária que poderíamos informar sobre o navio que está partindo. No início, tanto <code>module.exports</code>, quanto <code>exports</code> têm a mesma informação sobre o "navio" de partida.</p><p>Se dissermos, no entanto, às exportações que o navio de saída será diferente (isto é, se atribuíssemos <code>exports</code> a um valor completamente novo), o que quer que digamos depois (como atribuir propriedades de <code>exports</code> a valores) não estará no navio que <code>module.exports</code> está realmente preparando para ser recebido por require.</p><p>Por outro lado, se apenas disséssemos às exportações para "carregar alguns contêineres no navio de saída" (atribuindo propriedades de <code>exports</code> ao valor), na verdade, acabaríamos carregando "contêineres" (isto é, valores de propriedade) no navio que está sendo enviado.</p><p>Com base no erro comum explicado acima, poderíamos definitivamente desenvolver algumas boas convenções em torno do uso de módulos CommonJS no Node.js.</p><h2 id="melhores-pr-ticas-de-exporta-o-para-o-node-js-uma-alternativa-sensata"><strong>Melhores práticas de exportação para o Node.JS – uma alternativa sensata</strong></h2><p>Logicamente, a convenção oferecida abaixo é inteiramente baseada em minhas próprias análises e raciocínio. Se tiver uma alternativa para a qual você realmente acha que pode melhorar a situação, não hesite em <a href="https://twitter.com/stanley_ngn">me enviar uma mensagem pelo Twitter</a> a respeito.</p><p>O principal que desejo conseguir com essa convenção é:</p><ul><li>eliminar a confusão entre <code>exports</code> e <code>module.exports</code></li><li>facilitar a leitura e melhorar a observabilidade com relação à exportação de módulos</li></ul><p>Minha proposta é, portanto, consolidar os valores exportados na parte de baixo do arquivo, assim:</p><pre><code class="language-js">// exportação padrão
module.exports = function defaultExportedFunction() {};
// exportação nomeada
module.exports = {
  something,
  anotherThing,
};
</code></pre><p>Ao fazer isso, eliminaríamos as desvantagens em termos de concisão que <code>module.exports</code> têm em comparação com a abreviação <code>exports</code>. Isso removeria todos os incentivos para que usemos os <code>exports</code>, confusos e potencialmente danosos.</p><p>Esta prática ainda facilitaria para que os leitores do código o lessem &nbsp;e aprendessem sobre os valores exportados de um módulo específico.</p><h2 id="indo-al-m-do-commonjs"><strong>Indo além do CommonJS</strong></h2><p>Existe um padrão novo e, obviamente, melhor que foi introduzido há pouco no Node.js, chamamos de <code>módulos do ECMAScript</code>. <a href="https://nodejs.org/api/esm.html">Os módulos do ECMAScript</a> costumavam estar disponíveis apenas em código que precisaria mais tarde de uma transpilação do <a href="https://babeljs.io/">Babel</a>, ou como parte de um recurso experimental do Node.js, versões 12 ou posteriores.</p><p>É uma maneira bastante simples e elegante de lidar com a exportação de módulos. Uma ideia geral a seu respeito pode ser resumida com a exportação padrão (em inglês, <em>default</em>) a seguir:</p><pre><code class="language-js">export default function exportedFunction() {}
</code></pre><p>Já as exportações nomeadas teriam esta aparência:</p><pre><code class="language-js">// Exportações nomeadas em linhas separadas
export const constantString = "CONSTANT_STRING";
export const constantNumber = 5;
// Exportações nomeadas consolidadas
export default {
  constantString,
  constantNumber,
};
</code></pre><p>Esses valores, podem, então, ser facilmente importados pelo receptor, assim:</p><pre><code class="language-js">// valores padrão importados
import exportedFunction from "exporting-module.js";
// importar valores das exportações nomeadas por meio da desestruturação de objetos
import { constantString, constantNumber } from "exporting-module.js";
</code></pre><p>Isso termina com a confusão entre <code>module.exports</code> e <code>exports</code> com uma sintaxe bonita e que qualquer um pode entender!</p><p>Existem, certamente, projetos que ainda serão migrados para a versão 14 &nbsp;ou posterior do Node.js e que ainda não poderão usar essa sintaxe nova.</p><p>Porém, se você tiver a oportunidade de fazer isso (por estar começando um novo projeto ou porque seu projeto foi migrado com sucesso para a versão 14 do Node.js ou posteriores), não há motivo para não mudar para este modo futurista e incrível de se olhar para a questão.</p><h3 id="obrigado-pela-leitura-"><strong>Obrigado pela leitura!</strong></h3><p>Para encerrar, se você gostou do que o autor escreveu, acesse o <a href="https://blog.stanleynguyen.me/">blog</a> do autor para ver comentários semelhantes e <a href="https://twitter.com/stanley_ngn">siga-o no Twitter</a>. 🎉</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ O que é exatamente o Node.js? ]]>
                </title>
                <description>
                    <![CDATA[ O Node.js é um ambiente de tempo de execução do JavaScript. Certo, mas o que isso quer dizer? Como é que ele funciona? O ambiente de tempo de execução chamado Node.js inclui tudo de que você precisa para executar um programa escrito em JavaScript. Se você conhece Java, esta é ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/o-que-e-exatamente-o-node-js/</link>
                <guid isPermaLink="false">641c7b96a2272ae7bb7fbbdf</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Thu, 23 Mar 2023 23:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/5f9cae6a740569d1a4caa649.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/what-exactly-is-node-js-ae36e97449f5/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">What exactly is Node.js?</a>
      </p><p>O Node.js é um ambiente de tempo de execução do JavaScript. Certo, mas o que isso quer dizer? Como é que ele funciona?</p><p>O ambiente de tempo de execução chamado Node.js inclui tudo de que você precisa para executar um programa escrito em JavaScript.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_sYPllpcAZLHmpuQSRPuO0Q.png" class="kg-image" alt="1_sYPllpcAZLHmpuQSRPuO0Q" width="449" height="267" loading="lazy"><figcaption>Se você conhece Java, esta é uma analogia que você pode usar</figcaption></figure><p>O Node.js passou a existir quando os desenvolvedores originais do JavaScript decidiram transformá-lo de algo que somente podia ser executado no navegador em algo que podia ser executado em sua máquina e como uma aplicação autônoma.</p><p>Agora, é possível fazer muito mais com o JavaScript do que tornar sites da web interativos.</p><p>O JavaScript, agora, consegue fazer coisas que outras linguagens de programação como o Python podem fazer.</p><p>Tanto o JavaScript do seu navegador quanto o Node.js são executados na <em>engine </em>de tempo de execução V8 do JavaScript. Essa <em>engine </em>recebe o código em JavaScript e o converte em código de máquina mais rápido. O código de máquina é um código de baixo nível que o computador pode executar sem a necessidade de interpretá-lo primeiramente.</p><h3 id="por-que-usar-o-node-js"><strong>Por que usar o <strong>Node.js?</strong></strong></h3><p>Aqui temos uma definição formal dada no <a href="https://nodejs.org/">site oficial do Node.js</a>:</p><blockquote>O Node.js® é um tempo de execução do JavaScript criado com base na <a href="https://developers.google.com/v8/" rel="noopener">engine de JavaScript V8 do Chrome</a>.<br><br>O Node.js usa um modelo de entrada e saída orientado por eventos e não bloqueador que o torna leve e eficiente.<br><br>O ecossistema de pacotes do Node.js, o <a href="https://www.npmjs.com/" rel="noopener">npm</a>, é o maior ecossistema de bibliotecas de código aberto do mundo.</blockquote><p>Já discutimos a primeira linha dessa definição: "O Node.js® é um tempo de execução do JavaScript criado com base na <em>engine</em> de JavaScript V8 do Chrome." Agora, vamos entender as outras duas linhas para podermos descobrir a razão pela qual o Node.js é tão popular.</p><p>Entrada e saída têm a ver com o que chamamos em inglês de <em>input</em>/<em>output (cuja sigla é I/O)</em>. Pode ser qualquer coisa – de ler ou gravar arquivos localmente a fazer uma solicitação de HTTP para uma API.</p><p>O processo de E/S (entrada e saída) leva tempo e, por isso, bloqueia outras funções.</p><p>Considere um cenário onde solicitamos a um banco de dados do <em>back-end</em> que nos retorne os detalhes sobre o usuário1 e o usuário2 (na imagem abaixo, <em>user1</em> e <em>user2</em>) e que, em seguida, os imprima na tela/console. A resposta para essa solicitação leva tempo, mas as duas solicitações de dados dos usuários podem ser realizadas independentemente e ao mesmo tempo.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_B_UCsFOPfRDKO8ovHpxphg.png" class="kg-image" alt="1_B_UCsFOPfRDKO8ovHpxphg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/1_B_UCsFOPfRDKO8ovHpxphg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_B_UCsFOPfRDKO8ovHpxphg.png 800w" sizes="(min-width: 720px) 720px" width="800" height="236" loading="lazy"><figcaption>E/S com bloqueio (à esquerda) x E/S sem bloqueio (à direita)</figcaption></figure><h3 id="e-s-com-bloqueio"><strong>E/S com bloqueio</strong></h3><p>No método com bloqueio, a solicitação de dados do usuário2 não é iniciada até que os dados do usuário1 sejam impressos na tela.</p><p>Se estamos falando de um servidor da web, teríamos de iniciar uma nova <em>thread</em> (algo como uma "sequência", em português) para cada novo usuário. O JavaScript, porém, usa uma <em>thread</em> única (isso não é bem verdade, mas ele tem um <em>loop </em>de eventos que são de <em>thread </em>única – falaremos sobre isso mais tarde). Assim, isso faria com que o JavaScript não fosse a melhor opção para tarefas que exigem várias <em>threads</em>.</p><p>É aí que entra a parte do "sem bloqueio".</p><h3 id="e-s-sem-bloqueio"><strong>E/S sem bloqueio</strong></h3><p>Por outro lado, usando uma solicitação sem bloqueio, é possível iniciar uma solicitação de dados do usuário2 sem esperar pela resposta dada sobre o usuário1. Você pode iniciar as duas solicitações em paralelo.</p><p>Essa E/S sem bloqueio elimina a necessidade de várias <em>threads</em>, já que o servidor pode lidar com diversas solicitações ao mesmo tempo.</p><h3 id="o-loop-de-eventos-do-javascript"><strong>O <em>loop </em>de eventos do <strong>JavaScript</strong></strong></h3><p>Se você tiver 26 minutos à disposição, assista essa explicação em vídeo excelente sobre o <em>loop </em>de eventos do Node (em inglês):</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.49999999999999%;" class="fluid-width-video-wrapper">
            <iframe width="200" height="113" src="https://www.youtube.com/embed/8aGhZQkoFbQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" title="What the heck is the event loop anyway? | Philip Roberts | JSConf EU" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><p>Caso contrário, aqui, temos uma explicação passo a passo de como funciona o <em>loop </em>de eventos em JavaScript.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_BBlPbUjGVtfSPd7BHa1LHw.png" class="kg-image" alt="1_BBlPbUjGVtfSPd7BHa1LHw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/1_BBlPbUjGVtfSPd7BHa1LHw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_BBlPbUjGVtfSPd7BHa1LHw.png 759w" sizes="(min-width: 720px) 720px" width="759" height="421" loading="lazy"><figcaption>Créditos da imagem: <a href="https://www.udemy.com/the-complete-nodejs-developer-course-2/">curso de Andrew Mead</a> na Udemy sobre o Node</figcaption></figure><ol><li>Colocar <code>main()</code> na <em>stack </em>de chamadas.</li><li>Colocar <code>console.log()</code> na <em>stack</em> de chamadas. Ele é executado imediatamente e retirado da <em>stack</em>.</li><li>Colocar <code>setTimeout(2000)</code> na <em>stack</em>. <code>setTimeout(2000)</code> é uma API do Node. Quando a chamamos, registramos o par evento-função de callback. O evento aguardará 2.000 milissegundos, depois chamará a função de <em>callback</em>.</li><li>Depois de ser registrada nas APIs, <code>setTimeout(2000)</code> é retirada da <em>stack </em>de chamadas.</li><li>O segundo <code>setTimeout(0)</code> é registrado do mesmo modo. Agora, temos duas APIs do Node esperando para serem executadas.</li><li>Após aguardar 0 segundos, <code>setTimeout(0)</code> é movida para a fila de <em>callback</em>. O mesmo ocorre com <code>setTimeout(2000)</code>.</li><li>Na fila de <em>callback</em>, as funções aguardam que a <em>stack</em> de chamadas esteja vazia, pois apenas uma instrução pode ser executada por vez. Quem cuida disso é o <em>loop </em>de eventos.</li><li>O último <code>console.log()</code> é executado e <code>main()</code> é retirado da stack de chamadas.</li><li>O <em>loop </em>de eventos vê que a <em>stack </em>de chamadas está vazia e que a fila de <em>callbacks</em> não está. Ele, então, move as funções de <em>callback</em> (na ordem em que a primeira a entrar é a primeira a sair – FIFO) para a <em>stack</em> de chamadas para execução.</li></ol><h3 id="npm"><strong><strong>npm</strong></strong></h3><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/0_A47ZVKudfCOCBbyx.png" class="kg-image" alt="0_A47ZVKudfCOCBbyx" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/0_A47ZVKudfCOCBbyx.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/0_A47ZVKudfCOCBbyx.png 800w" sizes="(min-width: 720px) 720px" width="800" height="311" loading="lazy"></figure><p>Essas são as bibliotecas criadas pela fantástica comunidade e que resolverão a maior parte dos problemas genéricos. O npm (do inglês, <em>Node package manager</em>) tem pacotes que você pode usar com suas aplicações para tornar o desenvolvimento mais rápido e mais eficiente.</p><h3 id="require"><strong><strong><em>Require</em></strong></strong></h3><p><em>Require</em> faz três coisas:</p><ul><li>Carrega os módulos que vêm com o Node.js, como o sistema de arquivos e o HTTP a partir da <a href="http://nodejs.org/api/" rel="noopener">API do Node.js</a>.</li><li>Carrega as bibliotecas de terceiros, como o Express e o Mongoose, que você instalará a partir do npm.</li><li>Permite que você solicite seus próprios arquivos e modularize seu projeto.</li></ul><p><em>Require </em>é uma função que aceita o parâmetro "path" (caminho) e retorna <code>module.exports</code>.</p><h3 id="m-dulos-do-node"><strong>Módulos do <strong>Node</strong></strong></h3><p>Um módulo do Node é um bloco de código reutilizável cuja existência não afeta outros códigos acidentalmente.</p><p>Você pode escrever seus próprios módulos e usá-los em diversas aplicações. O Node.js tem um conjunto de módulos já incorporados que você pode usar sem precisar instalá-los.</p><h3 id="a-v8-turbina-o-javascript-fazendo-uso-do-c-"><strong>A <strong>V8 </strong>turbina o <strong>JavaScript </strong>fazendo uso do<strong> C++</strong></strong></h3><p>A V8 é uma <em>engine </em>de tempo de execução de código aberto escrita em C++.</p><p>JavaScript -&gt; V8(C++) -&gt; código de máquina</p><p>A V8 implementa uma linguagem de script chamada ECMAScript, conforme especificado na ECMA-262. O ECMAScript foi criado pela Ecma International para padronizar o JavaScript.</p><p>A V8 pode ser executada de modo autônomo ou ser incorporada a qualquer aplicação em C++. Ela tem <em>hooks </em>que permitem que você escreva seu próprio código em C++ e que você pode disponibiizar para o JavaScript.</p><p>Essencialmente, isso permite que você adicione recursos ao JavaScript incorporando a V8 em seu código em C++ para que o código em C++ entenda mais do que aquilo que, de outro modo, é especificado pelo padrão do ECMAScript.</p><p>Comentário: <a href="https://github.com/LetMyPeopleCode">Greg Bulmash</a> chamou minha atenção para o fato de que existem muitas <em>engines </em>de tempo de execução do JavaScript além da V8, usada no Chrome. Também existem a SpiderMonkey, da Mozilla, a Chakra, da Microsoft, entre outras. Detalhes sobre isso podem ser encontrados <a href="https://pt.wikipedia.org/wiki/Interpretador_de_JavaScript">nesta página</a>.</p><h3 id="eventos"><strong><strong>Event</strong>o<strong>s</strong></strong></h3><p>Eventos são situações que ocorrem em nossas aplicações e as quais podemos responder. Existem dois tipos de eventos no Node.</p><ul><li>Eventos de sistema: a base do C++ a partir de uma biblioteca chamada libuv (por exemplo, terminar de ler um arquivo).</li><li>Eventos personalizados: a base do JavaScript.</li></ul><h3 id="como-escrever-o-hello-world-no-node-js"><strong>Como escrever o '<strong>Hello World</strong>'<strong> </strong>no<strong> Node.js</strong></strong></h3><p>Precisamos fazer isso, certo?</p><p>Crie um arquivo <code>app.js</code> e adicione a ele o seguinte:</p><pre><code class="language-javascript">console.log("Hello World!");</code></pre><p>Abra seu terminal do Node, altere o diretório para a pasta onde o arquivo está salvo e execute o comando <code>node app.js</code>.</p><p>Aí está! Você acaba de escrever o 'Hello World' no Node.js.</p><p>Você pode seguir o autor, <a href="https://twitter.com/Priyesh_p18">Priyesh Patel</a>, no Twitter.</p><p>Existem diversos recursos que você pode usar para aprender mais sobre o Node.js, incluindo, é claro, o <a href="https://www.freecodecamp.org/" rel="noopener">freeCodeCamp.org</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como usar o Nodemailer para enviar e-mails do seu servidor do Node.js ]]>
                </title>
                <description>
                    <![CDATA[  O Nodemailer [https://nodemailer.com/about/] é um módulo do Node.js que permite enviar e-mails para o seu servidor com facilidade. Quando você quiser se comunicar com seus usuários ou apenas ser notificado quando algo der errado, uma das opções para fazer isso seria usando o e-mail. Existem muitos artigos explicando como ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-usar-o-nodemailer-para-enviar-emails-do-seu-servidor-do-node-js/</link>
                <guid isPermaLink="false">63d7bda4b42da706e17c2fa9</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Renan Botasse ]]>
                </dc:creator>
                <pubDate>Mon, 20 Mar 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/600efb510a2838549dcb7595.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/use-nodemailer-to-send-emails-from-your-node-js-server/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Use Nodemailer to Send Emails from Your Node.js&nbsp;Server</a>
      </p><p></p><p>O <a href="https://nodemailer.com/about/" rel="noopener">Nodemailer</a> é um módulo do Node.js que permite enviar e-mails para o seu servidor com facilidade. Quando você quiser se comunicar com seus usuários ou apenas ser notificado quando algo der errado, uma das opções para fazer isso seria usando o e-mail.</p><p>Existem muitos artigos explicando como usar o mínimo necessário do Nodemailer, mas esse artigo não é um deles. Aqui, eu vou te mostrar o modo mais comum de praticar o envio de e-mails do seu <em>back-end</em> do Node.js usando o Nodemailer e o Gmail.</p><h2 id="como-come-ar-com-o-nodemailer"><strong>Como começar com o Nodemailer</strong></h2><p>Primeiro, vamos precisar preparar o nosso Node.js usando o Express. Para ter certeza de que você possui o Node e o npm instalado, execute o seguinte comando:</p><pre><code class="language-bash">node -v 
npm -v</code></pre><p>Se os dois comandos mostrarem suas versões, você pode continuar. Do contrário, instale o que estiver faltando.</p><p>Crie um diretório para o seu projeto. Usaremos <strong><strong>nodemailerProject</strong></strong>.</p><pre><code class="language-bash">mkdir nodemailerProject</code></pre><p>Vá para o diretório criado e execute o seguinte comando:</p><pre><code class="language-bash">npm init</code></pre><p>Isso inicializará o nosso projeto com um arquivo <strong><strong>pacakge.json</strong></strong>.</p><p>A seguir, vamos instalar o Express, usando:</p><pre><code>npm install express</code></pre><p>Dependendo de qual arquivo você apontou como ponto de entrada (o padrão seria <code>index.js</code>), abra e cole o seguinte código:</p><figure class="kg-card kg-code-card"><pre><code class="language-node">const express = require('express')
const app = express()
const port = 3000


app.listen(port, () =&gt; {
  console.log(`nodemailerProject is listening at http://localhost:${port}`)
})</code></pre><figcaption>index.js</figcaption></figure><p>Acima, você tem o necessário para iniciar um servidor simples usando o Express. Você pode vê-lo funcionando executando o comando abaixo:</p><pre><code class="language-bash">node index.js</code></pre><h3 id="como-instalar-o-nodemailer"><strong>Como instalar o Nodemailer</strong></h3><p>Instale o Nodemailer usando o seguinte comando:</p><pre><code class="language-bash">npm install nodemailer</code></pre><p>A API do Nodemailer é bem simples. Faça o seguinte:</p><ol><li>Crie um objeto <strong><strong>Transporter</strong></strong></li><li>Crime um objeto <strong><strong>MailOptions</strong></strong></li><li>Use o método <strong><strong>Transporter.sendMai</strong>l</strong></li></ol><p>Para criar o objeto <code>Transporter</code>, devemos fazer o seguinte:</p><pre><code class="language-node">let transporter = nodemailer.createTransport({
      service: 'gmail',
      auth: {
        type: 'OAuth2',
        user: process.env.MAIL_USERNAME,
        pass: process.env.MAIL_PASSWORD,
        clientId: process.env.OAUTH_CLIENTID,
        clientSecret: process.env.OAUTH_CLIENT_SECRET,
        refreshToken: process.env.OAUTH_REFRESH_TOKEN
      }
    });</code></pre><blockquote>✋ Preste atenção, pois além do usuário e das chaves de acesso, que são suas próprias credenciais da sua conta do gmail, outras três chaves deverão ser recuperadas após configurar o OAuth.</blockquote><p>Assim como dissemos no começo do artigo, usaremos o Gmail para enviar e-mails. Como você deve ter imaginado, o Gmail possui um alto nível de segurança quando o assunto é enviar e-mails para/pela conta do usuário.</p><p>Existem inúmeras formas para superarmos esses obstáculos (algumas melhores que outras). A solução que escolhemos torna necessário configurar um projeto no <strong><strong>Google Cloud Platform</strong></strong>. Precisamos fazer isso para poder ter credenciais para segurança do <em>OAuth </em>habilitada pelo Gmail.</p><blockquote>Se você quiser ler mais sobre a complexidade de usar o Gmail com o nodemailer, vá <a href="https://nodemailer.com/usage/using-gmail/" rel="noopener">aqui</a> (documentação em inglês).</blockquote><p>O próximo passo requer algumas configurações em vez de código, portanto preparem-se.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/image-297.png" class="kg-image" alt="image-297" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/image-297.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/03/image-297.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/03/image-297.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/image-297.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1125" loading="lazy"><figcaption>Foto criada por <a href="https://unsplash.com/@d_mccullough?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Daniel McCullough</a>, extraída do <a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Unsplash</a></figcaption></figure><h2 id="configura-es-do-google-cloud-platform"><strong>Configurações do <strong>Google Cloud Platform</strong></strong></h2><p>Se você não tem uma conta no <a href="https://console.cloud.google.com/home" rel="noopener">Google Cloud Platform</a>, crie uma, pois é um pré-requisito. Possuindo a conta, crie um projeto clicando na seta do menu que fica no canto superior esquerdo.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_a4fnFLNMoTtLJuqsKilVnA.png" class="kg-image" alt="1_a4fnFLNMoTtLJuqsKilVnA" width="526" height="44" loading="lazy"></figure><p>Selecione a opção <em>New Project</em>:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_HNwUG3wPdbrwc3JB5D7_tg.png" class="kg-image" alt="1_HNwUG3wPdbrwc3JB5D7_tg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/1_HNwUG3wPdbrwc3JB5D7_tg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_HNwUG3wPdbrwc3JB5D7_tg.png 924w" width="924" height="61" loading="lazy"></figure><p>Na próxima janela, teremos que dar um nome ao nosso projeto. Escolha o que você quiser. Continuaremos usando <strong><strong>NodemailerProject</strong></strong>. Na propriedade <em>location</em>, você pode manter <em>No organization</em>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_TRlA6RBLCCCSMQ5R4di27A.png" class="kg-image" alt="1_TRlA6RBLCCCSMQ5R4di27A" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/1_TRlA6RBLCCCSMQ5R4di27A.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_TRlA6RBLCCCSMQ5R4di27A.png 689w" width="689" height="491" loading="lazy"></figure><p>Deve levar alguns segundos para o projeto estar pronto para ser usado. Quando estiver, será possível ver a seguinte janela:</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_FT9MhBZyU4cZd4Qg6zeFag.png" class="kg-image" alt="1_FT9MhBZyU4cZd4Qg6zeFag" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/1_FT9MhBZyU4cZd4Qg6zeFag.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_FT9MhBZyU4cZd4Qg6zeFag.png 1000w" width="1000" height="481" loading="lazy"></figure><p>Abra o menu de navegação clicando nos três pontos no canto superior esquerdo e selecione <strong><strong><em>APIs and Services</em>:</strong></strong></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_qPaPpPadHQLdKCQbhjND7Q.png" class="kg-image" alt="1_qPaPpPadHQLdKCQbhjND7Q" width="317" height="52" loading="lazy"></figure><p>Para habilitar a utilização do Nodemailer no Gmail, teremos que usar o OAuth2. Se você não estiver familiarizado com o OAuth, ele é um protocolo de autenticação. Eu não vou ser muito específico aqui, pois não é necessário. Se, no entanto, você quiser entender mais sobre isso, pode acessar <a href="https://oauth.net/2/" rel="noopener">aqui</a> (documentação do OAuth em inglês).</p><p>Primeiro, vamos configurar a nossa tela de consentimento do OAuth (em inglês, <em>OAuth Consent Screen</em>):</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_W2oeT1KmJXpwSQlIMIVo5w.png" class="kg-image" alt="1_W2oeT1KmJXpwSQlIMIVo5w" width="306" height="364" loading="lazy"></figure><p>Se você não for um membro do G-Suite, a única opção disponível será <em>External </em>em <em>User Type</em>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_l_GrPVtXODPS0GXKLMdWYA.png" class="kg-image" alt="1_l_GrPVtXODPS0GXKLMdWYA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/1_l_GrPVtXODPS0GXKLMdWYA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_l_GrPVtXODPS0GXKLMdWYA.png 861w" width="861" height="575" loading="lazy"></figure><p>Após clicar em <em>Create</em>, a próxima janela vai exigir o preenchimento das informações da aplicação (ou do servidor):</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_reZ04hUX4jh1IzLGh7vCFA.png" class="kg-image" alt="1_reZ04hUX4jh1IzLGh7vCFA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/1_reZ04hUX4jh1IzLGh7vCFA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_reZ04hUX4jh1IzLGh7vCFA.png 780w" width="780" height="675" loading="lazy"></figure><p>Preencha com o seu e-mail no campo <em>User support email</em> e no campo de informações de contato do desenvolvedor. Clicando em <em>Save and Continue</em>, será apresentada a fase <em>Scopes</em> dessa configuração. Pule essa fase, já que não é relevante para nós. A seguir, entramos na fase <em>Test Users</em>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_Jms50wZ5mVmUyOaiVF7b4w.png" class="kg-image" alt="1_Jms50wZ5mVmUyOaiVF7b4w" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/1_Jms50wZ5mVmUyOaiVF7b4w.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_Jms50wZ5mVmUyOaiVF7b4w.png 891w" width="891" height="735" loading="lazy"></figure><p>Aqui, se adicione como usuário e clique em <em>Save and continue</em>.</p><h2 id="como-configurar-o-oauth"><strong>Como configurar o <strong>OAuth </strong></strong></h2><p>Nesta fase, vamos criar as credenciais do OAuth para serem usadas com o Nodemailer. Vá até a aba <em>Credentials, </em>acima de <em>OAuth Consent Screen</em>. Clique no sinal de mais (➕) do texto <strong><strong><em>Create Credentials</em></strong> </strong>e escolha <strong><em>OAuth Client ID</em></strong>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2021/01/1_h0nME2ccR7HPjKmz_DMZRw.png" class="kg-image" alt="1_h0nME2ccR7HPjKmz_DMZRw" width="600" height="400" loading="lazy"></figure><p>No item <em><strong>Application type</strong></em>, escolha <strong><strong><em>Web Application</em></strong></strong>:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_72Em-VS-fdM2WCwOA6zcfg.png" class="kg-image" alt="1_72Em-VS-fdM2WCwOA6zcfg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/1_72Em-VS-fdM2WCwOA6zcfg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_72Em-VS-fdM2WCwOA6zcfg.png 699w" width="699" height="539" loading="lazy"></figure><p>Na seção <strong><strong><em>Authorized Redirect URIs</em></strong></strong>, não se esqueça de adicionar o "OAuth2 Playground" (<a href="https://developers.google.com/oauthplayground/" rel="nofollow noopener">https://developers.google.com/oauthplayground</a>), já que vamos usá-lo para pegar uma das chaves mencionadas anteriormente neste artigo.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_ywIcOlqA5DHdsPaSNnjJ9Q.png" class="kg-image" alt="1_ywIcOlqA5DHdsPaSNnjJ9Q" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/1_ywIcOlqA5DHdsPaSNnjJ9Q.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_ywIcOlqA5DHdsPaSNnjJ9Q.png 668w" width="668" height="202" loading="lazy"></figure><p>Após clicar em <em>Create</em>, você receberá o seu <em>Client id</em> e o segredo do <em>client</em>. Mantenha-os e nunca os exponha sob qualquer condição ou formato.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/image-298.png" class="kg-image" alt="image-298" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/03/image-298.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/03/image-298.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/03/image-298.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/03/image-298.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1325" loading="lazy"><figcaption>Foto criada por <a href="https://unsplash.com/@welipower?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Power Lai</a>, extraída do <a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit">Unsplash</a></figcaption></figure><h3 id="mantenha-o-seu-token-do-oauth-atualizado"><strong>Mantenha o seu token do <strong>OAuth </strong>atualizado</strong></h3><p>Para manter o seu token atualizado, o qual usaremos para transportar o objeto no Nodemailer, vamos precisar acessar o "OAuth2 Playground". Aprovamos esse "URI" para esse propósito específico em um momento anterior. </p><p>1. Clique no ícone de engrenagem à direita (que é a configuração do OAuth2) e marque a caixa para usar sua própria credencial do OAuth2 (em inglês, <em><strong>Use your own oAuth credentials</strong></em>):</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_Kbg3RnTBNkDd_RQ0zn59mQ.png" class="kg-image" alt="1_Kbg3RnTBNkDd_RQ0zn59mQ" width="559" height="680" loading="lazy"></figure><p>2. Do lado esquerdo, você verá uma lista de serviços. Role para baixo até ver <em><strong>Gmail API v1</strong></em>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/news/content/images/2021/01/1_BppvkU1r4JzZ6j6FvC2qNw.png" class="kg-image" alt="1_BppvkU1r4JzZ6j6FvC2qNw" width="600" height="400" loading="lazy"></figure><p>3. Clique em <strong><strong><em>Authorize APIs</em></strong>.</strong></p><p>Você será apresentado a uma tela para fazer login em qualquer uma de suas contas do Gmail. Escolha aquela que você listou como um usuário de teste (na fase <em><strong>Test Users</strong></em>, anteriormente).</p><p>4. A próxima tela informará que o Google ainda não verificou essa aplicação, mas isso está ok, já que nós não a enviamos para verificação. Clique em <em><strong>Continue</strong></em>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_rL0tNdaZqOyIg6aCp4IR3g.png" class="kg-image" alt="1_rL0tNdaZqOyIg6aCp4IR3g" width="566" height="385" loading="lazy"></figure><p>5. Na próxima janela, será perguntado se você quer conceder permissão ao seu projeto para interagir com a sua conta do Gmail. Dê a permissão clicando em <em><strong>Allow</strong></em>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/03/1_y0TUXbtC_oUaB6KoGlURbQ.png" class="kg-image" alt="1_y0TUXbtC_oUaB6KoGlURbQ" width="409" height="291" loading="lazy"></figure><p>6. Feito isso, você será redirecionado de volta para o OAuth Playground e poderá ver que há um código de autorização no menu à esquerda. Clique no botão azul &nbsp;"<strong><strong>Exchange authorization code for tokens</strong></strong>" (em português, <em>troca de autorização de código para tokens</em>).</p><p>Os campos para o token de atualização e para o token de acesso serão preenchidos.</p><h2 id="de-volta-ao-servidor"><strong>De volta ao servidor</strong></h2><p>Depois de fazer todas essas configurações, podemos retornar à nossa aplicação e inserir todos os dados na criação do transportador. Para manter todas as suas credenciais privadas, você pode usar o pacote <code>dotenv</code>. Não se esqueça de adicionar o arquivo <code>.env</code> que você criará no <code>.gitignore</code>.</p><p>Então, agora, temos o seguinte:</p><pre><code class="language-node">let transporter = nodemailer.createTransport({
      service: 'gmail',
      auth: {
        type: 'OAuth2',
        user: process.env.MAIL_USERNAME,
        pass: process.env.MAIL_PASSWORD,
        clientId: process.env.OAUTH_CLIENTID,
        clientSecret: process.env.OAUTH_CLIENT_SECRET,
        refreshToken: process.env.OAUTH_REFRESH_TOKEN
      }
    });</code></pre><p>Em seguida, criamos o objeto <code>mailOptions</code>, que contém os detalhes de para onde enviar o e-mail e com quais dados.</p><pre><code class="language-node">let mailOptions = {
      from: tomerpacific@gmail.com,
      to: tomerpacific@gmail.com,
      subject: 'Nodemailer Project',
      text: 'Hi from your nodemailer project'
    };</code></pre><p>Esse objeto pode ter muito mais campos e até mesmo vários destinatários, mas não entraremos nesses detalhes aqui. </p><p>Finalmente, usaremos o método sendMail:</p><pre><code class="language-node">transporter.sendMail(mailOptions, function(err, data) {
      if (err) {
        console.log("Error " + err);
      } else {
        console.log("Email sent successfully");
      }
    });</code></pre><p>Execute sua aplicação e verá na sua caixa de entrada que recebeu um novo e-mail. </p><p>Este artigo foi inspirado em um projeto que criei usando o Nodemailer. Se você quiser conferir, acesse-o <a href="https://github.com/TomerPacific/ProjectChecker">aqui</a>.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como construir sua própria aplicação de bate-papo em tempo real ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Sudheesh Shetty [https://medium.com/@sudheeshshetty] Os aplicações de mensagens estão ficando cada vez mais populares. Os últimos anos trouxeram aplicações como o WhatsApp, o Telegram, o Signal e o Line. As pessoas parecem preferir aplicações baseadas em bate-papo, pois permitem interação em tempo real. Elas também adicionam um toque pessoal ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-construir-sua-propria-aplicacao-de-bate-papo-em-tempo-real/</link>
                <guid isPermaLink="false">63aee81f44e27f060d7a50a1</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Rafael Fontenelle ]]>
                </dc:creator>
                <pubDate>Sun, 12 Feb 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/02/1_q9WivDkg8ALSxw1jG1y1Jw.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/building-a-chat-application-with-mean-stack-637254d1136d/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to build your own real-time chat app</a>
      </p><p>Escrito por: <a href="https://medium.com/@sudheeshshetty">Sudheesh Shetty</a></p><p>Os aplicações de mensagens estão ficando cada vez mais populares. Os últimos anos trouxeram aplicações como o WhatsApp, o Telegram, o Signal e o Line.</p><p>As pessoas parecem preferir aplicações baseadas em bate-papo, pois permitem interação em tempo real. Elas também adicionam um toque pessoal à experiência.</p><p>Recentemente, participei de um workshop conduzido pela Free Software Movement Karnataka (em português, Movimento de Software Livre Karnataka), em Bangalore, onde orientei um grupo de estudantes universitários.</p><p>Durante as interações, observei algumas coisas:</p><ol><li>Apesar de incentivar os alunos a interagir com o mentor, a comunicação sempre foi unilateral.</li><li>Os alunos muitas vezes ficavam tímidos para fazer perguntas durante as sessões.</li><li>Eles se sentiram mais à vontade para fazer perguntas e obter feedback em conversas individuais.</li></ol><p>Então, tivemos que encontrar uma solução para quebrar o gelo entre mentores e alunos. Uma aplicação de bate-papo local foi útil nessa situação. As pessoas adoram ser anônimas, o que dá a elas mais poder para se expressar e perguntar a qualquer hora e em qualquer lugar. Este é o mesmo mantra usado pela maioria dos fóruns populares da internet, como o Reddit e o 4chan. Estes são apenas alguns exemplos gigantes de aplicações semianônimas.</p><p>Assim, comecei a pensar nessa ideia e criei alguns dos requisitos e recursos básicos.</p><ol><li>Os usuários se registram fornecendo um identificador, que é exclusivo para cada usuário (com um nome fictício). Apenas o identificador será revelado a outros usuários. Desse modo, as pessoas são livres para escolher qualquer identificador e, portanto, permanecem anônimas.</li><li>Um membro pode ver outros membros que estão on-line. Eles têm a opção de ficar visíveis ao público, o que transmite sua mensagem para todos os membros on-line no bate-papo.</li><li>Para mensagens privadas, o remetente deve primeiro enviar uma solicitação ao outro membro. Outros membros, ao aceitarem o pedido, podem ter um bate-papo privado com eles.</li></ol><h3 id="tecnologias-e-ferramentas-usadas"><strong>Tecnologias e ferramentas usadas</strong></h3><ol><li>A <em>stack </em>MEAN (Mongo, Express, Angular e Node).</li><li><em>Sockets </em>para permitir a comunicação individual em tempo real</li><li>AJAX para inscrição e autenticação</li></ol><h3 id="como-criar-uma-aplica-o-de-bate-papo-simples">Como criar uma aplicação de bate-papo simples<strong>?</strong></h3><p>Neste tutorial, vou ajudá-lo a criar sua própria aplicação de bate-papo. Posteriormente, você pode integrá-la como um widget em qualquer projeto! Este tutorial não se concentrará no desenvolvimento completo de uma aplicação de bate-papo. Ajudará, no entanto, a construir um.</p><p><strong>Pré-requisito:</strong> você precisa ter algum conhecimento básico da <em>stack</em> MEAN, pois estamos fazendo uso dela para o projeto.</p><p>Primeiro, crie uma estrutura de diretório mais ou menos assim.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/02/aholQChXQkfdRI26smzgqaGHiw0Ak82Yg7Gx.jpg" class="kg-image" alt="aholQChXQkfdRI26smzgqaGHiw0Ak82Yg7Gx" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/02/aholQChXQkfdRI26smzgqaGHiw0Ak82Yg7Gx.jpg 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/02/aholQChXQkfdRI26smzgqaGHiw0Ak82Yg7Gx.jpg 800w" sizes="(min-width: 720px) 720px" width="800" height="600" loading="lazy"><figcaption><strong>Estrutura de diretórios do projeto</strong></figcaption></figure><p>Instale o <a href="https://nodejs.org/en/download/package-manager/" rel="noopener">Node.js</a> e o <a href="https://docs.mongodb.com/manual/administration/install-community/" rel="noopener">MongoDB</a>.</p><p>Usaremos o AngularJS 1 para este tutorial. Baixe a biblioteca do AngularJS <a href="https://angularjs.org/">aqui</a> e copie-a para a pasta <code>lib</code> no diretório <code>Client</code>.</p><p>Se você gosta de embelezar a aplicação, pode baixar qualquer biblioteca do CSS e copiá-la para <code>lib</code> também.</p><h3 id="construindo-o-servidor"><strong>Construindo o servidor</strong></h3><p><strong>Passo 1 </strong>— Inicie o projeto:</p><p>Entre no diretório <code>Server</code> e execute este comando:</p><pre><code>npm init</code></pre><p>Um novo projeto será iniciado. Forneça todos os detalhes necessários. O <em>package.json</em> será criado e vai ter esta aparência:</p><pre><code class="language-json">{
  "name": "chat",
  "version": "1.0.0",
  "description": "Chat application",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;&amp; exit 1"
  },
  "author": "Your name",
  "license": "ISC"
}</code></pre><p><strong>Passo 2</strong> — Instale as dependências.</p><ul><li><strong>socket.io</strong> — é uma biblioteca do <em>JavaScript</em> para aplicações da web em tempo real. Ele permite a comunicação bidirecional em tempo real entre <em>clients</em> e servidores da web.</li><li><strong>express</strong> — é uma estrutura de aplicação da web do <em>Node.js</em>. Ele fornece o conjunto de recursos para desenvolver aplicações da web e para dispositivos móveis. Pode-se responder à solicitação HTTP usando diferentes <em>middlewares </em>e também renderizar páginas em HTML.</li></ul><pre><code>npm install --save socket.io
npm install --save express</code></pre><p>Isso instalará as dependências necessárias e as adicionará ao <em>package.json</em>. Um campo a mais será adicionado ao <em>package.json</em>, que ficará assim:</p><pre><code class="language-json">"dependencies": {
    "express": "^4.14.0",
    "socket.io": "^1.4.8"
  }</code></pre><p><strong>Passo 3 — </strong>Criando o servidor</p><p>Crie um servidor que atenda na porta 3000 e que envie o documento html quando for chamado.</p><p>Inicie uma nova conexão de <em>socket</em> passando o objeto HTTP.</p><p>A conexão de evento estará escutando os <em>sockets</em> de entrada.</p><p>Cada <em>socket</em> emite um evento de desconexão que será chamado sempre que um <em>client</em> se desconectar.</p><ul><li><strong>socket.on</strong> espera pelo evento. Sempre que esse evento é acionado, a função de <em>callback</em> é chamada.</li><li><strong>io.emit</strong> é usado para enviar a mensagem para todos os <em>sockets </em>conectados a ele.</li></ul><p>A sintaxe é:</p><pre><code class="language-js">socket.on('evento', function(msg){})
io.emit('evento', 'mensagem')</code></pre><p>Crie um servidor com o nome <em>server.js</em>. Ele deverá:</p><ul><li>imprimir uma mensagem para o console após a conexão de um usuário</li><li>escutar eventos de mensagem de bate-papo e transmitir a mensagem recebida para todos os <em>sockets </em>conectados.</li><li>imprimir uma mensagem de desconexão no console sempre que um usuário se desconectar.</li></ul><p>O servidor vai ter uma aparência semelhante a esta:</p><pre><code class="language-js">var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendfile('index.html');
});

io.on('connection', function(socket){
  console.log('user connected');
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});</code></pre><h3 id="construindo-o-client"><strong>Construindo o <em>client</em></strong></h3><p>Crie o arquivo index.html no diretório <code>Client</code>, o arquivo <code>style.css</code> no diretório <code>CSS</code> e o arquivo <code>app.js</code> no diretório <code>JS</code> do <em>client</em>.</p><p><strong><em>index.html:</em></strong></p><p>Vamos escrever um HTML simples que possa receber nossa mensagem e também exibi-la.</p><p>Inclua <em>socket.io-client</em> e <em>angular.js</em> em elementos <code>script</code> no seu HTML.</p><pre><code class="language-html">&lt;script src="/path/to/angular.js"&gt;&lt;/script&gt;
&lt;script src="/socket.io/socket.io.js"&gt;&lt;/script&gt;</code></pre><p><strong>socket.io</strong> serve o <em>client</em> para nós. O padrão é se conectar ao host, que serve a página. O HTML final terá esta aparência:</p><pre><code class="language-html">&lt;!doctype html&gt;
&lt;html ng-app="myApp"&gt;
  &lt;head&gt;
    &lt;title&gt;Socket.IO chat&lt;/title&gt;
    &lt;link rel="stylesheet" href="/css/style.css"&gt;
    &lt;script src="/lib/angular/angular.js"&gt;&lt;/script&gt;
    &lt;script src="/socket.io/socket.io.js"&gt;&lt;/script&gt;
    &lt;script src="http://code.jquery.com/jquery-1.11.1.js"&gt;
    &lt;/script&gt;
    &lt;script src="/js/app.js"&gt;&lt;/script&gt;
  &lt;/head&gt;
  &lt;body ng-controller="mainController"&gt;
    &lt;ul id="messages"&gt;&lt;/ul&gt;
    &lt;div&gt;
      &lt;input id="m" ng-model="message" autocomplete="off" /&gt;
      &lt;button ng-click="send()"&gt;Send&lt;/button&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre><p><strong><em>CSS/style.css:</em></strong></p><p>Dê um estilo para a aplicação fazendo com que se pareça uma caixa de bate-papo. Você pode usar qualquer biblioteca.</p><pre><code class="language-css">* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
div { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
div input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
div button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }</code></pre><p><strong><em>JS/app.js:</em></strong></p><p>Crie uma aplicação com o <code>angular.js</code> e inicie uma conexão de <em>socket</em>.</p><ul><li><strong>socket.on</strong> escuta um determinado evento. Ele chama uma função de <em>callback</em> sempre que o evento for chamado.</li><li><strong>socket.emit</strong> é usado para emitir a mensagem para o evento específico.</li></ul><p>A sintaxe básica de ambos é:</p><pre><code class="language-js">socket.on('nome do evento', function(msg){});
socket.emit('nome do evento', mensagem);</code></pre><p>Assim, sempre que a mensagem for digitada e o botão for clicado, chame a função para enviar a mensagem.</p><p>Sempre que o soquete receber uma mensagem, exiba-a.</p><p>O código em JavaScript ficará mais ou menos assim:</p><pre><code class="language-js">var app=angular.module('myApp',[]);

app.controller('mainController',['$scope',function($scope){
 var socket = io.connect();
 $scope.send = function(){
  socket.emit('chat message', $scope.message);
  $scope.message="";
 }
 socket.on('chat message', function(msg){
  var li=document.createElement("li");
  li.appendChild(document.createTextNode(msg));
  document.getElementById("messages").appendChild(li);
 });
}]);</code></pre><h3 id="executando-a-aplica-o"><strong>Executando a aplicação</strong></h3><p>Vá para o diretório <code>Server</code>, onde nosso servidor está presente. Execute o servidor usando o seguinte comando:</p><pre><code>node server.js</code></pre><p>O servidor começa a rodar na porta 3000. Acesse o navegador e digite o seguinte url:</p><pre><code>http://localhost:3000</code></pre><h3 id="como-melhorar-a-aplica-o"><strong>Como melhorar a aplicação</strong></h3><p>Você pode criar um banco de dados para salvar detalhes e mensagens do usuário. Seria bom se o design fosse escalável para que você pudesse adicionar mais recursos posteriormente.</p><p>Você precisa instalar o Mongoose ou um módulo do MongoDB para usar um banco de dados do Mongo:</p><pre><code>npm install --save mongoose</code></pre><p>ou:</p><pre><code>npm install --save mongodb</code></pre><p>Aqui está a documentação para usar o <a href="http://mongoosejs.com/docs/index.html">mongoose</a> e o módulo <a href="https://www.mongodb.com/docs/drivers/node/current/">mongodb</a>.<br>Aqui está a aparência do meu design de esquema:</p><pre><code class="language-json">{
 "_id" : ObjectId("5809171b71e640556be904ef"),
 "name" : "Sudheesh Shetty",
 "handle" : "sudheesh",
 "password" : "556624370",
 "phone" : "8888888888",
 "email" : "sudheeshshetty@gmail.com",
 "friends" : [
    {
      "name" : "abc",
      "status" : "Friend"
    },
    {
      "name" : "xyz",
      "status" : "Friend"
    }
 ],
 "__v" : 0
}</code></pre><p>Aqui, o status de cada membro pode ser:</p><ul><li>Friend: afirmando que o membro é um amigo.</li><li>Pending: se o membro ainda não aceitou.</li><li>Blocked: se o membro bloqueou o outro membro.</li></ul><p>Suponha que o membro rejeitou uma solicitação de bate-papo. O remetente pode enviar uma solicitação de bate-papo novamente. Um usuário também pode salvar as mensagens criando uma coleção extra. Cada documento terá a mensagem, o remetente, o destinatário e a hora.</p><p>Portanto, projete seu banco de dados de acordo com suas necessidades específicas e como deseja tratar as mensagens.</p><p>2. Crie APIs REST para servir o <em>client</em>. Por exemplo, um terminal que envia uma página inicial, a partir da qual os usuários podem fazer outras solicitações.</p><p>Alguns dos meus <em>endpoints </em>de API são:</p><pre><code class="language-js">app.post('/register',function(req,res){})

app.post('/login',function(req,res){})

app.post('/friend_request',function(req,res){})

app.post('/friend_request/confirmed',function(req,res){})</code></pre><p>3. Pense em alguns recursos adicionais interessantes e implemente-os.</p><p>O autor criou uma aplicação de bate-papo:</p><p><a href="https://github.com/sudheeshshetty/Chat" rel="noopener"><strong>sudheeshshetty/Chat</strong></a><br><a href="https://github.com/sudheeshshetty/Chat" rel="noopener"><em>Contribua com o desenvolvimento do Chat criando uma conta no GitHub</em></a></p><p>Aqui está uma rápida olhada na minha aplicação de bate-papo:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/02/1-PmXr40QmsMiaRVejb1iS--qs3BqE2zINJE.png" class="kg-image" alt="1-PmXr40QmsMiaRVejb1iS--qs3BqE2zINJE" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/02/1-PmXr40QmsMiaRVejb1iS--qs3BqE2zINJE.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/02/1-PmXr40QmsMiaRVejb1iS--qs3BqE2zINJE.png 800w" sizes="(min-width: 720px) 720px" width="800" height="449" loading="lazy"><figcaption>Tela de autenticação</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/02/qQFOHwAEgl7k4DqVqRKVMlR1yd9c8T9I-388.png" class="kg-image" alt="qQFOHwAEgl7k4DqVqRKVMlR1yd9c8T9I-388" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/02/qQFOHwAEgl7k4DqVqRKVMlR1yd9c8T9I-388.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/02/qQFOHwAEgl7k4DqVqRKVMlR1yd9c8T9I-388.png 800w" sizes="(min-width: 720px) 720px" width="800" height="449" loading="lazy"><figcaption>Aparência da aplicação após a autenticação</figcaption></figure><p>Dê uma olhada na aplicação e, se gostar, dê a ela uma estrela. Há muitas maneiras de melhorar essa aplicação. Se tiver alguma sugestão, envie-a para o autor pelo e-mail <em>sudheeshshetty@gmail.com</em>.<br><br>Você pode seguir o autor no <a href="https://github.com/sudheeshshetty">GitHub</a>.<br></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como instalar o Node.js e o npm no Windows ]]>
                </title>
                <description>
                    <![CDATA[ Neste artigo, você aprenderá a trabalhar com o JavaScript no back-end usando o Node no Windows. Ao começar a trabalhar com o JavaScript e descobrir que você pode não apenas trabalhar com ele no front-end, mas também no back-end, um novo mundo de possibilidades parece se abrir. Para começar, percebemos ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-instalar-o-node-js-e-o-npm-no-windows/</link>
                <guid isPermaLink="false">63ca854891baea05fef710bd</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Daniel Rosa ]]>
                </dc:creator>
                <pubDate>Sun, 22 Jan 2023 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/pexels-digital-buggu-171198--1-.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-install-node-js-and-npm-on-windows-2/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Install Node.js and npm on Windows</a>
      </p><p>Neste artigo, você aprenderá a trabalhar com o JavaScript no <em>back-end</em> usando o Node no Windows.</p><p>Ao começar a trabalhar com o JavaScript e descobrir que você pode não apenas trabalhar com ele no front-end, mas também no <em>back-end</em>, um novo mundo de possibilidades parece se abrir.</p><p>Para começar, percebemos que não é necessário utilizar outra linguagem de programação para ter o <em>back-end</em> de suas aplicações funcionando. Em segundo lugar, o Node.js tem uma instalação simples e funciona em todas as plataformas de desenvolvimento com as quais estamos acostumados: Mac, Linux e Windows.</p><p>Neste artigo, mostrarei como instalar o Node no Windows com um guia passo a passo para deixá-lo pronto para o uso.</p><p>Também é uma ótima notícia o fato de que o gerenciamento de pacotes é facilitado, já que o npm (ou Node Package Manager) vem junto com a instalação do Node.</p><p>Com ele, você poderá ter acesso a uma quantidade quase infinita de dependências criadas pela comunidade. Você pode simplesmente instalar essas dependências em sua aplicação e não precisará fazer tudo do zero sempre que precisar.</p><p>Vamos, então, instalar o Node no Windows e começar a brincar com ele um pouco.</p><h2 id="como-instalar-o-node-no-windows"><strong>Como instalar o Node no Windows</strong></h2><p>A primeira coisa a se fazer é acessar o <a href="https://nodejs.org/">site oficial do Node</a>.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_site.png" class="kg-image" alt="node_site" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/01/node_site.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/01/node_site.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/01/node_site.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_site.png 1920w" sizes="(min-width: 1200px) 1200px" width="1920" height="968" loading="lazy"><figcaption>Página inicial do site do Node</figcaption></figure><p>O site é inteligente o suficiente para detectar o sistema que você está utilizando. Assim, se você estiver no Windows, provavelmente verá uma página como a da imagem acima. Bem no meio dela, dois botões mostram as possibilidades mais comuns – e mais recentes – para <em>download</em>.</p><p>Se estiver curioso sobre todos os recursos mais recentes que o Node tem a oferecer, clique no botão da direita. Para a maioria dos usuários, no entanto, o próprio site recomenda usar a versão de suporte estendido (em inglês, <em>Long-Term Support</em>, ou <em>LTS</em>), aquela disponível para <em>download</em> usando o botão da esquerda.</p><p>No momento em que este artigo foi criado, a versão LTS é a versão 16.14.0.</p><blockquote>Nota de tradução: no momento da tradução do texto, a versão LTS mais recente é a 18.13.0.</blockquote><p>Ao clicar em qualquer um dos botões, é feito o <em>download</em> de um arquivo .msi para o seu computador. O próximo passo é clicar nele e a instalação começará. O assistente abre e a janela a seguir é exibida:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install1.png" class="kg-image" alt="node_install1" width="491" height="384" loading="lazy"><figcaption>Página inicial do assistente de instalação do Node</figcaption></figure><p>Clique em <em>Next</em> (Avançar). Na janela seguinte, você lerá (você lerá, não lerá?) o Acordo de licença do usuário final (ou <em>EULA</em>, com base na sigla em inglês), aceitará os termos do acordo e clicará em <em>Next </em>novamente. A próxima janela é o local onde você selecionar a pasta de destino para o Node.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install2.png" class="kg-image" alt="node_install2" width="493" height="383" loading="lazy"></figure><p>O Windows normalmente recomenda que os programas sejam instalados na pasta Arquivos de programas (ou, em inglês, <em>Program Files</em>), cada um deles em sua pasta próprio (em nosso caso, como instalaremos o Node.js, a pasta <strong>nodejs</strong> parece o local ideal).</p><p>Para simplificar, vamos seguir as sugestões do assistente e usar <code>C:\Program Files\nodejs\</code> como a pasta de destino.</p><p>A janela a seguir é aquela na qual personalizamos nossa instalação. A menos que você tenha problemas com espaço em disco ou se tiver uma ideia bem clara do que está fazendo, recomendo manter as opções como estão e simplesmente clicar em <em>Next </em>novamente.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install3.png" class="kg-image" alt="node_install3" width="492" height="383" loading="lazy"></figure><p>Algo que eu gostaria de enfatizar nessa janela é a terceira opção que você verá. Essa é a opção que permite a instalação do npm com o Node em seu computador. Desse modo, se você ainda pretende alterar a configuração dessa página de algum outro modo, mantenha, pelo menos, essa opção como está e o npm será instalado para você ao final do processo.</p><p>A próxima janela trata da instalação automática das "Ferramentas para módulos nativos" (em inglês, <em>Tools for Native Modules</em>). Mais uma vez, a menos que você tenha a certeza de que precisa delas, recomendo deixar essa caixa de seleção desmarcada e clicar em <em>Next </em>mais uma vez.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install4.png" class="kg-image" alt="node_install4" width="488" height="383" loading="lazy"></figure><p>Chegamos à janela final pré-instalação. Conforme ela diz, aqui, basta clicar em <em>Install</em> (Instalar) para começar a instalação. Então, vamos lá.</p><p>Consegue observar o escudo azul e amarelo ao lado da palavra <em>Install</em>? Ele significa que o Windows pedirá para você confirmar se realmente deseja realizar o processo de instalação tão logo clique naquele botão. Levando em consideração que esse é o motivo de você estar lendo este artigo, basta clicar em <em>Yes</em> e deixar que o instalador faça seu serviço.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install5.png" class="kg-image" alt="node_install5" width="492" height="383" loading="lazy"></figure><p>Finalmente chegamos à janela que esperávamos, aquela que nos diz que o Node foi instalado com sucesso em nosso computador com o Windows. Clique em <em>Finish</em> (Finalizar) e vamos conferir se está tudo certo.</p><h2 id="como-verificar-sua-instala-o-do-node"><strong>Como verificar sua instalação do Node</strong></h2><p>Para verificar se o Node (e o npm) foram instalados corretamente em seu computador, você pode selecionar abrir o Windows Powershell ou o Prompt de comando.</p><p>Usaremos o primeiro neste exemplo. Clique na barra de pesquisa ao lado do botão do seu menu Iniciar e digite <code>powershell</code>. Pressione Enter e o Windows Powershell será aberto em uma janela para você.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install10.png" class="kg-image" alt="node_install10" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/01/node_install10.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/01/node_install10.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install10.png 1202w" sizes="(min-width: 1200px) 1200px" width="1202" height="639" loading="lazy"></figure><p>Em qualquer pasta (como, por exemplo, em <code>C:\Users</code>), você pode digitar <code>node -v</code> para conferir a versão do Node que está usando. Como mencionei anteriormente, a versão mais recente no momento em que escrevo este artigo é a versão 16.14.0 e é exatamente isso que vemos no Powershell acima.</p><blockquote>Nota de tradução: no momento da tradução deste artigo, se fizéssemos os mesmos passos com a versão LTS, a linha que diz <em><strong>v16.14.0</strong></em> diria <strong>v18.13.0</strong>.</blockquote><p>Vale a pena mencionar que, se você está se perguntando o motivo de podermos fazer essa verificação a partir de qualquer pasta, isso tem a ver com nossa maneira de instalar o Node e o npm. Uma das opções na configuração personalizada que vimos (e que deixamos como estava) foi a de adicionar o Node ao PATH (onde ficam os caminhos que o Windows carrega desde o início). Ao fazer isso, podemos acessá-lo de qualquer lugar ao navegar entre as pastas.</p><p>Também é possível conferir a versão do npm. Ao fazer isso, digite <code>npm -v</code> e pressione Enter. Em nosso caso, a versão mais recente é a versão 8.3.1. Então, podemos dizer que estamos atualizados.</p><blockquote>Nota de tradução: no momento da tradução deste artigo, se fizéssemos os mesmos passos com a versão LTS do Node, a linha que diz <em><strong>v8.3.1</strong></em> para a versão mais recente do npm diria <strong>v8.19.3</strong>.</blockquote><h2 id="como-usar-o-npm"><strong>Como usar o npm</strong></h2><p>Certo, mas você não chegou até aqui na leitura para concluir após a instalação do Node e do npm, correto? Você quer ver os dois em ação. Vamos lá, então.</p><p>Para aprender a iniciar um projeto com o Node e a instalar pacotes com o npm, usaremos o Visual Studio Code.</p><p>Criaremos uma pasta chamada Node_Test, onde colocaremos o Node e o npm a trabalhar um pouco.</p><p>Vamos começar com o simples. Dentro da pasta Node_Test, clique com o botão direito dentro da pasta e clique em <em>Open with Visual Studio Code </em>(Abrir com o VS Code). Isso abrirá o VS Code nessa pasta vazia automaticamente.</p><p>Dentro do VS Code, se você já não fez isso, abra um novo terminal pressionando <code>Ctrl+Shift+'</code> (aspa simples).</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install11.png" class="kg-image" alt="node_install11" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/01/node_install11.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/01/node_install11.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/01/node_install11.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install11.png 1917w" sizes="(min-width: 1200px) 1200px" width="1917" height="1037" loading="lazy"></figure><p>Clique no terminal e, na linha de comando, digite <code>npm init -y</code>. Isso iniciará um projeto do Node automaticamente para nós sem a necessidade de nos preocuparmos com toda a configuração inicial (a <em>flag</em> <code>-y</code> fara isso por conta própria). Será criado um arquivo <em>package.json</em> na pasta Node_Test.</p><p>Em seguida, vamos instalar o Express como dependência. Você pode encontrá-lo com uma lista de outras dependências possíveis do npm em <a href="https://www.npmjs.com/">https://www.npmjs.com/</a>.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install12.png" class="kg-image" alt="node_install12" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/01/node_install12.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/01/node_install12.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2023/01/node_install12.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install12.png 1907w" sizes="(min-width: 1200px) 1200px" width="1907" height="609" loading="lazy"></figure><p>Mais um detalhe: sempre que você abrir o site da web do npm, no canto superior esquerdo, você verá o que parece ser uma combinação de três palavras sem muito sentido. Se olhar as iniciais de cada uma, no entanto, verá que é uma sequência cuja sigla é npm.</p><p>Certo. Agora, vamos instalar o Express com essa "mantícora ronronadora eficaz" (esse é o significado do <em>Nifty Purring Manticore</em> acima, a propósito). De volta ao VS Code e ao terminal, digite <code>npm i express</code> e pressione Enter. O Express será instalado. Você pode fazer o mesmo com qualquer outra dependência que você imaginar.</p><p>Para ter certeza de que o Express foi instalado, abra o arquivo package.json. Role até a lista de dependências (a propriedade <em>dependencies</em> desse grande objeto que compõe o package.json) e você verá o Express lá.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install13.png" class="kg-image" alt="node_install13" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2023/01/node_install13.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2023/01/node_install13.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2023/01/node_install13.png 1337w" sizes="(min-width: 1200px) 1200px" width="1337" height="695" loading="lazy"></figure><h2 id="para-concluir"><strong>Para concluir</strong></h2><p>Era isso que tínhamos de momento. Neste artigo, você viu como instalar o Node e o npm no Windows.</p><p>Espero que o artigo tenha sido útil para você. Para ver mais tutoriais como esse em português, confira <a href="https://freecodecamp.org/portuguese/news">freecodecamp.org/portuguese/news</a> e busque pelo assunto sobre o qual você gostaria de aprender.</p><p>Boa programação para você! 😊</p> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
