<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Andrey Araújo</title>
    <description>The latest articles on Forem by Andrey Araújo (@andreyaraujo).</description>
    <link>https://forem.com/andreyaraujo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F462332%2F33195082-1d4c-43cb-94b2-1207a8dba7ff.jpg</url>
      <title>Forem: Andrey Araújo</title>
      <link>https://forem.com/andreyaraujo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/andreyaraujo"/>
    <language>en</language>
    <item>
      <title>As Vantagens do Tailwind CSS em Projetos ReactJS</title>
      <dc:creator>Andrey Araújo</dc:creator>
      <pubDate>Wed, 31 Jan 2024 14:26:14 +0000</pubDate>
      <link>https://forem.com/andreyaraujo/as-vantagens-do-tailwind-css-em-projetos-reactjs-4e5g</link>
      <guid>https://forem.com/andreyaraujo/as-vantagens-do-tailwind-css-em-projetos-reactjs-4e5g</guid>
      <description>&lt;p&gt;O desenvolvimento de aplicações web utilizando &lt;strong&gt;ReactJS&lt;/strong&gt; tem se tornado cada vez mais popular devido à sua &lt;strong&gt;flexibilidade&lt;/strong&gt; e &lt;strong&gt;eficiência&lt;/strong&gt;. Quando combinado com o framework &lt;strong&gt;Next.js&lt;/strong&gt;, os desenvolvedores têm acesso a uma experiência de desenvolvimento ainda mais robusta e otimizada. Principalmente quando se trata da última versão do Next.js e do ReactJS.&lt;/p&gt;

&lt;p&gt;Neste artigo, exploraremos as vantagens de integrar o Tailwind CSS em projetos ReactJS, com foco especial nas melhorias que ele pode oferecer quando utilizado com o Next.js. Além disso, vou mostrar uma alternativa interessante, o &lt;strong&gt;ShadcnUI&lt;/strong&gt;, que pode ser integrado de forma complementar ao TailwindCSS, trazendo ainda mais agilidade na criação de interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tailwind CSS
&lt;/h2&gt;

&lt;p&gt;O &lt;a href="https://tailwindcss.com/docs/installation" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt; é um framework CSS utilitário que proporciona uma abordagem única para o desenvolvimento de interfaces. Ele permite aos desenvolvedores criar designs personalizados diretamente em suas marcações. Diferente de outras bibliotecas CSS, como Bootstrap ou Material UI, que oferecem componentes predefinidos, Tailwind fornece classes utilitárias que você pode combinar para criar designs únicos.&lt;/p&gt;

&lt;p&gt;Suas vantagens são especialmente evidentes ao trabalhar com ReactJS e, mais ainda, em projetos Next.js. Algumas das principais vantagens incluem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Produtividade Aprimorada:&lt;/strong&gt; Com classes utilitárias predefinidas, &lt;code&gt;p-10 flex m-2&lt;/code&gt; por exemplo, o Tailwind acelera o desenvolvimento ao eliminar a necessidade de escrever CSS do zero. Isso resulta em um fluxo de trabalho mais ágil e produtivo para os desenvolvedores ReactJS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Estilo Consistente:&lt;/strong&gt; O Tailwind promove um estilo consistente em todo o projeto, graças às suas classes padronizadas. Isso simplifica a manutenção do código e garante uma experiência de usuário coesa. Então chega de perder tempo escolhendo nome para classes CSS!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customização Flexível:&lt;/strong&gt; Apesar de suas classes predefinidas, o Tailwind é altamente customizável. Isso permite que os desenvolvedores personalizem o design de acordo com as necessidades específicas do projeto, mantendo a flexibilidade do ReactJS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;A Integração Perfeita com Next.js&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Ao integrar o Tailwind CSS em projetos Next.js, as vantagens mencionadas são ainda mais perceptíveis. Next.js oferece um sistema de roteamento eficiente e renderização otimizada, enquanto o Tailwind simplifica o styling. Juntos, eles proporcionam um ambiente de desenvolvimento dinâmico e eficaz.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Otimização de Desempenho:&lt;/strong&gt; A natureza modular do Tailwind se alinha perfeitamente com a abordagem de componentes do React e Next.js. Isso resulta em um código mais otimizado e em um desempenho geral aprimorado da aplicação.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-Side Rendering (SSR) e Static Site Generation (SSG):&lt;/strong&gt; O Next.js suporta SSR e SSG, e ao integrar o Tailwind, a aplicação mantém um estilo consistente mesmo ao ser renderizada no servidor. Isso é crucial para garantir uma experiência do usuário mais suave.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  O que vejo falar sobre o Tailwind
&lt;/h2&gt;

&lt;p&gt;Tem um tempo já que pesquiso sobre esse framework, e como ele vem crescendo dentro da comunidade. Mas já vi muitos comentários do tipo: “ele só adiciona complexidade ao projeto”, “os arquivos React ficam enormes adicionando tantas classes nos elementos HTML”, e por ai vai.&lt;/p&gt;

&lt;p&gt;Confesso que no começo vi dessa forma, mas depois de começar a usar, a fazer vários testes, e recentemente usar em projetos do trabalho, mudei totalmente de ideia, e hoje vejo que esse framework traz mais vantagens do que desvantagens. &lt;/p&gt;

&lt;p&gt;Uma das vantagens do React é a possibilidade de componentizar elementos da nossa aplicação, e isso vai de encontro com a construção de interfaces usando Tailwind, por mais que as vezes precisemos adicionar bastante classes para estilizar um componente, vai do desenvolvedor analisar cada situação e componentizar o que for preciso, para não termos aqueles arquivos gigantes que adoramos dar manutenção. (contém ironia) &lt;/p&gt;

&lt;p&gt;E por mais que o Tailwind já traga bastante agilidade no desenvolvimento de interfaces, vou te mostrar uma outra ferramenta que vai te trazer ainda mais.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;ShadcnUI com TailwindCSS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Enquanto o Tailwind CSS é excepcional para a estilização utilitária, às vezes é desejável adicionar elementos de design mais complexos, ou que já tenham uma certa estilização pronta, para termos mais agilidade na criação de interfaces. É aqui que o &lt;a href="https://ui.shadcn.com/" rel="noopener noreferrer"&gt;ShadcnUI&lt;/a&gt; entra em cena. Este é um conjunto de componentes UI que podem ser facilmente integrados com o Tailwind, adicionando uma camada extra de estilo e interatividade.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Componentes Prontos para Uso:&lt;/strong&gt; O ShadcnUI oferece uma variedade de componentes prontos para uso, como botões, cards e modais, que podem ser facilmente integrados a projetos ReactJS com Tailwind, apenas fazendo uma instalação do componente.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Estilo Elegante e Responsivo:&lt;/strong&gt; Os componentes do ShadcnUI são projetados para serem elegantes e responsivos, complementando o estilo utilitário do Tailwind. Isso permite que os desenvolvedores alcancem uma estética visualmente atraente sem sacrificar a eficiência do desenvolvimento.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tamanho do framework:&lt;/strong&gt; O ShadcnUI não é igual ao MaterialUi, ou ChakraUI, que no momento da instalação já adiciona todos dos componentes disponíveis para usar. Nós fazemos a instalação apenas do componente que iremos usar, sendo totalmente customizável com as classes do tailwind. Isso eu vejo como uma grande vantagem.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx shadcn-ui@latest add button
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusão&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Ao escolher Tailwind CSS para estilização em projetos ReactJS, especialmente em conjunto com Next.js, os desenvolvedores podem alcançar uma eficiência e consistência notáveis. A adição do ShadcnUI oferece uma alternativa interessante para projetos que exigem componentes mais elaborados. Experimente essa combinação poderosa e impulsione seus projetos ReactJS para novos patamares de desenvolvimento eficiente e estilo envolvente.&lt;/p&gt;

&lt;p&gt;Se quiserem um vídeo mostrando essas ferramentas, desde instalação até a utilização em projetos reais, deixem ai nos comentários. 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Links úteis
&lt;/h2&gt;

&lt;p&gt;ShadcnUI: &lt;a href="https://ui.shadcn.com/docs" rel="noopener noreferrer"&gt;https://ui.shadcn.com/docs&lt;/a&gt;&lt;br&gt;
Tailwind CSS: &lt;a href="https://tailwindcss.com/docs/installation" rel="noopener noreferrer"&gt;https://tailwindcss.com/docs/installation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>braziliandevs</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Começando na programação em 2024</title>
      <dc:creator>Andrey Araújo</dc:creator>
      <pubDate>Tue, 02 Jan 2024 23:53:26 +0000</pubDate>
      <link>https://forem.com/andreyaraujo/comecando-na-programacao-em-2024-301g</link>
      <guid>https://forem.com/andreyaraujo/comecando-na-programacao-em-2024-301g</guid>
      <description>&lt;p&gt;A área da programação, apesar de suas promissoras oportunidades, não está isenta de desafios para aqueles que buscam iniciar suas carreiras. A crescente demanda por profissionais de tecnologia é evidente, mas o caminho até se tornar um programador competente pode ser íngreme e desafiador. Neste artigo, exploraremos as dificuldades enfrentadas pelos aspirantes a programadores, destacaremos o constante crescimento da indústria de tecnologia e ofereceremos dicas valiosas para superar as barreiras iniciais da carreira.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Os Desafios Iniciais na Jornada da Programação:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Abundância de Escolhas:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A variedade de linguagens de programação, frameworks e tecnologias pode ser esmagadora para quem está começando. A escolha certa pode ser difícil, e a curva de aprendizado varia de uma linguagem para outra.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autoconfiança e “Impostorismo”:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Muitos novatos enfrentam dúvidas sobre suas habilidades e se veem como "impostores". A autoconfiança é um desafio contínuo, mesmo para programadores experientes. Tentar fugir da síndrome do impostor é uma coisa que fazemos sempre, não importa a senioridade. Então esteja ciente que isso vai andar lado a lado na sua jornada.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Experiência Prática Limitada:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A teoria é crucial, mas a falta de experiência prática pode dificultar a aplicação do conhecimento em situações do mundo real, como resolver testes técnicos em entrevistas de empregos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;O Crescimento Exponencial da Área de Programação&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Aqui podemos destacar três pontos, o primeiro é a demanda crescente por profissionais de TI. Onde empresas de todos os tamanhos estão buscando talentos para impulsionar sua presença digital. Empresas pequenas estão querendo se destacar ou alavancar cada vez mais no mundo digital e as grandes estão buscando números maiores ainda ou melhoria nos seus processos.&lt;/p&gt;

&lt;p&gt;O segundo ponto é a diversidade de oportunidades, porque sabemos que a programação não se limita ao desenvolvimento de software. Áreas como ciência de dados, inteligência artificial, segurança cibernética oferecem uma gama diversificada de oportunidades.&lt;/p&gt;

&lt;p&gt;E por último a inovação constante. A natureza dinâmica da tecnologia exige que os programadores estejam sempre atualizados. Novos frameworks, linguagens e metodologias surgem regularmente, impulsionando a inovação na indústria.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Dicas para Superar os Desafios Iniciais e Ingressar no Mercado:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Escolha com Sabedoria e Comece com o Básico:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Inicie com uma linguagem amigável para iniciantes, como Python, e expanda gradualmente para outras à medida que ganha confiança.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Aproveite os Recursos Online:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Utilize plataformas online, cursos e tutoriais para aprender a programar. Há uma infinidade de recursos gratuitos disponíveis.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Participe de Comunidades Online:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Junte-se a fóruns e grupos de discussão. A comunidade de programadores é vasta e geralmente acolhedora para novatos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crie Projetos Práticos:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A aplicação prática do conhecimento é fundamental. Comece com projetos simples e vá aumentando a complexidade à medida que avança.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Busque Mentoria:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Ter um mentor pode ser inestimável. Procure orientação de programadores mais experientes para obter insights valiosos.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Não Tenha Medo de Errar:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Os erros são oportunidades de aprendizado. Enfrente desafios, corrija seus erros e evolua constantemente.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desenvolva Habilidades de Resolução de Problemas:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A programação é, em sua essência, a resolução de problemas. Pratique a lógica de programação e trabalhe em projetos desafiadores.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mantenha-se Atualizado e Esteja Aberto à Mudança:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;A tecnologia evolui rapidamente. Esteja disposto a aprender novas tecnologias e métodos de programação.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusão:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ingressar na área da programação pode ser desafiador, mas os benefícios a longo prazo são imensuráveis. Com dedicação, paciência e um compromisso contínuo com a aprendizagem, vocês podem superar as dificuldades iniciais e prosperar em um setor em constante expansão. Lembre-se de que o sucesso na programação é uma jornada, e cada linha de código é um passo em direção ao domínio das habilidades necessárias para se destacar no mundo digital.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>braziliandevs</category>
    </item>
    <item>
      <title>Estrutura de dados - Coleções chaveadas</title>
      <dc:creator>Andrey Araújo</dc:creator>
      <pubDate>Wed, 22 Mar 2023 00:56:44 +0000</pubDate>
      <link>https://forem.com/andreyaraujo/estrutura-de-dados-colecoes-chaveadas-3g5g</link>
      <guid>https://forem.com/andreyaraujo/estrutura-de-dados-colecoes-chaveadas-3g5g</guid>
      <description>&lt;p&gt;Sabemos que todas as linguagens de programação tem estrutura de dados embutidas e que se diferem uma das outras. Meu objetivo aqui não vai ser explicar e mostrar o que são e como funcionam estrutura de dados em si, mas mostrar um tipo de estrutura de dados em Javascript que acredito que seja interessante conhecermos, por mais que no dia a dia quase sempre recorremos a outro tipo de estrutura de dados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Map
&lt;/h2&gt;

&lt;p&gt;Na estrutura Map, temos conjuntos de chave e valor, e o mais interessante aqui é que podemos ter &lt;strong&gt;qualquer tipo de valor&lt;/strong&gt; para identificar essas chaves e valores.&lt;/p&gt;

&lt;p&gt;O conjunto de valores é iterado por ordem de inserção, e quando fazemos uma iteração nessa estrutura, usando um loop, for...of por exemplo, é &lt;strong&gt;retornado um array de [chave, valor]&lt;/strong&gt; para cada iteração.&lt;/p&gt;

&lt;p&gt;Aqui já podemos perceber que os objetos são praticamente iguais aos Maps, e sempre optamos por usar objetos. Mas vou te mostrar algumas diferenças entre eles:&lt;/p&gt;

&lt;h3&gt;
  
  
  Tipos das chaves
&lt;/h3&gt;

&lt;p&gt;As chaves do Map podem ser qualquer valor (incluindo funções, objetos, ou qualquer outro tipo primitivo). &lt;br&gt;
A chave de um Objeto deve ser uma String ou um Symbol.&lt;/p&gt;
&lt;h3&gt;
  
  
  Iteração
&lt;/h3&gt;

&lt;p&gt;Um Map é iterável, então ele pode ser diretamente iterável.&lt;br&gt;
O Objeto não implementa o protocolo de iteração, e os objetos não podem ser iterados diretamente usando o for...of (por padrão).&lt;/p&gt;
&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;O Map performa melhor em cenários envolvendo adições e remoções frequentes em pares chave-valor.&lt;br&gt;
Já o Objeto não é otimizado para adições e remoções frequentes de pares chave-valor.&lt;/p&gt;
&lt;h2&gt;
  
  
  Definindo Maps
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contacts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Andrey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;andreyaraujo.dev@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Andrey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="c1"&gt;// {email: 'andreyaraujo.dev@gmail.com'}&lt;/span&gt;
&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Araújo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Andrey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;É bastante simples usar Maps, mas temos que ter cuidados com alguns pontos ao definirmos Maps e seus valores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contacts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Andrey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;andreyaraujo.dev@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa forma de definir propriedades não interage com a estrutura de dados do Map. Dessa forma é usada a implementação genérica do objeto. O valor 'Andrey' não é armazenado no Map para queries. Outras operações nos dados irão falhar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Andrey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;contacts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Andrey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  WeakMap
&lt;/h2&gt;

&lt;p&gt;Da mesma forma que o Map, o WeakMap é um objeto com chave/valor, em que as chaves são fracamente referenciadas. Os valores podem ser de qualquer tipo, já as chaves tem que ser objetos.&lt;/p&gt;

&lt;p&gt;A sua utilização é bem semelhante ao Map, mas podendo receber um Array ou outro objeto iterável cujos elementos são pares key-value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WeakMap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;wm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;andrey&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;99999&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Set
&lt;/h2&gt;

&lt;p&gt;Objetos Set são coleções iteráveis, por ordem de inserção, que &lt;strong&gt;aceitam qualquer tipo de valor, desde que não se repitam&lt;/strong&gt;. Na sua definição também podemos passar um objeto iterável, sem  valores repetidos, onde todos esses valores são adicionados ao novo Set. Caso esse objeto iterável contenha itens repetidos, o novo objeto não terá esses objetos repetidos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mySet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;// {1, 2, 3}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Comparando ao Array, o Set tem algumas facilidades, como busca, deleção de elementos, (.has, .delete) mas ainda tem funcionalidades bem básicas, o Array nos da muito mais opções como por exemplo, &lt;code&gt;.reduce, .sort, .filter&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mas e porque usar o Set ao invés de Array ou objeto normal?&lt;/strong&gt;&lt;br&gt;
Como o Set contém apenas elementos distintos, deixa a vida muito mais fácil se soubermos antecipadamente que queremos evitar salvar dados duplicados em nossa estrutura.&lt;/p&gt;

&lt;h2&gt;
  
  
  WeakSet
&lt;/h2&gt;

&lt;p&gt;Assim como no objeto Set, o WaekSet permite armazenar valores únicos. Também pode receber como parâmetro um objeto iterável. A diferença aqui é que no WeakSet, &lt;strong&gt;só podemos armazenar objetos&lt;/strong&gt;, e não qualquer tipo de valor igual no Set. Aqui também as referências ao objetos na coleção são mantidos fracamente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O Javascript nos da algumas opções para trabalhar com estrutura de dados, por mais que no dia a dia não sejam tão usadas, para cada caso elas tem sua utilidade e valor, cabe a nós analisar e ver onde cada uma se encaixa melhor. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>braziliandevs</category>
      <category>brasil</category>
    </item>
    <item>
      <title>Usando Docker e docker-composer no dia a dia</title>
      <dc:creator>Andrey Araújo</dc:creator>
      <pubDate>Fri, 05 Mar 2021 22:40:24 +0000</pubDate>
      <link>https://forem.com/andreyaraujo/usando-docker-e-docker-composer-no-dia-a-dia-4mi</link>
      <guid>https://forem.com/andreyaraujo/usando-docker-e-docker-composer-no-dia-a-dia-4mi</guid>
      <description>&lt;p&gt;Vou mostrar aqui apenas como se inicia um projeto em Node e Typescript, com Docker e banco de dados Postgres. Espero que o que tem aqui os inspire a ir em busca de mais conhecimento sobre o assunto.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sumário
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.notion.so/Iniciando-projeto-com-Docker-e-Docker-compose-64da0c5a5d4c46549a303fad14316c39" rel="noopener noreferrer"&gt;Iniciando o projeto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.notion.so/Iniciando-projeto-com-Docker-e-Docker-compose-64da0c5a5d4c46549a303fad14316c39" rel="noopener noreferrer"&gt;Arquivos iniciais&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.notion.so/Iniciando-projeto-com-Docker-e-Docker-compose-64da0c5a5d4c46549a303fad14316c39" rel="noopener noreferrer"&gt;Criando o arquivo Dockerfile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.notion.so/Iniciando-projeto-com-Docker-e-Docker-compose-64da0c5a5d4c46549a303fad14316c39" rel="noopener noreferrer"&gt;Docker Compose&lt;/a&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.notion.so/Iniciando-projeto-com-Docker-e-Docker-compose-64da0c5a5d4c46549a303fad14316c39" rel="noopener noreferrer"&gt;Mão na massa...&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;&lt;a href="https://www.notion.so/Iniciando-projeto-com-Docker-e-Docker-compose-64da0c5a5d4c46549a303fad14316c39" rel="noopener noreferrer"&gt;Usando variáveis de ambiente no docker compose&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://www.notion.so/Iniciando-projeto-com-Docker-e-Docker-compose-64da0c5a5d4c46549a303fad14316c39" rel="noopener noreferrer"&gt;Conclusão&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href="https://www.notion.so/Iniciando-projeto-com-Docker-e-Docker-compose-64da0c5a5d4c46549a303fad14316c39" rel="noopener noreferrer"&gt;Links úteis&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  Iniciando o projeto
&lt;/h2&gt;

&lt;p&gt;Para iniciar o projeto vou rodar o comando &lt;code&gt;yarn init -y&lt;/code&gt;, caso esteja usando o npm é só trocar por &lt;code&gt;npm init -y&lt;/code&gt;. Com isso vai ser criado o arquivo package.json. &lt;/p&gt;

&lt;p&gt;Logo em seguida vamos instalar todas as dependências do projeto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;yarn add express&lt;/li&gt;
&lt;li&gt;yarn add -D @types/express&lt;/li&gt;
&lt;li&gt;yarn add -D typescript ts-node nodemon&lt;/li&gt;
&lt;li&gt;yarn tsc —init (Para criar o arquivo &lt;code&gt;tsconfig.json&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Com todas as dependências instaladas, agora vamos começar a codar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquivos iniciais
&lt;/h2&gt;

&lt;p&gt;Na raiz do seu projeto crie uma pasta chamada &lt;code&gt;src&lt;/code&gt; e dentro dela crie dois arquivos, &lt;code&gt;index.ts&lt;/code&gt; e &lt;code&gt;routes.ts&lt;/code&gt;. No arquivo &lt;code&gt;index.ts&lt;/code&gt; vamos ter o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./routes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// 4&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 6&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🔥 Server started at http://localhost:3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Importamos o express.&lt;/li&gt;
&lt;li&gt;Importamos o arquivo de rotas.&lt;/li&gt;
&lt;li&gt;Criamos uma variável chamada &lt;code&gt;app&lt;/code&gt; e atribuímos a ela o módulo com funções do express.&lt;/li&gt;
&lt;li&gt;Configuramos para que o &lt;code&gt;app&lt;/code&gt; faça o parse do JSON.&lt;/li&gt;
&lt;li&gt;Dizemos para o &lt;code&gt;app&lt;/code&gt; usar o arquivo de rotas.&lt;/li&gt;
&lt;li&gt;Dizemos para o &lt;code&gt;app&lt;/code&gt; subir o servidor na porta &lt;code&gt;3000&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Agora vamos para o arquivo de rotas. No arquivo &lt;code&gt;routes.ts&lt;/code&gt; coloque o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Router&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Olá Mundo!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apenas criamos uma rota do tipo GET que devolve uma resposta "Olá Mundo!", sem muita complicação, aqui é moleza!&lt;/p&gt;

&lt;p&gt;Por último, mas não menos importante, no arquivo &lt;code&gt;package.json&lt;/code&gt; temos que inserir um script para subir a aplicação, então, coloque o seguinte código logo antes das declarações das dependências do projeto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx nodemon --exec ts-node ./src/index.ts --ignore-watch node_modules"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui estamos dizendo pro &lt;code&gt;nodemon&lt;/code&gt; executar o &lt;code&gt;ts-node&lt;/code&gt; partindo do arquivo &lt;code&gt;index.ts&lt;/code&gt; ignorando a pasta &lt;code&gt;node_modules&lt;/code&gt;. Nada de outro mundo aqui.&lt;/p&gt;

&lt;p&gt;E para testar tudo no seu terminal, rode o comando &lt;code&gt;yarn dev&lt;/code&gt; ou &lt;code&gt;npm run dev&lt;/code&gt;, o resultado deve ser mais ou menos esse:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F930a79f5l75kjgserg6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F930a79f5l75kjgserg6t.png" alt="Alt Text" width="675" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando o arquivo Dockerfile
&lt;/h2&gt;

&lt;p&gt;Depois de ter criado a aplicação e testado, vamos criar o arquivo Dockerfile. Nesse arquivo vai conter apenas as configurações iniciais do projeto para criar nossa imagem, como por exemplo, versão do node.&lt;/p&gt;

&lt;p&gt;Mas antes disso você sabe o que é o Dockerfile? Para que serve?&lt;/p&gt;

&lt;p&gt;Dockerfile é o arquivo onde definimos as instruções para criar as nossas próprias imagens. Ele tem sua própria sintaxe com os seus respectivos comandos. Nele é como se tivesse uma receita de bolo, só que no nosso caso o bolo é a aplicação, é uma receita para criar nossa imagem da aplicação.&lt;/p&gt;

&lt;p&gt;Para este exemplo vamos colocar o seguinte conteúdo no nosso arquivo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:alpine&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;yarn

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["yarn", "dev"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos saber pra que serve cada instrução dessa.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;FROM&lt;/code&gt; → De onde vai baixar a imagem que vamos utilizar, no caso vamos usar a ver alpine do node, que é uma versão mais simplificada.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;WORKDIR&lt;/code&gt; → Define o diretório onde a aplicação vai ficar no disco do container, aqui você pode usar o diretório que preferir.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;COPY&lt;/code&gt; → Copia tudo que começa com package e termina com .json para dentro da pasta /usr/src/app.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RUN&lt;/code&gt; → Executa o yarn ou npm install para adicionar as dependências do projeto e criar a pasta node_modules.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;COPY&lt;/code&gt; → Copia tudo que está no diretório onde o arquivo Dockerfile está para dentro da pasta que definimos no WORKDIR.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;EXPOSE&lt;/code&gt; → Expomos uma porta para o container ficar ouvindo os acessos.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CMD&lt;/code&gt; → Executa o comando yarn dev que está nos scripts do package.json para iniciar a aplicação. Aqui separamos todas as palavras por vírgula dentro de um array.&lt;/p&gt;

&lt;p&gt;Crie um arquivo .dockerignore para ignorar algumas coisas, neste exemplo vamos adicionar a pasta node_modules para ser ignorada.&lt;/p&gt;

&lt;p&gt;Agora para verificar se está tudo certo vamos rodar o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;docker build -t dockernode .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker build&lt;/code&gt; cria uma imagem a partir do Dockerfile&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-t&lt;/code&gt; é o nome da imagem&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dockernode&lt;/code&gt; é o nome que escolhi para essa imagem&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.&lt;/code&gt; é onde o Dockerfile está, o comando será executado no mesmo diretório que o Dockerfile se encontra.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se a saída no terminal for algo semelhante a isso, deu tudo certo na criação da imagem:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9n166t7ty7h2xeqx66th.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9n166t7ty7h2xeqx66th.png" alt="Alt Text" width="434" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você chegou até aqui sem nenhum erro, ótimo, mas ainda faltam algumas coisinhas. Até agora só criamos a imagem, falta criar o container. E para isso temos e executar o comando abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;docker run -p 3000:3000 -d dockernode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docker run&lt;/code&gt; cria um container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-p 3000:3000&lt;/code&gt; libera a porta 3000 do container para que ele possa ouvir as requisições de fora acessando a porta 3000.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdjratv89f2ipsnk6wu8n.png" alt="Alt Text" width="362" height="58"&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; detach, o terminal fica livre e o processo roda em segundo plano. (Se você não passar essa tag você não conseguirá mais usar a aba do terminal, ficará travada mostrando o processo.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dockernode&lt;/code&gt; o nome da imagem que estou usando para criar o container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjpq480o18hrs4ap5ho2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjpq480o18hrs4ap5ho2.png" alt="Alt Text" width="800" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rodando o comando será exibido o ID do container e executando no terminal &lt;code&gt;docker ps&lt;/code&gt; será listado o processo em execução no Docker.&lt;/p&gt;

&lt;p&gt;É interessante observar, a aplicação está rodando dentro do container do Docker, e não na nossa máquina local. Para acessar basta colocar no navegador &lt;code&gt;[http://localhost:3000](http://localhost:3000)&lt;/code&gt; que será exibida a mensagem "Olá Mundo!"&lt;/p&gt;

&lt;p&gt;O comando docker run só precisa ser executado uma vez para criar o container, para outras operações usamos: &lt;code&gt;docker start &amp;lt;id do container&amp;gt;&lt;/code&gt; para iniciar, &lt;code&gt;docker stop &amp;lt;id do container&amp;gt;&lt;/code&gt; para parar e &lt;code&gt;docker logs &amp;lt;id do container&amp;gt;&lt;/code&gt; para ver os logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Compose
&lt;/h2&gt;

&lt;p&gt;Estamos chegando a última parte do nosso exemplo de uso de Dockerfile e Docker Compose, agora vamos ver o que é e como funciona o Docker Compose.&lt;/p&gt;

&lt;p&gt;Basicamente o Docker compose é um orquestrador de containers no Docker. Ele vai definir como o container deve se comportar. Anteriormente no dockerfile definimos como a aplicação vai funcionar, o Docker compose vai fazer o banco de dados subir, a aplicação ficar no ar e se conectar com o banco de dados, neste exemplo, mas ele pode fazer muito mais.&lt;/p&gt;

&lt;p&gt;Vou mostrar também um recurso muito legal que são os volumes, usamos eles para espelhar os arquivos do projeto na máquina local com o volume do container. Dessa forma toda vez que alterarmos qualquer arquivo na máquina local ele enviará para o container do Docker. (Para isso que instalamos o nodemon).&lt;/p&gt;

&lt;h3&gt;
  
  
  Mão na massa...
&lt;/h3&gt;

&lt;p&gt;Na raiz do projeto crie o arquivo &lt;code&gt;docker-compose.yml&lt;/code&gt; e dentro dele coloque o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;version: "3"
services: 
  api:
    image: dockernode
    container_name: "app"
    ports: 
      - "3000:3000"
    links: 
      - link-db
    volumes: 
      - ./:/usr/src/app
  link-db:
    image: postgres
    container_name: "postgres"
    volumes: 
      - ./postgres:/var/lib/postgres
    ports: 
      - "5432:5432"
    environment: 
      - POSTGRES_USER=your_user
      - POSTGRES_DB=your_db
      - POSTGRES_PASSWORD=your_pass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;version&lt;/code&gt; → Especifica a versão do docker-compose file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;services&lt;/code&gt; → Define um serviço.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;api&lt;/code&gt; → Nome do serviço, aqui você pode colocar o nome que preferir.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;image&lt;/code&gt; → imagem que o serviço vai usar.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;container_name&lt;/code&gt; → Como o próprio nome diz, é o nome do container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ports&lt;/code&gt; → Portas que serão usadas no host e no container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;links&lt;/code&gt; → Link para containers em outro serviço.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;volumes&lt;/code&gt; → Diretório que usamos para espelhar, antes dos dois pontos é o diretório que vamos pegar os arquivos e depois dos dois pontos o diretório de destino, que vai ser o do container.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;environment&lt;/code&gt; → Contém as variáveis de ambiente do banco de dados, aqui definimos o usuário, senha e banco de dados que a aplicação vai usar para se conectar com o banco de dados.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aqui coloquei a pasta para os arquivos do banco de dados na mesma pasta do projeto, mas só como exemplo, você deve definir uma outra pasta para poder guardar esses arquivos do banco de dados. (Volumes do service link-db)&lt;/p&gt;

&lt;p&gt;Antes de executar o comando do &lt;code&gt;docker-compose&lt;/code&gt; vamos parar o container e excluí-lo.&lt;/p&gt;

&lt;p&gt;Execute no terminal &lt;code&gt;docker ps&lt;/code&gt; para conferir se o container está executando, pegue o ID do container e para parar o container rode o comando &lt;code&gt;docker stop &amp;lt;id&amp;gt;&lt;/code&gt; e depois execute &lt;code&gt;docker rm &amp;lt;id&amp;gt;&lt;/code&gt;  para remover o container, por fim execute o comando abaixo para criar o container e subir o serviço:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pronto, ele vai iniciar o serviço fazendo &lt;em&gt;build&lt;/em&gt; do projeto conforme o Dockerfile, liberar a porta 3000 e ficará monitorando a pasta do projeto a partir da &lt;code&gt;rootDir&lt;/code&gt; e enviar para &lt;code&gt;/usr/src/app&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para parar o serviço tecle &lt;code&gt;CTRL+C&lt;/code&gt;. Pode rodar com &lt;code&gt;docker-compose up -d&lt;/code&gt; para rodar em &lt;em&gt;background&lt;/em&gt; e liberar o terminal.&lt;/p&gt;

&lt;p&gt;Agora sim tudo pronto, já temos o serviço sendo executado, e acessando &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; teremos "Olá Mundo" como retorno.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usando variáveis de ambiente no docker compose
&lt;/h2&gt;

&lt;p&gt;Um arquivo que nos ajuda e poupa um bom trabalho nos projetos é o arquivo &lt;code&gt;.env&lt;/code&gt; , (eu espero que todos usem 😄), com ele definimos todas as variáveis de ambiente que nosso projeto usar, usuário de banco de dados, host, senha, por exemplo. &lt;/p&gt;

&lt;p&gt;E como vimos anteriormente, no arquivo &lt;code&gt;docker-compose.yml&lt;/code&gt; existem algumas dessas variáveis, mas setamos elas manualmente, isso pode expor dados sensíveis da nossa aplicação, já que esse arquivo fica exposto para todos. Na sessão de &lt;code&gt;environment&lt;/code&gt; no banco de dados, vamos substituir algumas coisas. Então vamos lá.&lt;/p&gt;

&lt;p&gt;Na raiz do projeto crie um arquivo chamado &lt;code&gt;.env&lt;/code&gt; e nele coloque o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="nx"&gt;Database&lt;/span&gt;
&lt;span class="nx"&gt;DB_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;your_user&lt;/span&gt;
&lt;span class="nx"&gt;DB_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;your_db&lt;/span&gt;
&lt;span class="nx"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;your_password&lt;/span&gt;
&lt;span class="nx"&gt;DB_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5432&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;São as mesmas variáveis que estão no arquivo docker-compose.yml, substitua os valores delas pelos seus dados.&lt;/p&gt;

&lt;p&gt;No arquivo docker-compose.yml faça as seguinte alterações:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;${DB_PORT}:5432&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;DB_USER&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na parte do serviço do banco de dados, coloque os mesmos nomes das variáveis de ambiente que você definiu anteriormente. &lt;/p&gt;

&lt;p&gt;Certo, mas como o arquivo do &lt;code&gt;docker-compose.yml&lt;/code&gt; vai entender essas variáveis de ambiente se eu não tenho nenhuma configurada na minha máquina?&lt;/p&gt;

&lt;p&gt;Para isso temos que criar um arquivo &lt;code&gt;makefile&lt;/code&gt;, que vai criar essas variáveis pra gente e fazer com que o arquivo do docker entenda essas variáveis. E para subir a aplicação, ao invés de usar &lt;code&gt;docker-compose up&lt;/code&gt;, vamos usar &lt;code&gt;make up&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Então na raiz do seu projeto crie um arquivo chamado &lt;code&gt;Makefile&lt;/code&gt;. Esse arquivo é bastante simples, não tem nada demais, apenas algumas instruções:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="k"&gt;include&lt;/span&gt;&lt;span class="sx"&gt; .env&lt;/span&gt;

&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;up&lt;/span&gt;

&lt;span class="nl"&gt;up&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt; 

&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;down&lt;/span&gt;

&lt;span class="nl"&gt;down&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    docker-compose down

&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;logs&lt;/span&gt;

&lt;span class="nl"&gt;logs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; 
    docker-compose logs &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;include&lt;/code&gt; vai incluir o arquivo &lt;code&gt;.env&lt;/code&gt; e no escopo da execução o arquivo vai entender as variáveis de ambiente como se todas tivessem exportadas.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.PHONY&lt;/code&gt; força a criação de um rótulo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agora você pode executar o comando &lt;code&gt;make up&lt;/code&gt; no terminal.&lt;/p&gt;

&lt;p&gt;Pronto, acessando &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; no navegador você verá que a aplicação está no ar. E acessando o banco de dados com um aplicativo de sua preferência você verá que o banco de dados foi criado e também já está no ar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Apesar desse app ter sido bem simples, as vantagens de usar o Docker são grandes, ainda mais quando começamos a usar mais de um banco de dados, vários serviços, e temos que trabalhar em equipe, todos com as mesmas versões e configurações do projeto. &lt;/p&gt;

&lt;p&gt;Outra coisa que agrada bastante é que se formos apagar os containers e as imagens, não fica nenhum arquivo no nosso computador, aquele lixo na máquina.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links úteis
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/gomex/docker-para-desenvolvedores" rel="noopener noreferrer"&gt;gomex/docker-para-desenvolvedores&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ingresse/docker-e-docker-compose-um-guia-para-iniciantes-48k8"&gt;Docker e Docker Compose um guia para iniciantes.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>node</category>
    </item>
  </channel>
</rss>
