<?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[ Paula Flávia Pagotto Simionato - 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[ Paula Flávia Pagotto Simionato - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/portuguese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Thu, 28 May 2026 16:39:29 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/portuguese/news/author/paulaflavia/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ O que é Tailwind CSS? Um guia para iniciantes ]]>
                </title>
                <description>
                    <![CDATA[ Escrever CSS pode ser muito difícil. Não se discute. Eu entendo – pode ser frustrante definir suas próprias ideias ou os designs que você recebe de sua equipe de design. Tenho certeza de que muitos de vocês passaram pelo mesmo incômodo ao menos algumas vezes em suas carreiras de desenvolvimento. ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/o-que-e-tailwind-css-um-guia-para-iniciantes/</link>
                <guid isPermaLink="false">632867a5926c2f06e57d1afe</guid>
                
                    <category>
                        <![CDATA[ Tailwind ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paula Flávia Pagotto Simionato ]]>
                </dc:creator>
                <pubDate>Thu, 29 Sep 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Group-69.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/what-is-tailwind-css-a-beginners-guide/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">What is Tailwind CSS? A Beginner's Guide</a>
      </p><p>Escrever CSS pode ser muito difícil. Não se discute. Eu entendo – pode ser frustrante definir suas próprias ideias ou os designs que você recebe de sua equipe de design.</p><p>Tenho certeza de que muitos de vocês passaram pelo mesmo incômodo ao menos algumas vezes em suas carreiras de desenvolvimento.</p><p>Bem, &nbsp;agora não precisa mais sofrer. É hora de aprender uma ferramenta interessante que diminui muito esse fardo. Não, não é o Bootstrap – o nome dela é Tailwind CSS.</p><p>Embora o Tailwind já exista há algum tempo, talvez você ainda não o tenha encontrado. Talvez você simplesmente não tenha ouvido falar sobre ele, ou não sabe se aprender uma nova tecnologia relacionada ao CSS realmente facilitará sua vida.</p><p>De fato, existem muitas maneiras de escrever CSS – como CSS3 puro, LESS, SCSS, Bootstrap, styled-components, Windi CSS e mais. Uma lista e tanto, não é?</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/spongebob-long-list.gif" class="kg-image" alt="spongebob-long-list" width="120" height="90" loading="lazy"></figure><p>Espero que este pequeno guia o ajude a entender o Tailwind CSS e seus benefícios para que você possa dizer: "É isso. É esse".</p><p>Bem, chega de bate-papo. Vamos mergulhar direto no Tailwind.</p><h2 id="o-que-atomic-css"><strong>O que é<strong> Atomic CSS?</strong></strong></h2><p>Antes de entrar no Tailwind CSS, vamos entender o que é Atomic CSS. De acordo com o <a href="https://css-tricks.com/">CSS Tricks</a> (site em inglês):</p><blockquote><em><em>"</em></em>Atomic CSS é a abordagem da arquitetura CSS que favorece classes pequenas e de propósito único com nomes baseados na função visual.<em><em>"</em></em></blockquote><p>É como criar classes que supostamente têm um único propósito. Por exemplo, vamos fazer uma classe <code>bg-blue</code> com o seguinte CSS:</p><pre><code class="language-css">.bg-blue {
  background-color: rgb(81, 191, 255);
}

</code></pre><p>Agora, se adicionarmos essa classe a uma tag <code>&lt;h1&gt;</code>, ela terá um fundo azul com a cor <code>rgb(81, 191, 255)</code>, como você pode ver no código acima.</p><p>Aqui está o HTML:</p><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="UTF-8" /&gt;
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;link rel="stylesheet" href="style.css" /&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div&gt;&lt;h1 class="bg-blue"&gt;Hello world!&lt;/h1&gt;&lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre><p>Este HTML resultará em algo assim:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/img2-1.png" class="kg-image" alt="img2-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/img2-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/img2-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/img2-1.png 1309w" sizes="(min-width: 720px) 720px" width="1309" height="238" loading="lazy"></figure><p>Agora, imagine escrever <strong>regras CSS de propósito único,</strong> tão úteis, e mantê-las em um <strong>arquivo CSS global</strong>. Eu sei que é um investimento de tempo, mas pense nisso – você poderá usar essas classes auxiliares de propósito único em qualquer lugar que desejar.</p><p>Você só precisa do seu arquivo HTML para consumir esse arquivo CSS global e pronto. Você também poderá usar combinações dessas classes auxiliares em uma única tag HTML.</p><p>Vamos ver outro exemplo?</p><p>Vamos criar um arquivo CSS com as seguintes regras:</p><pre><code class="language-css">.bg-blue {
  background-color: rgb(81, 191, 255);
}
.bg-green {
  background-color: rgb(81, 255, 90);
}
.text-underline {
  text-decoration: underline;
}
.text-center {
  text-align: center;
}
.font-weight-400 {
  font-weight: 400;
}
</code></pre><p>e, em seguida, consumi-lo em nosso arquivo HTML da seguinte forma:</p><pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
  &lt;head&gt;
    &lt;meta charset="UTF-8" /&gt;
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge" /&gt;
    &lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;link rel="stylesheet" href="style.css" /&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div&gt;&lt;h1 class="bg-blue"&gt;Hello world 1&lt;/h1&gt;&lt;/div&gt;
    &lt;div&gt;&lt;h1 class="text-underline"&gt;Hello world 2&lt;/h1&gt;&lt;/div&gt;
    &lt;div class="text-center"&gt;
      &lt;h1 class="bg-green font-weight-400 text-underline"&gt;Hello world 3&lt;/h1&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre><p>Isso gerará o seguinte resultado:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/img3-1.png" class="kg-image" alt="img3-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/img3-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/img3-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/img3-1.png 1289w" sizes="(min-width: 720px) 720px" width="1289" height="313" loading="lazy"></figure><h3 id="-pontos-a-observar-aqui-"><strong><strong>🗒️ </strong></strong>Pontos a observar aqui<strong><strong>:</strong></strong></h3><ul><li><strong>Combinação de várias classes auxiliares</strong>: veja como combinei várias classes auxiliares na linha 14 da tag <code>&lt;h1&gt;</code> , nomeadas <code>bg-green</code>, <code>font-weight-400</code> e <code>text-underline</code>. Todas foram aplicadas no meu texto <strong><strong>Hello world 3</strong></strong>.</li><li><strong>Reutilização de classes auxiliares: </strong>no exemplo acima, veja como a classe auxiliar <code>text-underline</code> é usada várias vezes nas linhas 12 e 14.</li></ul><p>Veja como conseguimos adicionar estilos diferentes sem sair da página HTML. Bem, você pode dizer: "Ei, nós tivemos que escrever essas classes auxiliares ou utilitárias no arquivo CSS global... e quanto a isso?" Bem, eu entendo. Esse definitivamente foi o investimento inicial de tempo que tivemos que fazer para começar.</p><p>Claro, quem sabe quantas dessas classes auxiliares ou utilitárias de propósito único teríamos que fazer se quiséssemos seguir essa arquitetura Atomic CSS.</p><p>É aí que entra o Tailwind CSS. O conceito de Atomic CSS não é novo, mas o Tailwind CSS o leva a outro nível.</p><h2 id="tailwind-css-um-framework-css-visando-a-utilidade"><strong><strong>Tailwind CSS – </strong></strong>um framework CSS visando a utilidade</h2><p>O Tailwind CSS, segundo o próprio <a href="https://tailwindcss.com/">site da web</a> é um "framework CSS visando a utilidade", que fornece várias dessas classes utilitárias, <strong>opinativas e de propósito único</strong>,<strong> </strong>que<strong> </strong>você pode usar diretamente dentro de sua marcação de texto para projetar um elemento.</p><p>Algumas das classes utilitárias que uso frequentemente hoje em dia são:</p><ul><li><strong><strong>flex</strong></strong>: usado para aplicar o Flexbox a uma <code>&lt;div&gt;</code></li><li><strong><strong>items-center</strong></strong>: para aplicar as propriedades do CSS &nbsp;<code>align-items: center;</code> a uma <code>&lt;div&gt;</code></li><li><strong><strong>rounded-full</strong></strong>: para fazer uma imagem circular, e assim por diante.</li></ul><p>Sério, não é possível listar todas elas porque existem muitas dessas classes de utilitários. A melhor parte, contudo, é que não precisamos escrever essas classes utilitárias e mantê-las em qualquer arquivo CSS global. Nós as pegamos diretamente do Tailwind.</p><p>Você pode obter uma lista de todas as classes utilitárias que o Tailwind tem a oferecer na <a href="https://tailwindcss.com/docs/installation">página de documentação</a>. Além disso, se você estiver trabalhando no VS Code, poderá instalar uma extensão chamada <a href="https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss">Tailwind CSS IntelliSense</a>, que dará sugestões automáticas, enquanto você continua digitando as classes utilitárias, conforme mostrado na imagem abaixo.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/img4-1.png" class="kg-image" alt="img4-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/img4-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/img4-1.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/img4-1.png 1044w" sizes="(min-width: 720px) 720px" width="1044" height="324" loading="lazy"></figure><h3 id="como-configurar-o-tailwind-css">Como configurar o Tailwind CSS<strong><strong> </strong></strong></h3><p>Existem várias maneiras de configurar o Tailwind CSS em seu projeto, todas mencionadas na <a href="https://tailwindcss.com/docs/installation">documentação</a>.</p><p>O Tailwind CSS funciona sem problemas com uma infinidade de estruturas como Next, React, Angular e muito mais – e até mesmo no HTML OG(Open Graph).</p><p>Para a demonstração prática abaixo, estou usando <strong>Tailwind CSS com uma aplicação do Next</strong>. Para configurar uma aplicação do Next com o Tailwind CSS diretamente, use o seguinte comando:</p><p>Com o <code>npx</code>:</p><pre><code class="language-shell">npx create-next-app --example with-tailwindcss with-tailwindcss-app
</code></pre><p>ou com o <code>yarn</code>:</p><pre><code class="language-shell">yarn create next-app --example with-tailwindcss with-tailwindcss-app
</code></pre><p>Uma vez que o projeto foi configurado, você pode começar a próxima etapa para criar um componente básico de cartão.</p><h3 id="m-os-obra">Mãos <strong>à obra</strong></h3><p>Vamos construir um componente de cartão em um projeto do Next.</p><pre><code class="language-jsx">// Arquivo Card.js
// a ser renderizado no index.js

import React from "react";

const Card = () =&gt; {
  return (
    &lt;div className="relative w-96 m-3 cursor-pointer border-2 shadow-lg rounded-xl items-center"&gt;
      {/* Imagem */}
      &lt;div className="flex h-28 bg-blue-700 rounded-xl items-center justify-center"&gt;
        &lt;h1 className="absolute mx-auto text-center right text-2xl text-white"&gt;
          Image goes here
        &lt;/h1&gt;
      &lt;/div&gt;

      {/* Descrição */}
      &lt;div className="p-2 border-b-2"&gt;
        &lt;h6&gt;
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis
          beatae nulla, atque et sunt ad voluptatum quidem impedit numquam quia?
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Facilis
          beatae nulla, atque et sunt ad voluptatum quidem impedit numquam quia?
        &lt;/h6&gt;
      &lt;/div&gt;

      {/* Stack de tecnologias utilizada */}
      &lt;div className="flex flex-wrap items-center m-2"&gt;
        &lt;span className=" border border-blue-300 rounded-2xl px-2 my-1 mx-1"&gt;
          #React
        &lt;/span&gt;
        &lt;span className=" border border-blue-300 rounded-2xl px-2 my-1 mx-1"&gt;
          #Redux
        &lt;/span&gt;
        &lt;span className=" border border-blue-300 rounded-2xl px-2 my-1 mx-1"&gt;
          #Javascript
        &lt;/span&gt;
      &lt;/div&gt;

      {/* Links */}
      &lt;div className="flex flex-wrap items-center rounded-b-xl border-t-2 bg-white"&gt;
        &lt;button className="border rounded-2xl bg-blue-600 text-white shadow-sm p-1 px-2 m-2"&gt;
          Go to Project
        &lt;/button&gt;
        &lt;button className="border-2 border-blue-600 rounded-2xl text-blue-600 shadow-sm p-1 px-2 m-2"&gt;
          Github
        &lt;/button&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  );
};

export default Card;
</code></pre><p>Isso resulta no cartão a seguir, que é renderizado na interface do usuário:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/img5-1.png" class="kg-image" alt="img5-1" width="519" height="517" loading="lazy"></figure><p>Veja com que facilidade consigo estilizar o componente de cartão sem sair do arquivo Card.js. Não há a necessidade de escrever nenhum arquivo CSS extra.</p><p>Usando <code>flex</code> com a <code>&lt;div&gt;</code>, aplique a ela a regra de CSS <code>display: flex;</code>. Quer adicionar <code>position: relative;</code> em uma <code>&lt;div&gt;</code>? Adicione apenas &nbsp;<code>relative</code> na &nbsp;<code>className</code> e pronto.</p><p>Também podemos adicionar diferentes modificadores como <code>hover</code>, <code>active</code>, <code>focus</code> e assim por diante para renderizar condicionalmente classes utilitárias. É possível aplicar regras de CSS complexas como esta:</p><pre><code class="language-css">.some-class-name {
          --tw-space-x-reverse: 0;
          margin-right: calc(0.5rem * var(--tw-space-x-reverse));
          margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
}
</code></pre><p>Basta mencionar <code>space-x-2</code> na tag <code>&lt;div&gt;</code>. Legal, não é?</p><p>Temos que mencionar esses estilos explicitamente em algum tipo de arquivo CSS global? Absolutamente, não! O Tailwind faz isso automaticamente por nós. Essa é a beleza do Tailwind.</p><p>Ainda não terminamos... há muitas outras vantagens. Vamos vê-las agora.</p><h3 id="vantagens-do-tailwind-css">Vantagens do Tailwind CSS</h3><h4 id="o-modo-just-in-time-jit-fornece-tempos-de-constru-o-extremamente-r-pidos"><strong>O modo <strong>Just-In-Time (JIT) </strong></strong>fornece tempos de construção extremamente rápidos</h4><p>Antes do Tailwind v3, ele limpava todos os estilos para remover quaisquer estilos não utilizados, para que a compilação de produção permanecesse a menor possível.</p><p>De acordo com o Tailwind, a construção de produção costumava ficar entre 5 e 10 kB. Essa, porém, é a história <em>em produção</em>. Em um ambiente de desenvolvimento, o CSS pode ficar muito grande, especialmente se usarmos muitas configurações personalizadas.</p><p>Com a v3 e depois dela, o Tailwind lançou um novo recurso chamado <strong>compilador Just-in-Time.</strong> O compilador JIT evita compilar todo o CSS antecipadamente e compila apenas o CSS como e quando precisamos dele.</p><p>Isso resulta em tempos de construção extremamente rápidos em todos os ambientes. E como os estilos são gerados conforme precisamos deles, não há necessidade de limpar os estilos não utilizados. Isso significa que o CSS em todos os ambientes será o mesmo. Isso nos ajuda a nos livrar do medo de que qualquer CSS importante seja eliminado na produção.</p><figure class="kg-card kg-embed-card" data-test-label="fitted">
        <div class="fluid-width-video-container">
          <div style="padding-top: 56.17977528089888%;" class="fluid-width-video-wrapper">
            <iframe width="356" height="200" src="https://www.youtube.com/embed/3O_3X7InOw8?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" title="Just-In-Time: The Next Generation of Tailwind CSS" name="fitvid0"></iframe>
          </div>
        </div>
      </figure><h4 id="-opinativo-e-flex-vel-ao-mesmo-tempo">É opinativo e flexível ao mesmo tempo</h4><p>O Tailwind CSS é opinativo. Ele especifica algumas restrições quando se trata de estilo e, se você me perguntar, se isso é bom, eu diria que sim, pois nos ajuda a manter a parte do design para aqueles que realmente a entendem.</p><p>Basta olhar para uma das classes utilitárias para adicionar um <code>box-shadow</code> na sua &nbsp;<code>&lt;div&gt;</code> (<a href="https://www.freecodecamp.org/news/what-is-tailwind-css-a-beginners-guide/tailwindcss.com/docs/box-shadow">fonte</a>):</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/img6-1.png" class="kg-image" alt="img6-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/img6-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/img6-1.png 654w" width="654" height="338" loading="lazy"></figure><p>Como você pode ver, existem apenas 8 variantes de sombra que o Tailwind fornece. Existem valores predefinidos para deslocamento vertical e horizontal, desfoque, propagação, cor e opacidade. É por isso que o Tailwind é opinativo.</p><p>Ele tenta dar uma opinião sobre quais valores de propriedade escolher em quase todas as propriedades de estilo existentes. Acredite: na maioria dos casos, essas 8 variantes (para <code>box-shadow</code>) serão mais do que suficiente para criar uma ótima interface de usuário.</p><p>Por exemplo, no exemplo prático acima, usei <code>shadow-lg</code> na <code>&lt;div&gt;</code> pai principal, para obter aquela bela sombra de caixa externa.</p><p>Usar a mesma variante de uma classe de utilitário específica em diferentes áreas da interface do usuário também garante a uniformidade em toda a aplicação e resulta em uma melhor experiência do usuário.</p><p>Caso, no entanto, você precise de algum valor realmente personalizado para qualquer estilo em particular, pode obter isso adicionando um tema personalizado no <code>tailwind.config.js</code>. Por exemplo, para ter um <code>shadow-3xl</code> (o Tailwind não fornece <code>shadow-3xl</code> para usar diretamente), você pode adicionar as seguintes linhas no <code>module.exports</code> no <code>tailwind.config.js</code>:</p><pre><code class="language-js">module.exports = {
  theme: {
    extend: {
      boxShadow: {
        '3xl': '0 35px 60px -15px rgba(0, 0, 0, 0.3)',
      }
    }
  }
}
</code></pre><p>Agora, com o advento do JIT, você também pode usar um valor arbitrário entre colchetes <code>[]</code>, como mostrado abaixo:</p><pre><code class="language-jsx">&lt;div class="shadow-[0_35px_60px_-15px_rgba(0,0,0,0.3)]"&gt;
  // O resto do código vai aqui
&lt;/div&gt;
</code></pre><p>O uso de valores arbitrários pode ser útil quando você precisar de um estilo específico em apenas alguns lugares. Neste caso, criar um tema para ele no <code>tailwind.config.js</code> pode parecer desnecessário.</p><h3 id="minhas-considera-es">Minhas considerações</h3><p>Eu realmente espero ter conseguido fazer você entender o que é o Tailwind CSS e o que você pode fazer com ele.</p><p>O Tailwind é um framework do CSS que nos fornece <strong>classes utilitárias de propósito único</strong> que são, em sua maioria, <strong>opinativas</strong> e que nos ajudam a projetar nossas páginas da web diretamente de dentro de nossos arquivos de marcação ou .js/.jsx/.ts/.tsx.</p><p>Na minha opinião, o Tailwind é simples e fácil de entender. É verdade que pode levar algum tempo para pegar o jeito de todos os nomes de classes de utilitários, mas não se preocupe – você pode consultar a documentação sempre que ficar travado.</p><p>Para todos os iniciantes, que estão recém começando em sua jornada com o desenvolvimento para a web, é muito importante saber o que é o CSS3, antes mesmo de explorar o Tailwind (ou qualquer outro framework do CSS, como &nbsp;o Bootstrap, o Windi CSS e outros) .</p><h2 id="conclus-o"><strong>Conclusão</strong></h2><p>Obrigado pela leitura! Eu realmente espero que você tenha gostado de ler sobre o Tailwind CSS neste artigo e que o tenha achado útil.</p><p>Considere compartilhá-lo com seus amigos. Eu ficarei muito grato, de verdade. Siga o autor no <a href="https://www.linkedin.com/feed/">LinkedIn</a> e no <a href="https://twitter.com/_sohamderoy">Twitter</a> e fique ligado para ver mais conteúdos incríveis. Paz!</p><p><strong>Links</strong></p><ul><li><a href="https://www.sohamderoy.dev/">Site da web do autor</a> (em inglês)</li><li><a href="https://blogs.sohamderoy.dev/">Outros textos do autor</a> (em inglês)</li></ul> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Tutorial de Git e GitHub – controle de versão para iniciantes ]]>
                </title>
                <description>
                    <![CDATA[ Git e GitHub são duas tecnologias que todo desenvolvedor deve aprender, independentemente de sua área. Se você é um desenvolvedor iniciante, pode pensar que esses dois termos significam a mesma coisa, mas são diferentes. Este tutorial ajudará você a entender o que é Git e controle de versão, os comandos ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/tutorial-de-git-e-github-controle-de-versao-para-iniciantes/</link>
                <guid isPermaLink="false">6318e4ab281b1606c8fcd31e</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paula Flávia Pagotto Simionato ]]>
                </dc:creator>
                <pubDate>Wed, 28 Sep 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/g1117.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/git-and-github-for-beginners/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Git and GitHub Tutorial – Version Control for Beginners</a>
      </p><p>Git e GitHub são duas tecnologias que todo desenvolvedor deve aprender, independentemente de sua área.</p><p>Se você é um desenvolvedor iniciante, pode pensar que esses dois termos significam a mesma coisa, mas são diferentes.</p><p>Este tutorial ajudará você a entender o que é Git e controle de versão, os comandos básicos do Git que você precisa conhecer, como você pode usar seus recursos para aumentar a eficiência do seu trabalho e como estender esses recursos usando o GitHub.</p><p>Este guia é voltado a iniciantes, pois os exemplos serão muito fáceis de entender. Também será um tutorial generalizado para que qualquer pessoa possa acompanhar, não importa qual seja sua linguagem de programação favorita.</p><p>Para nosso projeto, faremos uma lista de tarefas escrita em um arquivo de texto (txt). Você verá como podemos usar os recursos do Git para trabalhar e criar uma versão final da lista.</p><h3 id="pr-requisitos"><strong><strong>Pr</strong>é-<strong>requisit</strong>o<strong>s</strong></strong></h3><p>Para concluir este tutorial, você precisará do seguinte:</p><ul><li>Uma interface de linha de comando, um terminal.</li><li>Um editor de texto de sua escolha (usarei o VS Code). </li><li>Uma conta no GitHub. </li></ul><h2 id="o-que-git"><strong>O que é <strong>Git?</strong></strong></h2><p>O Git é um sistema de controle de versão que permite rastrear as alterações feitas em seus arquivos ao longo do tempo. Com o Git, você pode reverter para vários estados de seus arquivos (como se usasse uma máquina do tempo). Você também pode fazer uma cópia do arquivo, fazer alterações nessa cópia e mesclar essas alterações na versão original.</p><p>Por exemplo, você pode estar trabalhando na página de destino de um site e descobrir que não gosta da barra de navegação. Ao mesmo tempo, você pode ficar apreensivo em começar a alterar seus componentes, porque o resultado pode ser pior.</p><p>Com o Git, você pode criar uma cópia idêntica desse arquivo e mexer na barra de navegação. Então, quando estiver satisfeito com suas alterações, poderá mesclar a cópia ao arquivo original.</p><p>Você não está limitado a usar o Git apenas para arquivos de código-fonte – você também pode usá-lo para acompanhar arquivos de texto ou até imagens. Isso significa que o Git não é apenas para desenvolvedores – qualquer um pode achá-lo útil.</p><h3 id="como-instalar-o-git"><strong>Como instalar o<strong> Git</strong></strong></h3><p>Para usar o Git, você precisa instalá-lo em seu computador. Para fazer isso, você pode baixar a versão mais recente no <a href="https://git-scm.com/downloads">site da web oficial</a>. Você pode fazer o download para o seu sistema operacional a partir das opções fornecidas.</p><p>Você também pode instalar o Git usando a linha de comando, mas, como os comandos variam de acordo com cada sistema operacional, vamos nos concentrar na abordagem mais geral.</p><h3 id="como-configurar-o-git"><strong>Como<strong> configur</strong>ar<strong> </strong>o <strong>Git</strong></strong></h3><p>Vou assumir que, neste ponto, você já instalou o Git. Para verificar isso, você pode executar este comando no terminal: <code>git --version</code>. Ele mostra a versão atual instalada no seu PC.</p><p>A próxima coisa que você precisa fazer é definir seu nome de usuário e endereço de e-mail. O Git usará essas informações para identificar quem fez alterações específicas nos arquivos.</p><p>Para definir seu nome de usuário, digite e execute estes comandos: <code>git config --global user.name "SEU_NOME_DE_USUARIO"</code> e <code>git config --global user.email "SEU_E-MAIL"</code>. Apenas certifique-se de substituir <code>"SEU_NOME_DE_USUARIO"</code> e <code>"SEU_E-MAIL"</code> pelos valores que você escolher — ou seja, seu nome de usuário e seu e-mail reais. </p><h2 id="como-criar-e-inicializar-um-projeto-no-git">Como criar e inicializar um projeto no <strong><strong>Git</strong></strong></h2><p>Após terminarmos de instalar e configurar o Git, agora é hora de criar nosso projeto.</p><p>Eu criei uma pasta, no meu desktop, chamada <code>Git and GitHub tutorial</code>. Usando a linha de comando, navegue até o local do seu novo projeto. Para mim, eu executaria os seguintes comandos:</p><p><code>cd desktop</code></p><p><code>cd Git and GitHub tutorial</code></p><p>Se você conhece a linha de comando há pouco e ainda está aprendendo a usá-la para navegar pelo seu PC, sugiro usar o Visual Studio Code da Microsoft. É um editor de código que possui um terminal embutido para executar comandos. Você pode baixá-lo <a href="https://code.visualstudio.com/download">aqui</a>.</p><p>Depois de instalar o VS Code, abra seu projeto no editor e abra um novo terminal para seu projeto. Isso apontará automaticamente o terminal/linha de comando para o caminho do seu projeto.</p><p>Agora, para inicializar um repositório do seu projeto, basta executar <code>git init</code>. Isso dirá ao Git para começar a observar seus arquivos a cada alteração que ocorrer. Esta é a aparência na linha de comando/terminal:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot--95-.png" class="kg-image" alt="Screenshot--95-" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screenshot--95-.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot--95-.png 682w" width="682" height="84" loading="lazy"><figcaption>git init</figcaption></figure><p>A primeira linha tem informações sobre meu PC e o caminho para a pasta. A segunda linha é o comando <code>git init</code> e a terceira linha é a resposta enviada de volta me dizendo que meu repositório (ou <em>repo</em>) foi inicializado. Ele é considerado vazio porque não informamos ao Git quais arquivos rastrear.</p><p>Um repositório é apenas outra maneira de definir um projeto que está sendo monitorado/rastreado pelo Git.</p><h3 id="arquivos-de-projeto-no-git">Arquivos de projeto no Git</h3><p>Eu criei apenas um arquivo chamado <code>todo.txt</code>. Essa é a aparência do arquivo:</p><pre><code class="language-txt">MINHA LISTA DE TAREFAS

1. Escrever um artigo.
2. Programar.
3. Estudar pelos livros.
4. Chegar nas aulas a tempo.
5. Visitar minha tia.
6. Me candidatar a trabalhos remotos. </code></pre><p>Antes de continuarmos aprendendo outros comandos do Git, vamos falar sobre o GitHub.</p><h2 id="o-que-o-github"><strong>O que é<strong> </strong>o <strong>GitHub?</strong></strong></h2><p>O GitHub é um serviço de hospedagem on-line para repositórios do Git. Imagine trabalhar em um projeto em casa e, enquanto estiver fora – talvez na casa de um amigo, de repente – se dar conta da solução para um erro de código que o deixou inquieto por dias.</p><p>Você não pode fazer essas alterações porque seu PC não está com você. Se, contudo, você tiver seu projeto hospedado no GitHub, poderá acessar e baixar esse projeto com um comando em qualquer computador ao qual tenha acesso. Em seguida, você pode fazer suas alterações e enviar a versão mais recente de volta ao GitHub.</p><p>Em resumo, o GitHub permite que você armazene seu repositório em sua plataforma. Outro recurso incrível que vem com o GitHub é a capacidade de colaborar com outros desenvolvedores de qualquer local.</p><p>Agora que criamos e inicializamos nosso projeto localmente, vamos enviá-lo para o GitHub.</p><p>Se você é iniciante, encontrará alguns termos novos como <em>push</em>, <em>commit</em>, <em>add </em>e assim por diante – mas não se deixe assustar com eles. Com alguma prática, você será capaz de lembrar desses termos e do que eles fazem.</p><h2 id="como-enviar-um-reposit-rio-para-o-github">Como enviar um repositório para o GitHub</h2><p>Vou dividir esta seção em etapas para ajudá-lo a entender o processo com mais clareza.</p><h3 id="passo-1-crie-uma-conta-no-github"><strong>Passo<strong> 1 – Cr</strong>i<strong>e </strong>um<strong>a</strong> conta no<strong> GitHub</strong></strong></h3><p>Para poder usar o GitHub, terá de criar uma conta primeiramente. Você pode fazer isso no <a href="https://github.com/">site da web</a> do GitHub.</p><h3 id="passo-2-crie-um-reposit-rio"><strong>Passo<strong> 2 – Cr</strong>i<strong>e </strong>um<strong> repositó</strong>rio</strong></h3><p>Você pode clicar no símbolo <code>+</code> no canto superior direito da página e escolher "<em>New repository</em>" (Novo repositório). Dê um nome ao seu repositório, role para baixo e clique no botão "<em>Create repository</em>" (Criar repositório).</p><h3 id="passo-3-adicionar-e-confirmar-arquivos"><strong>Passo <strong>3 – </strong></strong>Adicionar e confirmar arquivos</h3><p>Antes de "adicionar" e "confirmar" nossos arquivos, você precisa entender os estágios de um arquivo que está sendo rastreado pelo Git.</p><h4 id="estado-confirmado-committed-"><strong>Estado confirmado (committed)</strong></h4><p>Um arquivo está no estado <strong>confirmado </strong>quando todas as alterações feitas no arquivo foram salvas no repositório local. Os arquivos no estágio confirmado são arquivos prontos para serem enviados para o repositório remoto (no GitHub).</p><h4 id="estado-modificado-modified-"><strong>Estado m<strong>odifi</strong>cado (modified)</strong></h4><p>Um arquivo no estado <strong>modificado</strong> tem algumas alterações feitas nele, mas ainda não foi salvo. Isso significa que o estado do arquivo foi alterado de seu estado anterior no estado confirmado.</p><h4 id="estado-preparado-staged-"><strong>Estado preparado (staged)</strong></h4><p>Um arquivo no estado <strong>preparado </strong>significa que está pronto para ser confirmado. Nesse estado, todas as alterações necessárias foram feitas. Portanto, o próximo passo é mover o arquivo para o estado de confirmação.</p><p>Você pode entender isso melhor imaginando o Git como uma câmera. A câmera só tirará um instantâneo quando o arquivo atingir o estado de confirmação. Após este estado, a câmera começa a comparar as alterações feitas no mesmo arquivo com o último instantâneo (este é o estado modificado). Quando as alterações necessárias forem feitas, o arquivo é preparado e movido para o estado de confirmação para um novo instantâneo.</p><p>Isso pode ser muita informação para absorver no momento, mas não desanime – fica mais fácil com a prática.</p><h3 id="como-adicionar-arquivos-ao-git"><strong>Como adicionar arquivos ao<strong> Git</strong></strong></h3><p>Quando inicializamos nosso projeto, o arquivo não estava sendo rastreado pelo Git. Para isso, usamos o comando <code>git add .</code> O ponto que vem depois de <code>add</code> representa todos os arquivos que existem no repositório. Se você quiser adicionar um arquivo específico (por exemplo, um arquivo chamado <code>about.txt</code>), use <code>git add about.txt</code>.</p><p>Agora, nosso arquivo está no estado preparado. Você não receberá uma resposta após este comando, mas, para saber em que estado seu arquivo está, você pode executar o comando <code>git status</code>. </p><h3 id="como-confirmar-commit-arquivos-no-git"><strong>Como confirmar (<strong>commit</strong>) arquivos no<strong> Git</strong></strong></h3><p>O próximo estado de um arquivo após o estado preparado é o estado confirmado. Para confirmar nosso arquivo, usamos o comando <code>git commit -m "first commit"</code> </p><p>A primeira parte do comando <code>git commit</code> diz ao Git que todos os arquivos preparados estão prontos para serem confirmados. Então, é hora de tirar um instantâneo. A segunda parte, <code>-m "first commit"</code>, é a mensagem de confirmação. <code>-m</code> é uma abreviação de mensagem enquanto o texto entre aspas é a mensagem de confirmação (que pode ser a mensagem que você quiser e no idioma que quiser).</p><p>Depois de executar este comando, você deve obter uma resposta semelhante a esta:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot--97-.png" class="kg-image" alt="Screenshot--97-" width="586" height="107" loading="lazy"><figcaption>git commit</figcaption></figure><p>Agora, nosso arquivo está no estado confirmado.</p><h3 id="passo-4-envie-o-reposit-rio-para-o-github"><strong>Passo<strong> 4 – </strong></strong>Envie o repositório para o<strong><strong> GitHub</strong></strong></h3><p>Depois de criar o repositório, você deve ser redirecionado para uma página que informa como criar um repositório localmente ou enviar um já existente.</p><p>No nosso caso, o projeto já existe localmente, então usaremos comandos na seção "… ou enviar um repositório existente a partir da linha de comando". Estes são os comandos:</p><pre><code>git remote add origin https://github.com/ihechikara/git-and-github-tutorial.git
git branch -M main
git push -u origin main</code></pre><p>O primeiro comando, <code>git remote add origin <a href="https://github.com/ihechikara/git-and-github-tutorial.git">https://github.com/ihechikara/git-and-github-tutorial.git</a></code>, cria uma conexão entre seu repositório local e o repositório remoto no GitHub.</p><p>O URL do seu projeto remoto deve ser totalmente diferente do anterior. Portanto, para acompanhar, certifique-se de seguir as etapas e trabalhar com seu próprio repositório remoto. Normalmente, você não receberá uma resposta após executar este comando, mas certifique-se de ter uma conexão com a internet.</p><p>O segundo comando, <code>git branch -M main</code>, altera o nome do seu branch principal para "main". O branch padrão pode ser criada como "master", mas "main" é o nome padrão para este repositório agora. Geralmente, não há resposta aqui.</p><p>O último comando, <code>git push -u origin main</code>, envia seu repositório do seu dispositivo local para o GitHub. Você deve obter uma resposta semelhante a esta:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot--102-.png" class="kg-image" alt="Screenshot--102-" width="551" height="195" loading="lazy"><figcaption>git push</figcaption></figure><p>Para ajudá-lo a aprofundar sua compreensão dos estágios do arquivo, farei alterações no arquivo e, em seguida, enviarei a nova versão para o GitHub.</p><p>Lembre-se de que nosso arquivo agora está no estado confirmado. Vamos fazer alterações no arquivo e anotar os estados.</p><p>Vou adicionar uma nova tarefa à lista de tarefas:</p><pre><code>MINHA LISTA DE TAREFAS

1. Escrever um artigo.
2. Programar.
3. Estudar pelos livros.
4. Chegar nas aulas a tempo.
5. Visitar minha tia.
6. Me candidatar a trabalhos remotos. 
7. Praticar programação</code></pre><p>Depois de adicionar a nova tarefa, execute o comando <code>git status</code>. Isto é o que você deverá ver:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot--98-.png" class="kg-image" alt="Screenshot--98-" width="551" height="217" loading="lazy"><figcaption>git status</figcaption></figure><p>Depois de fazer alterações no arquivo, ele foi movido para o estado modificado, mas ainda não está preparado para confirmação. Então, você ainda não pode enviá-lo para o GitHub. O Git não tirou um instantâneo final desse estado atual, pois está apenas comparando as alterações que fizemos agora com o último instantâneo.</p><p>Agora vamos adicionar (preparar) este arquivo e, em seguida, confirmá-lo e enviá-lo. Isto é igual ao que fizemos na última seção.</p><p>Primeiro, adicionamos o arquivo usando <code>git add .</code>, que adiciona todos os arquivos na pasta (um único arquivo, no nosso caso). Em seguida, confirmamos o arquivo executando <code>git commit -m "added new task"</code> (a mensagem significa "nova tarefa adicionada") seguido de <code>git push -u origin main</code>.</p><p>Essas são as três etapas para enviar seus arquivos modificados para o GitHub. Você adiciona, confirma e, em seguida, envia. Espero que agora você entenda os estágios do arquivo e os comandos associados a eles.</p><h2 id="como-usar-branches-no-git">Como usar branches no <strong><strong>Git</strong></strong></h2><p>Com branches, você pode criar uma cópia de um arquivo no qual gostaria de trabalhar sem estragar a cópia original. Você pode mesclar essas alterações com a cópia original ou apenas deixar o branch permanecer independente.</p><p>Antes de começarmos a usar branches, quero mostrar uma representação visual do nosso repositório, que se parece com isso:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/g638.png" class="kg-image" alt="g638" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/g638.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/g638.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/09/g638.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/g638.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1016" loading="lazy"><figcaption>branch main</figcaption></figure><p>A imagem acima mostra nosso branch principal com os dois últimos commits (o primeiro commit e o commit da nova tarefa adicionada).</p><p>Neste ponto, quero adicionar mais tarefas à lista, mas ainda não tenho certeza se as quero na minha lista principal. Então, vou criar um outro branch chamado &nbsp;<code>test</code> para ver como ficaria minha lista com mais tarefas incluídas.</p><p>Para criar um outro branch, execute este comando: <code>git checkout -b test</code>. Vamos dividir isso em partes e explicar.</p><p><code>checkout</code> diz ao Git que deve mudar para um outro branch. <code>-b</code> diz ao Git para criar esse outro branch. <code>test</code> é o nome do branch a ser criado e alterado. Aqui está a resposta que você deve obter:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot--99-.png" class="kg-image" alt="Screenshot--99-" width="547" height="74" loading="lazy"><figcaption>git checkout -b</figcaption></figure><p>Agora que criamos um outro branch, é assim que nosso repositório ficará:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/g664.png" class="kg-image" alt="g664" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/g664.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/g664.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/09/g664.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/g664.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1014" loading="lazy"><figcaption>git branch</figcaption></figure><p>Criamos o outro branch a partir do estado do nosso último commit. Vamos agora adicionar mais tarefas a esse novo branch.</p><pre><code>MINHA LISTA DE TAREFAS

1. Escrever um artigo.
2. Programar.
3. Estudar pelos livros.
4. Chegar nas aulas a tempo.
5. Visitar minha tia.
6. Me candidatar a trabalhos remotos. 
7. Praticar programação
8. Completar a tarefa de estágio.
9. Praticar aberturas do xadrez.
10. Resolver quebra-cabeças do xadrez.
11. Verificar o cronograma dos testes. </code></pre><p>Eu adicionei quatro novas tarefas. Para mesclar o novo estado com o branch <code>main</code>, você deve primeiro preparar e confirmar esse branch. Não entrarei em detalhes sobre o assunto, pois fizemos isso duas vezes na última seção.</p><p>Você deve tentar fazer isso sozinho para entender como funciona. Como dica, adicione o arquivo e, em seguida, confirme com uma mensagem (consulte a seção anterior para obter detalhes de como fazer isso).</p><p>Depois de confirmar seu branch <code>test</code>, volte para o branch <code>main</code> executando este comando: <code>git checkout main</code>.</p><p>Você notou que não adicionamos o <code>-b</code> ? Isso ocorre porque não estamos criando um outro branch, mas mudando para um branch existente. Você pode verificar todos os branches que existem em seu repositório executando o comando <code>git branch</code> </p><p>Agora, podemos mesclar as alterações que fizemos no branch <code>test</code> no branch <code>main</code> executando <code>git merge test</code>. Neste ponto, você verá todas as alterações feitas no branch <code>test</code> refletidas no branch <code>main</code>. Você também deve receber uma resposta semelhante a esta:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot--100-.png" class="kg-image" alt="Screenshot--100-" width="548" height="122" loading="lazy"><figcaption>git merge</figcaption></figure><p>Aqui está uma representação visual do nosso repositório:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/g816.png" class="kg-image" alt="g816" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/g816.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/g816.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/09/g816.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/g816.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1014" loading="lazy"><figcaption>git merge</figcaption></figure><p>Se você continuar a enviar seu repositório para o GitHub, verá que o branch <code>test</code> não será enviado. Ele permanecerá apenas em seu repositório local. Se você quiser enviar seu branch <code>test</code>, mude para ele usando <code>git checkout test</code> e execute o comando <code>git push -u origin test</code>.</p><h2 id="como-extrair-um-reposit-rio-no-git">Como extrair um repositório no Git</h2><p>Fazer <em>pull </em>no Git significa clonar o estado atual de um repositório remoto em seu computador/repositório. Isso é útil quando você deseja trabalhar em seu repositório de um computador diferente ou quando está contribuindo para um projeto de código aberto on-line.</p><p>Para testar isso, não se preocupe em mudar para um novo computador. Basta executar <code>cd ..</code> para sair do diretório atual e voltar uma etapa. No meu caso, naveguei de volta para a minha área de trabalho.</p><p>Vá para o GitHub e, na página principal do seu repositório, você verá um botão verde que diz "Code". Ao clicar no botão, você deverá ver algumas opções em um menu suspenso. Vá em frente e copie o URL no formato HTTPS.</p><p>Depois disso, execute <code>git clone SEU_URL_DE_HTTPS</code>. Este comando puxa o repositório remoto para seu computador local em uma pasta chamada git-and-git-tutorial. Isto é o que você deverá ver em seu terminal:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot--101-.png" class="kg-image" alt="Screenshot--101-" width="538" height="165" loading="lazy"><figcaption>git clone</figcaption></figure><h2 id="conclus-o"><strong><strong>Conclusã</strong>o</strong></h2><p>Este artigo abordou os comandos básicos que ajudarão você a começar a usar o Git. Também começamos a aprender a usar o GitHub.</p><p>Se você seguiu até este ponto, parabéns. Você está pronto para seguir em frente. Agora, você pode usar o Git em seus projetos, independentemente da linguagem de programação que estiver usando.</p><p>Você deve saber que esses não são todos os comandos que existem no Git – portanto, sinta-se à vontade para fazer mais pesquisas para aprender mais comandos e seus usos. <a href="https://www.freecodecamp.org/news/what-is-git-learn-git-version-control/">Este artigo</a> e <a href="https://www.freecodecamp.org/news/git-cheat-sheet/">esta página de dicas</a> (ambos em inglês) são boas fontes para se começar . <a href="https://gist.github.com/brandon1024/14b5f9fcfd982658d01811ee3045ff1e">Este</a> é um ótimo lugar para ver uma lista detalhada de mais comandos do Git (em inglês).</p><p>Encontre o autor no <a href="https://twitter.com/Ihechikara2">Twitter</a>. Feliz programação!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como se tornar um desenvolvedor de front-end - habilidades para desenvolver para a web ]]>
                </title>
                <description>
                    <![CDATA[ Alguns dos profissionais mais bem pagos do mundo são desenvolvedores de  front-end. Eles usam seus conhecimentos e talentos para criar sites atraentes e fáceis de usar. Os desenvolvedores de front-end não precisam de um diploma ou certificado escolar para trabalhar. Em vez disso, eles devem entender os fundamentos do ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-se-tornar-um-desenvolvedor-de-front-end-habilidades-para-desenvolver-para-a-web/</link>
                <guid isPermaLink="false">6315fb96281b1606c8fccca5</guid>
                
                    <category>
                        <![CDATA[ Desenvolvimento Front-End ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paula Flávia Pagotto Simionato ]]>
                </dc:creator>
                <pubDate>Tue, 27 Sep 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/cover-template--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-become-a-frontend-developer/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Become a Front End Developer – Front End Web Dev Skills</a>
      </p><p>Alguns dos profissionais mais bem pagos do mundo são desenvolvedores de <em>front-end</em>. Eles usam seus conhecimentos e talentos para criar sites atraentes e fáceis de usar.<br>Os desenvolvedores de <em>front-end</em> não precisam de um diploma ou certificado escolar para trabalhar. Em vez disso, eles devem entender os fundamentos do desenvolvimento de <em>front-end</em>, linguagens de programação e <em>frameworks </em>de desenvolvimento de <em>front-end</em>.<br>Neste guia, você aprenderá como se tornar um desenvolvedor de <em>front-end</em>, entendendo primeiramente o que o desenvolvimento de <em>front-end</em> envolve, as habilidades técnicas e sociais necessárias, as linguagens e estruturas disponíveis e algumas etapas para começar.<br>Um desenvolvedor de front-end nos Estados Unidos pode ganhar, em média, US$ 86.178 por ano, de acordo com o <a href="https://www.glassdoor.co.in/Salaries/us-front-end-developer-salary-SRCH_IL.0,2_IN1_KO3,22.htm" rel="noreferrer nofollow noopener">Glassdoor</a>. De acordo com o <a href="https://www.payscale.com/research/US/Job=Front_End_Developer_%2F_Engineer/Salary" rel="noreferrer nofollow noopener">Payscale</a>, um desenvolvedor de front-end "típico" pode ganhar uma renda anual de até US$ 71.350.</p><p>Se você é novo no setor de tecnologia, pode estar confuso sobre o que significa <em>front-end</em>, bem como outros aspectos do desenvolvimento para a web, como <em>back-end</em> e <em>full stack</em>. Então, vamos começar com uma explicação sobre eles.</p><h2 id="o-que-o-front-end"><strong>O que é o front-end<strong>?</strong></strong></h2><p>Todos os sites pelos quais navegamos, os sites de comércio eletrônico nos quais compramos produtos, os blogs que lemos e assim por diante, são tornados fáceis de usar e esteticamente agradáveis pelos desenvolvedores de <em>front-end</em>.</p><p>Existem dois aspectos principais do desenvolvimento para a web a serem considerados ao criar sites e aplicações para a web: o <em>front-end</em> e o <em>back-end</em>.<br>O desenvolvimento de <em>front-end </em>está preocupado com a "fachada" de qualquer aplicação para a web, como o nome indica (em inglês, <em>front-end</em> significa a "parte frontal"). É com ela que o usuário interage e é ela que o usuário vê ao executar operações como clicar em um botão, rolar uma página, preencher um formulário e assim por diante. É a funcionalidade do lado do <em>client</em> de uma aplicação para a web.</p><p>O <em>back-end </em>(em inglês, <em>back-end</em> significa a "parte traseira") refere-se aos eventos que ocorrem nos bastidores, como a infraestrutura, a conexão e a comunicação com o banco de dados e assim por diante. <em>Full stack</em> refere-se a uma combinação de <em>front-end </em>e <em>back-end</em>.</p><h2 id="o-que-faz-um-desenvolvedor-de-front-end">O que faz um desenvolvedor de front-end<strong><strong>?</strong></strong></h2><p>Acabamos de discutir os vários aspectos do desenvolvimento para a web, <em>front-end</em>, <em>back-end</em> e <em>full stack</em>. Para acompanhar isso, também temos diferentes tipos de desenvolvedores com base nos aspectos do desenvolvimento para a web nos quais eles são proficientes. Portanto, temos desenvolvedores de <em>front-end</em>, desenvolvedores de <em>back-end</em> e desenvolvedores <em>full stack</em>.</p><p>Um desenvolvedor de <em>front-end</em> é um profissional responsável por criar a interface do usuário e a experiência do usuário (UI/UX) com a qual os usuários interagem para acessar a aplicação em questão. Eles são solucionadores de problemas que usam linguagens de programação, ferramentas, criatividade e experiência para criar um site ou aplicação que resolva o problema de um usuário e que tenha uma boa aparência.</p><p>Como dito anteriormente, um desenvolvedor de <em>back-end</em> é responsável por tudo relacionado ao <em>back-end</em>, incluindo a lógica, a comunicação com os banco de dados e muito mais.</p><p>Por fim, os desenvolvedores <em>full stack</em> são aqueles que entendem tanto do desenvolvimento de <em>front-end</em> quanto de <em>back-end</em>, permitindo que eles iniciem e terminem um projeto por conta própria.</p><p>Em uma configuração profissional ou empresa padrão, geralmente há um designer de UI/UX que projeta a aparência da interface e o que eles desejam que seja a experiência do usuário.</p><p>Em seguida, eles passarão seu design para os desenvolvedores de <em>front-end</em> e <em>back-end</em>, que agora trabalham na implementação para que a aplicação que eles projetaram funcione na web. O desenvolvedor de <em>front-end</em> recriará o design, escrevendo o programa em HTML, CSS e JavaScript. </p><h2 id="como-tornar-se-um-desenvolvedor-de-front-end"><strong>Como tornar-se um desenvolvedor<strong> </strong>de f<strong>ront-</strong>e<strong>nd </strong></strong></h2><p>Até agora, discutimos o que significa <em>front-end</em> e quem é o desenvolvedor de <em>front-end</em>. Agora, vamos ver alguns dos principais requisitos/habilidades necessários antes que você possa se chamar de desenvolvedor de <em>front-end</em>.</p><p>É importante entender que você não precisa saber tudo antes de trabalhar como desenvolvedor de <em>front-end</em>, mas os fundamentos, como HTML, CSS e JavaScript, são sempre essenciais.</p><h3 id="1-aprenda-html-css-e-javascript"><strong><strong>1. </strong>Aprenda <strong>HTML, CSS</strong> e <strong>JavaScript</strong></strong></h3><p>Quando você olha para um site na web, as três coisas mais importantes que compõem o que você vê na web são o HTML, o CSS e o JavaScript. Portanto, essas são as três primeiras coisas a serem aprendidas como base para se tornar um desenvolvedor de <em>front-end</em>.</p><p>Eles são os blocos de construção para o desenvolvimento para a web e de aplicações. Portanto, você deve aprendê-los se quiser entrar no desenvolvimento para a web. Felizmente, existem vários recursos on-line disponíveis para ajudá-lo a aprender e a praticá-los.</p><h4 id="o-que-html"><strong>O que é<strong> HTML?</strong></strong></h4><p>HTML é a sigla para <em>Hyper Text Markup Language</em> (ou "linguagem de marcação de hipertexto", em português). Ele é o esqueleto de todas as páginas da web e aplicações, seu bloco de construção mais básico. Você usa HTML para estruturar sua página em elementos como parágrafos, seções, títulos, barras de navegação e assim por diante.</p><p>O HTML fornece a estrutura ao conteúdo que aparece em um site, como imagens, texto ou vídeos. Uma página que tenha apenas HTML é muito básica e pouco atraente, e precisará de estilo em CSS para torná-la apresentável.</p><p>O HTML é frequentemente a primeira linguagem que os desenvolvedores aprendem e é essencial para o trabalho de desenvolvimento de <em>front-end</em>. Quer saber mais sobre o HTML? Comece com a <a href="https://www.freecodecamp.org/portuguese/learn/">certificação em design responsivo para a web do freeCodeCamp</a> e <a href="https://www.freecodecamp.org/news/html-crash-course/" rel="noreferrer nofollow noopener">com o novo curso completo sobre HTML do Beau Carnes</a> (texto em inglês).</p><h4 id="o-que-css"><strong>O que é<strong> CSS?</strong></strong></h4><p>CSS é a abreviação de <em>Cascading Style Sheets</em> (ou "folhas de estilo em cascata", em português), e você o usa para melhorar a aparência de uma página da web, adicionando estilos em CSS. Esses estilos tornam seu site mais atraente e agradável de ver e usar para o usuário final.</p><p>Você quer saber mais sobre &nbsp;CSS? Para começar, verifique a <a href="https://www.freecodecamp.org/learn/responsive-web-design/" rel="noreferrer nofollow noopener"></a><a href="https://www.freecodecamp.org/portuguese/learn/">segunda parte da certificação em Design Responsivo para a web do freeCodeCamp</a>.</p><h4 id="o-que-javascript"><strong>O que é<strong> JavaScript?</strong></strong></h4><p>O HTML é uma linguagem de marcação e o CSS são as folhas de estilo. Então, temos o JavaScript, o terceiro bloco de construção. O JavaScript é uma linguagem de programação que permite que você torne suas páginas da web mais interativas. Isso pode incluir animações, estilo dinâmico, efeitos/comportamentos quando os botões são clicados, movimento dos jogos e assim por diante.</p><p>Se você quiser aprender JavaScript, consulte a <a href="https://www.freecodecamp.org/portuguese/learn/">certificação em algoritmos e estruturas de dados em JavaScript do freeCodeCamp</a>. Você também pode complementar seu aprendizado com este excelente curso de <a href="https://www.freecodecamp.org/news/learn-javascript-full-course/" rel="noreferrer nofollow noopener">introdução ao JS</a> (texto em inglês).</p><h3 id="2-pratique-programa-o"><strong><strong>2. </strong></strong>Pratique programação</h3><p>Existe uma expressão &nbsp;popular que diz que "a prática leva à perfeição". Isso significa que você se tornará melhor em alguma coisa se a fizer com frequência.</p><p>Se você quer se tornar um desenvolvedor de <em>front-end</em> profissional, precisa praticar de forma consistente. Isso vai ajudá-lo a aprender os conceitos completamente (e não apenas na superfície). Quanto mais você praticar, mais (e melhor) você entenderá os conceitos.</p><h3 id="3-aprimore-suas-habilidades"><strong><strong>3. </strong></strong>Aprimore suas habilidades</h3><p>"Aprenda constantemente. Sempre há mais uma coisa para aprender!" disse Steve Jobs. Isso vale em todos os aspectos da vida, incluindo programação e desenvolvimento de <em>front-end</em>.</p><p>À medida que novas tecnologias, ferramentas, sintaxe e abordagens são introduzidas, é sempre melhor manter-se atualizado com as novas tendências tecnológicas e evitar ficar para trás.</p><p>Isso ajudará você a aumentar suas habilidades como desenvolvedor de <em>front-end</em>, e você sempre poderá se manter atualizado, participando e interagindo com comunidades ativas de desenvolvedores. Existem muitas comunidades por aí, como a comunidade de desenvolvedores do freeCodeCamp e todas as outras comunidades locais que nos cercam, incluindo a sua.</p><h3 id="4-aprenda-sobre-a-linha-de-comando-e-sobre-controle-de-vers-o"><strong><strong>4.</strong></strong>Aprenda sobre a linha de comando e sobre controle de versão</h3><p>Como desenvolvedor de <em>front-end</em>, você deve entender como a linha de comando funciona, pois ela permite acessar as funções do sistema operacional por meio de uma interface de texto. Muitos profissionais preferem as CLIs ("interfaces de linha de comando", em português) por sua velocidade e desempenho ao instalar bibliotecas e estruturas.</p><p>Desenvolvedores de <em>front-end</em> também devem estar familiarizados com sistemas de controle de versão, como o Git, que é o mais utilizado. Ao programar, você frequentemente desejará rastrear seu histórico de programação e outras informações.</p><p>O controle de versão torna isso muito mais fácil, pois permite que você e sua equipe se comuniquem e gerenciem (rastreiem) com eficiência todas as alterações feitas no código-fonte. Ele também fornece informações como quem fez as alterações e quais alterações foram feitas.</p><h3 id="5-compreenda-as-interfaces-de-programa-o-de-aplicativos-apis-"><strong><strong>5. </strong></strong>Compreenda as interfaces de programação de aplicativos<strong><strong> (APIs)</strong></strong></h3><p>Como desenvolvedor <em>front-end </em>profissional, você deve estar familiarizado com as APIs e com o modo de consumi-las e manipulá-las. Isso é fundamental para a comunicação com lógicas de <em>back-end </em>e bancos de dados.</p><p>Para interagir com APIs em JavaScript, você usará principalmente a <em>API Fetch</em> do navegador ou a biblioteca <em>Axios</em>. Este artigo (texto em inglês) explica <a href="https://www.freecodecamp.org/news/how-to-make-api-calls-with-fetch/" rel="noreferrer nofollow noopener">como usar a API Fetch em JavaScript</a>.</p><h3 id="6-aprenda-e-entenda-as-bibliotecas-do-javascript-e-do-css"><strong><strong>6. </strong></strong>Aprenda e entenda as bibliotecas do JavaScript e do CSS</h3><p>Hoje, existem inúmeras bibliotecas do JavaScript disponíveis, todas com o objetivo de facilitar o desenvolvimento de aplicações da web. Esses são scripts do JavaScript pré-escritos, que facilitam o desenvolvimento de aplicativos baseados em JavaScript.</p><p>Existem muitas delas, mas é melhor escolher uma e aprendê-la completamente, como o React, o Vue ou o Angular (três dos mais populares). Você pode conferir a <a href="https://www.freecodecamp.org/learn/front-end-development-libraries/" rel="noreferrer nofollow noopener"></a><a href="https://freecodecamp.org/portuguese/learn">certificação de bibliotecas de desenvolvimento em front-end do freeCodeCamp</a> para aprender mais.</p><p>Existem também algumas bibliotecas de estilo que simplificam o estilo de suas páginas da web, como o Bootstrap, Sass/Scss, Tailwind e assim por diante.</p><h3 id="7-crie-um-portf-lio-on-line"><strong><strong>7. </strong></strong>Crie um portfólio on-line</h3><p>Construir seu portfólio é uma maneira fácil de demonstrar sua experiência como desenvolvedor de <em>front-end</em>.</p><p>Se você está apenas começando como desenvolvedor de <em>front-end</em>, não precisa que cada parte de seu portfólio seja um projeto de cliente. Você pode assumir o comando e ser inventivo. Faça uso de novas ferramentas e bibliotecas para criar algo espetacular. À medida que sua carreira progride, você poderá apresentar ali mais projetos nos quais trabalhou.</p><p>Você também pode examinar os portfólios de seus colegas desenvolvedores de <em>front-end</em> para ver o que você gosta e o que não gosta. Então, sabendo o que você quer mostrar ao mundo, crie seu próprio site.</p><p><a href="https://www.freecodecamp.org/news/create-a-portfolio-website-using-html-css-javascript/">Aqui está um curso divertido</a> (texto em inglês) que o ajudará a criar seu próprio site de portfólio com HTML, CSS e JavaScript – para que você possa praticar essas habilidades de desenvolvimento para a web.</p><p>Você também pode fazer com que amigos e membros da comunidade critiquem e testem seu site para garantir que tudo fique bem. Não se esqueça de que todas as palavras em seu site devem ajudá-lo a conseguir um ótimo trabalho. Você não quer que seja muito longo ou muito chato.</p><p><a href="https://www.freecodecamp.org/news/level-up-developer-portfolio/">Aqui estão algumas dicas</a> (texto em inglês) que o ajudarão a aumentar o nível do seu portfólio de desenvolvedor para realmente se destacar.</p><h3 id="8-cultive-suas-soft-skills"><strong><strong>8. </strong></strong>Cultive suas soft skills</h3><p>Os desenvolvedores de <em>front-end</em> devem ser<strong> comunicadores</strong> eficazes (na escrita assim como na fala), pois devem interagir tanto com a equipe técnica quanto com o cliente.</p><p>Eles também devem ser excelentes comunicadores em seu código, pois é fundamental reservar um tempo para comentar e escrever a documentação apropriada em seu código para que você e outras pessoas possam entendê-lo facilmente, mesmo depois de muito tempo.</p><p>Os desenvolvedores de front-end também devem ter <strong>boa atenção aos detalhes</strong> e ser meticulosos em todos os aspectos de seu trabalho. Eles devem ter um olhar atento e ser capazes de detectar pequenos erros ou inconsistências ao criar páginas da web.</p><p>Os desenvolvedores de <em>front-end</em> também devem ser<strong> eternos aprendizes</strong>, pois os sites estão evoluindo e as expectativas de capacidade de resposta, acessibilidade e aparência estão sempre mudando. Os engenheiros de <em>front-end</em> devem permanecer o mais atualizados possível e quase certamente precisarão aprender novas linguagens de programação ou bibliotecas com o passar do tempo.</p><h3 id="9-comece-a-se-candidatar-a-est-gios-ou-empregos-que-voc-deseja"><strong><strong>9. </strong></strong>Comece a se candidatar a estágios ou empregos que você deseja</h3><p>Depois de obter o conhecimento adequado em <em>front-end</em>, aprenda as habilidades necessárias e <a href="https://www.freecodecamp.org/news/how-to-write-a-developer-resume-recruiters-will-read/">faça seu currículo</a> (texto em inglês). Agora, você poderá começar a procurar oportunidades de trabalho em <em>front-end</em>.</p><p>Confira seus requisitos para ver em quais outras áreas você precisa melhorar como desenvolvedor de <em>front-end</em>.</p><p>Para concluir, sempre se candidate a empregos e nunca tenha medo de se candidatar. Isso dará a você alguma experiência para ajudá-lo a aprender como as empresas contratam e o que é preciso para ser contratado.</p><h2 id="conclus-o"><strong><strong>Conclusã</strong>o</strong></h2><p>Neste artigo, aprendemos o que é um desenvolvedor de <em>front-end</em> e o que é preciso para se tornar um.</p><p>Também aprendemos que se tornar um desenvolvedor de <em>front-end</em> sem diploma não é apenas possível, mas também alcançável.</p><p>Uma pergunta final que a maioria das pessoas tem é sobre o tempo que leva para se tornar um desenvolvedor de <em>front-end</em>. Bem, o tempo que leva depende inteiramente do seu ritmo de aprendizado e de seu conhecimento prévio.</p><p>Apenas lembre-se de que você não deve comparar a si ou o seu ritmo de aprendizado com o de outros enquanto aprende. Reserve algum tempo a cada semana ou dia para aprender, faça o seu melhor para cumpri-lo e depois aproveite o processo.</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como criar um painel de análise em uma aplicação do Django ]]>
                </title>
                <description>
                    <![CDATA[ Olá, pessoal! Python, visualização de dados e programação são os tópicos aos quais me dedico profundamente. É por isso que gostaria de compartilhar com você minhas ideias, bem como meu entusiasmo por descobrir novas maneiras de apresentar dados de maneira significativa. O caso que vou abordar é bastante comum: você ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-criar-um-painel-de-analise-em-uma-aplicacao-do-django/</link>
                <guid isPermaLink="false">63164117281b1606c8fcce72</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paula Flávia Pagotto Simionato ]]>
                </dc:creator>
                <pubDate>Mon, 26 Sep 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/5f9c9c9e740569d1a4ca3336.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-create-an-analytics-dashboard-in-django-app/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to create an analytics dashboard in a Django app</a>
      </p><p>Olá, pessoal!</p><p><strong>Python, visualização de dados </strong>e<strong> programação </strong>são os tópicos aos quais me dedico profundamente. É por isso que gostaria de compartilhar com você minhas ideias, bem como meu entusiasmo por descobrir novas maneiras de apresentar dados de maneira significativa.</p><p>O caso que vou abordar é bastante comum: você tem dados no back-end da sua aplicação e deseja dar forma a eles no front-end. Se essa situação parece familiar a você, este tutorial pode ser útil.</p><p>Depois de concluí-lo, você terá uma aplicação <strong>desenvolvida com Django</strong>,<strong> </strong>com <strong>tabelas e gráficos dinâmicos interativos</strong>.</p><h2 id="pr-requisitos"><strong><strong>Pr</strong>é-<strong>requisit</strong>o<strong>s</strong></strong></h2><p>Para percorrer as etapas com confiança, você precisa de um conhecimento básico do framework Django e de um pouco de criatividade. ✨</p><p>Para acompanhá-lo, você pode baixar o <a href="https://github.com/veronikaro/django-dashboard-app">exemplo do GitHub</a>.</p><p>Aqui está uma breve lista das ferramentas que vamos usar:</p><ul><li><strong><strong><a href="https://www.python.org/downloads/release/python-374/">Python 3.7.4</a></strong></strong></li><li><strong><strong><a href="https://www.djangoproject.com/?r=fr5">Django</a></strong></strong></li><li><strong><strong><a href="https://virtualenv.pypa.io/en/latest/">Virtualenv</a></strong></strong></li><li><strong><a href="https://www.flexmonster.com/?r=fr5">Tabelas e gráficos dinâmicos do Flexmonster</a> </strong>(biblioteca do JavaScript)</li><li><strong><strong><a href="https://www.sqlite.org/index.html">SQLite</a></strong></strong></li></ul><blockquote><strong>Nota do tradutor:</strong> no momento desta tradução, o Python se encontra em sua versão 3.10.4. As soluções constantes aqui deverão funcionar, mesmo assim.</blockquote><p>Se você já configurou um projeto no Django e se sente confiante sobre o fluxo básico de criação de aplicações, pode ir direto para a seção <strong>Conectando dados ao Flexmonster</strong>, que explica como adicionar componentes de visualização de dados a ele.</p><p>Vamos começar!</p><h2 id="come-ando-com-o-django">Começando com o Django</h2><p><br>Antes de mais nada, vamos conferir se você já instalou o Django em sua máquina. A regra geral é instalá-lo em seu ambiente virtual configurado anteriormente –uma ferramenta poderosa para isolar seus projetos uns dos outros.</p><p>Além disso, verifique se você está ativo em um diretório recém-criado. Abra seu console e inicialize um projeto do Django com este comando:</p><p><code>django-admin startproject analytics_project</code></p><p>Agora, há um novo diretório chamado <code>analytics_project</code>. Vamos verificar se fizemos tudo certo. Vamos para <code>analytics_project</code> e iniciar o servidor com um comando de console:</p><p><code>python manage.py runserver</code></p><p>Abra <a href="http://127.0.0.1:8000/"><code>http://127.0.0.1:8000/</code></a> no seu navegador. Se o que você vê na página é este foguete incrível, é sinal de que está tudo certo:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/DjangoRocket.gif" class="kg-image" alt="DjangoRocket" width="854" height="480" loading="lazy"></figure><p>Em seguida, crie uma aplicação em seu projeto. Vamos chamá-lo de <code>dashboard</code>:</p><p><code>python manage.py startapp dashboard</code></p><blockquote>Aqui vai uma dica: se você não tiver certeza sobre a <a href="https://wsvincent.com/django-projects-vs-apps/">diferença entre o conceito de apps e de projetos em Django</a>, (texto em inglês), dedique um tempo a aprender sobre isso para ter uma visão clara de como os projetos do Django são organizados.</blockquote><p>Lá vamos nós. Agora, vemos um novo diretório dentro do projeto. Ele contém os seguintes arquivos:</p><p><code>__init__.py</code> – para fazer o Python tratá-lo como um pacote</p><p><code>admin.py</code> – configurações para as páginas de administração do Django</p><p><code>apps.py</code> – ajustes para as configurações da aplicação</p><p><code>models.py</code> – classes que serão convertidas em tabelas de banco de dados pelo ORM do Django</p><p><code>tests.py</code> – classes de teste</p><p><code>views.py</code> – funções e classes que definem como os dados são exibidos nos <em>templates</em></p><p>Depois, é necessário registrar a aplicação no projeto. Vá para <code>analytics_project/settings.py</code> e anexe o nome da aplicação à lista <code>INSTALLED_APPS</code> :</p><pre><code class="language-python">INSTALLED_APPS = [
	'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'dashboard',
]</code></pre><p>Agora, nosso projeto está ciente da existência da aplicação.</p><h2 id="views"><strong><strong>Views</strong></strong></h2><p><br>No <code>dashboard/views.py</code>, vamos criar uma função que direciona um usuário para os <em>templates </em>específicos definidos na pasta <code>dashboard/templates</code>. As visualizações (em inglês, <em>views</em>) também podem conter classes.</p><p>Veja como a definimos:</p><pre><code class="language-python">from django.http import JsonResponse
from django.shortcuts import render
from dashboard.models import Order
from django.core import serializers

def dashboard_with_pivot(request):
    return render(request, 'dashboard_with_pivot.html', {})</code></pre><p>Uma vez chamada, esta função renderizará <code>dashboard_with_pivot.html</code>, um template que definiremos em breve. Ele conterá os componentes da tabela e dos gráficos dinâmicos. </p><p>Mais algumas palavras sobre esta função. Seu argumento <code>request</code>, uma instância de <code>HttpRequestObject</code>, contém informações sobre a solicitação – por exemplo, o método HTTP usado (GET ou POST). O método <code>render</code> procura por <em>templates de </em>HTML em um diretório de <em>templates </em>localizado dentro do diretório da aplicação.</p><p>Também precisamos criar um método auxiliar que envie a resposta com dados para a tabela dinâmica no front-end da aplicação. Vamos chamá-lo de <code>pivot_data</code>:</p><pre><code class="language-python">def pivot_data(request):
    dataset = Order.objects.all()
    data = serializers.serialize('json', dataset)
    return JsonResponse(data, safe=False)</code></pre><p>Provavelmente, seu IDE estará informando que não pode encontrar a referência a <code>Order</code> em <code>models.py</code>. Sem problemas - trataremos disso mais tarde.</p><h2 id="templates"><strong><strong>Templates</strong></strong></h2><p>Por enquanto, vamos aproveitar o sistema de <em>templates </em>do Django.</p><p>Vamos criar um diretório <code>templates</code> dentro de <code>dashboard</code> e criar o primeiro <em>template</em> de HTML, chamado <code><strong><strong>dashboard_with_pivot.html</strong></strong></code>. Ele será exibido ao usuário mediante solicitação. Aqui, também adicionamos os scripts e contêineres para componentes de visualização de dados:</p><pre><code class="language-html">&lt;head&gt;
  &lt;meta charset="UTF-8"&gt;
  &lt;title&gt;Dashboard with Flexmonster&lt;/title&gt;
  &lt;script src="https://cdn.flexmonster.com/flexmonster.js"&gt;&lt;/script&gt;
  &lt;script src="https://code.jquery.com/jquery-3.3.1.min.js"&gt;&lt;/script&gt;
  &lt;link rel="stylesheet" href="https://cdn.flexmonster.com/demo.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="pivot-table-container" data-url="{% url 'pivot_data' %}"&gt;&lt;/div&gt;
&lt;div id="pivot-chart-container"&gt;&lt;/div&gt;
&lt;/body&gt;</code></pre><h2 id="fun-es-de-visualiza-o-de-mapeamento-para-urls">Funções de visualização de mapeamento para URLs</h2><p>Para chamar as visualizações e exibir <em>templates </em>de HTML renderizados para o usuário, precisamos mapear as visualizações para os URLs correspondentes.</p><blockquote>Aqui tem uma dica: <a href="https://docs.djangoproject.com/en/2.1/misc/design-philosophies/#id8">um dos princípios de design de URL do Django é sobre um acoplamento fraco</a>, (texto em inglês). Não devemos fazer URLs com os mesmos nomes das funções do Python.</blockquote><p>Vá para <code>analytics_app/urls.py</code> e adicione as configurações relevantes ao <code>dashboard</code> da aplicação em nível de projeto.</p><pre><code class="language-python">from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('dashboard/', include('dashboard.urls')),
]
</code></pre><p>Agora, os URLs da aplicação de <code>dashboard</code> podem ser acessados, mas somente se forem prefixados com <code>dashboard</code>.</p><p>Depois, vá para <code>dashboard/urls.py</code> (crie este arquivo se ele não existir) e adicione uma lista de padrões de URL que são mapeados para as funções de visualização:</p><pre><code class="language-python">from django.urls import path
from . import views

urlpatterns = [
    path('', views.dashboard_with_pivot, name='dashboard_with_pivot'),
    path('data', views.pivot_data, name='pivot_data'),
]</code></pre><h2 id="modelos"><strong><strong>Model</strong>os</strong></h2><p><br>Finalmente, chegamos à <strong>modelagem de dados</strong>. Essa é a minha parte favorita.</p><p>Como você deve saber, um modelo de dados é uma representação conceitual dos dados armazenados em um banco de dados.</p><p>Como o objetivo deste tutorial é mostrar como construir uma visualização interativa de dados dentro da aplicação, não vamos nos preocupar muito com a escolha do banco de dados. Usaremos o SQLite – um banco de dados leve que acompanha o servidor de desenvolvimento para a web do Django.</p><p>Lembre-se, porém, de que esse banco de dados não é a escolha apropriada para o desenvolvimento em produção. Com o ORM do Django, você pode usar outros bancos de dados que usam a linguagem SQL, como o PostgreSQL ou o MySQL.</p><p>Por uma questão de simplicidade, nosso modelo consistirá em uma classe. Você pode criar mais classes e definir relações entre elas, complexas ou simples.</p><p>Imagine que estamos projetando <strong>um painel para o departamento de vendas</strong>. Então, vamos criar uma classe <code>Order</code> (em português, o pedido) e definir seus atributos em <code>dashboard/models.py</code>:</p><pre><code class="language-python">from django.db import models


class Order(models.Model):
    product_category = models.CharField(max_length=20)
    payment_method = models.CharField(max_length=50)
    shipping_cost = models.CharField(max_length=50)
    unit_price = models.DecimalField(max_digits=5, decimal_places=2)</code></pre><h2 id="trabalhando-com-um-banco-de-dados">Trabalhando com um banco de dados</h2><p><br>Agora, precisamos criar um banco de dados e preenchê-lo com registros.</p><p><em>Como, no entanto, podemos traduzir nossa classe modelo para uma tabela de banco de dados</em>?</p><p>É aqui que o conceito de <strong>migração </strong>é útil. <strong>A migração</strong> é simplesmente um arquivo que descreve quais mudanças devem ser aplicadas ao banco de dados. Toda vez que precisamos criar um banco de dados baseado no modelo descrito pelas classes do Python, usamos a migração.</p><p>Os dados podem vir como objetos, dicionários ou listas do Python. Desta vez, vamos representar as entidades do banco de dados usando classes do Python que estão localizadas no diretório <code>models</code>.</p><p>Crie a migração para a aplicação com um comando:</p><p><code>python manage.py makemigrations dashboard</code></p><p>Aqui, especificamos que a aplicação deve dizer ao Django para aplicar migrações para os modelos da aplicação de <code>dashboard</code>.</p><p>Após criar um arquivo de migração, aplique as migrações descritas nele e crie um banco de dados:</p><p><code>python manage.py migrate dashboard</code></p><p>Caso perceba que há um novo arquivo <code>db.sqlite3</code> no diretório do projeto, é sinal de que estamos prontos para trabalhar com o banco de dados.</p><p>Vamos criar instâncias da nossa classe <code>Order</code>. Para isso, usaremos o shell do Django - é semelhante ao shell do Python, mas permite acessar o banco de dados e criar entradas.</p><p>Então, inicie o shell do Django:</p><p><code>python manage.py shell</code></p><p>Escreva no console interativo do shell o seguinte código:</p><pre><code class="language-python">from dashboard.models import Order

&gt;&gt;&gt; o1 = Order(
... product_category='Books',
... payment_method='Credit Card',
... shipping_cost=39,
... unit_price=59
... )
&gt;&gt;&gt; o1.save()</code></pre><p>Você pode criar e salvar quantos objetos precisar do mesmo modo.</p><h2 id="conectando-dados-ao-flexmonster">Conectando dados ao Flexmonster</h2><p><br>Aqui está o que eu prometi explicar.</p><p>Vamos descobrir como passar os dados do seu modelo para a ferramenta de visualização de dados no front-end.</p><p>Para fazer o back-end e o Flexmonster se comunicarem, podemos seguir duas abordagens diferentes:</p><ul><li><em>Usar o ciclo de request-response. Podemos usar o Python e o mecanismo de template do Django para escrever código em JavaScript diretamente no template</em>. </li><li><em>Usar uma solicitação assíncrona (AJAX) que retorna os dados em JSON.</em></li></ul><p>Na minha opinião, o segundo é o mais conveniente por vários motivos. Em primeiro lugar, o Flexmonster entende JSON. Para ser mais precisa, ele pode aceitar uma matriz de objetos JSON como dados de entrada. Outro benefício do uso de solicitações assíncronas é a maior velocidade de carregamento da página e o código mais sustentável.</p><p>Vamos ver como isso funciona.</p><p>Vá para <code>templates/dashboard_pivot.html</code>.</p><p>Aqui, criamos dois contêineres <code>div</code>, onde a tabela e os gráficos dinâmicos serão renderizados.</p><p>Dentro da chamada de Ajax, fazemos uma requisição com base no URL contido na propriedade <code>data-URL</code>. Em seguida, informamos à solicitação Ajax que esperamos que um objeto JSON seja retornado (definido por <code>dataType</code>).</p><p>Depois que a solicitação for concluída, a resposta em JSON retornada pelo nosso servidor será definida para o parâmetro <code>data</code> e a tabela dinâmica, preenchida com esses dados, será renderizada.</p><p>O resultado da consulta (a instância de <code>JSONResponse</code>) retorna uma string que contém um objeto de array com metainformações adicionais. Então, devemos adicionar uma pequena função para processamento de dados no front-end. Ela extrairá apenas os objetos aninhados de que precisamos e os colocará em um único array. Isso ocorre porque o Flexmonster aceita apenas um array de objetos JSON sem níveis aninhados.</p><pre><code class="language-javascript">function processData(dataset) {
    var result = []
    dataset = JSON.parse(dataset);
    dataset.forEach(item =&gt; result.push(item.fields));
    return result;
}</code></pre><p>Após o processamento dos dados, o componente os recebe no formato correto e realiza todo o trabalho árduo de visualização dos dados. Uma grande vantagem é que não há necessidade de agrupar ou agregar os valores dos objetos manualmente.</p><p>Veja a aparência do script completo no <em>template</em>:</p><pre><code class="language-javascript">function processData(dataset) {
    var result = []
    dataset = JSON.parse(dataset);
    dataset.forEach(item =&gt; result.push(item.fields));
    return result;
}
$.ajax({
    url: $("#pivot-table-container").attr("data-url"),
    dataType: 'json',
    success: function(data) {
        new Flexmonster({
            container: "#pivot-table-container",
            componentFolder: "https://cdn.flexmonster.com/",
            width: "100%",
            height: 430,
            toolbar: true,
            report: {
                dataSource: {
                    type: "json",
                    data: processData(data)
                },
                slice: {}
            }
        });
        new Flexmonster({
            container: "#pivot-chart-container",
            componentFolder: "https://cdn.flexmonster.com/",
            width: "100%",
            height: 430,
            //toolbar: true,
            report: {
                dataSource: {
                    type: "json",
                    data: processData(data)
                },
                slice: {},
                "options": {
                    "viewType": "charts",
                    "chart": {
                        "type": "pie"
                    }
                }
            }
        });
    }
});</code></pre><p>Não se esqueça de incluir este código JavaScript em tags <code>&lt;script&gt;</code> .</p><p><em>Ufa! Estamos quase no final desta aplicação.</em></p><h2 id="personaliza-o-de-campos">Personalização de campos</h2><p>O Flexmonster fornece uma propriedade especial de fonte de dados que permite definir tipos de dados de campo, legendas personalizadas e definir hierarquias de vários níveis.</p><p>Esse é um bom recurso – podemos separar elegantemente os dados e sua apresentação diretamente na configuração do relatório.</p><p>Adicione-a à propriedade <code>dataSource</code> do relatório:</p><pre><code class="language-javascript">mapping: {
    "product_category": {
        "caption": "Product Category",
        "type": "string"
    },
    "payment_method": {
        "caption": "Payment Method",
        "type": "string"
    },
    "shipping_cost": {
        "caption": "Shipping Cost",
        "type": "number"
    },
    "unit_price": {
        "caption": "Unit Price",
        "type": "number"
    }
}</code></pre><h2 id="projeto-do-painel">Projeto do painel</h2><p><br>Para fazer o painel, renderizamos duas instâncias do Flexmonster (você pode criar quantas quiser, dependendo dos objetivos de visualização de dados que deseja alcançar). Uma das instâncias é para a tabela dinâmica com dados resumidos e a outra é para os gráficos dinâmicos.</p><p>Ambas compartilham da mesma fonte de dados do nosso modelo. Eu encorajo você a tentar fazê-los funcionar em sincronia: com o evento <a href="https://www.flexmonster.com/api/reportchange/?r=fr5"><code>reportchange</code></a>, você pode fazer uma instância reagir às mudanças de outra.</p><p>Você também pode redefinir a funcionalidade do botão 'Exportar' na Barra de Ferramentas para salvar seus relatórios no servidor.</p><h2 id="resultados"><strong><strong>Result</strong>ado<strong>s</strong></strong></h2><p>Vamos iniciar o servidor de desenvolvimento Django e abrir <a href="http://127.0.0.1:8000/dashboard/"><code>http://127.0.0.1:8000/dashboard/</code></a> para ver o painel resultante:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/DjangoFlexmonster.gif" class="kg-image" alt="DjangoFlexmonster" width="1920" height="1076" loading="lazy"></figure><p>Parece bom, não é?</p><h2 id="conclus-o"><strong>Conclusão</strong></h2><p>Aqui, aprendemos <strong>como criar uma aplicação do Django simples</strong> e como exibir os dados no lado do <em>client </em>na forma de um <strong>painel de análise</strong>. Espero que tenham gostado do tutorial!</p><h2 id="refer-ncias">Referências</h2><p>O código-fonte do tutorial pode ser encontrado no <a href="https://github.com/veronikaro/django-dashboard-app">GitHub</a>. Aqui, temos o projeto de integração <a href="https://www.flexmonster.com/doc/integration-with-django/?r=fr5">do Flexmonster e do Django</a> que me inspirou a fazer este tutorial.</p><p>Além disso, recomendo percorrer conceitos importantes na documentação para dominar o Django (textos da documentação em inglês):</p><ul><li><a href="https://docs.djangoproject.com/en/3.0/topics/migrations/">Migrações no Django</a></li><li><a href="https://docs.djangoproject.com/en/3.0/ref/models/querysets/">QuerySets</a></li><li><a href="https://docs.djangoproject.com/en/3.0/topics/serialization/">Serialização de objetos no Django</a></li></ul><h4 id="se-este-artigo-foi-til-para-voc-compartilhe-o-obrigada-"><strong>Se este artigo foi útil para você, compartilhe-o! Obrigada!</strong></h4> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como fazer uma chamada de API no Swift ]]>
                </title>
                <description>
                    <![CDATA[ Se você deseja se tornar um desenvolvedor iOS, existem algumas habilidades fundamentais que vale a pena conhecer. Em primeiro lugar, é importante estar familiarizado com a criação de visualizações de tabela. Em segundo, você deve saber como preencher essas visualizações de tabela com dados. Em terceiro, é ótimo se você ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-fazer-uma-chamada-de-api-no-swift/</link>
                <guid isPermaLink="false">63165480281b1606c8fcd06d</guid>
                
                    <category>
                        <![CDATA[ API ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paula Flávia Pagotto Simionato ]]>
                </dc:creator>
                <pubDate>Sun, 25 Sep 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/5f9c9ef3740569d1a4ca4004.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-make-your-first-api-call-in-swift/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to make an API call in Swift</a>
      </p><p>Se você deseja se tornar um desenvolvedor iOS, existem algumas habilidades fundamentais que vale a pena conhecer. Em primeiro lugar, é importante estar familiarizado com a criação de visualizações de tabela. Em segundo, você deve saber como preencher essas visualizações de tabela com dados. Em terceiro, é ótimo se você puder buscar dados de uma API e usar esses dados em sua visualização de tabela.</p><p>O terceiro ponto é o que abordaremos neste artigo. Desde a introdução do <code>Codable</code> no Swift 4, fazer chamadas de API ficou muito mais fácil. Anteriormente, a maioria das pessoas usava pods como Alamofire e SwiftyJson (você pode ler sobre como fazer isso <a href="https://code.likeagirl.io/3-steps-to-make-your-first-api-call-836e43ed702c">aqui</a> - texto em inglês). Agora, o Swift está muito melhor desde o início. Assim, não há motivo para baixar um pod.</p><p>Vamos passar por alguns blocos de construção que são frequentemente usados para fazer uma chamada de API. Abordaremos esses conceitos primeiro, pois eles são partes importantes para entender como fazer uma chamada de API.</p><ul><li>Manipuladores de conclusão (em inglês, <em>Completion handlers</em>)</li><li><code>URLSession</code></li><li><code>DispatchQueue</code></li><li>Ciclos de retenção</li></ul><p>Por fim, vamos juntar isso tudo. Usaremos a <a href="https://www.swapi.co/">API de Star Wars</a> de código aberto para construir esse projeto. Você pode ver o código completo do meu projeto no <a href="https://github.com/ailyntang/starwars/">GitHub</a>.</p><p><em>Alerta de isenção de responsabilidade: sou nova na programação e sou autodidata. Peço desculpas se deturpei alguns conceitos.</em></p><h2 id="manipuladores-de-conclus-o">Manipuladores de conclusão</h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/pheobe.jpeg" class="kg-image" alt="pheobe" width="299" height="168" loading="lazy"><figcaption>Pobre e paciente Phoebe</figcaption></figure><p>Lembra do episódio de Friends em que a Phoebe fica grudada no telefone por dias esperando para falar com o atendimento ao cliente? Imagine se, bem no início dessa ligação, uma pessoa adorável chamada Pip dissesse: "Obrigado por ligar. Não tenho ideia de quanto tempo você precisará esperar, mas ligo de volta quando estivermos prontos para você." Não teria sido tão engraçado, mas Pip estaria se oferecendo para ser um manipulador de conclusão para Phoebe.</p><p>Você usa um manipulador de conclusão em uma função quando sabe que essa função demorará um pouco para ser concluída. Você não sabe quanto tempo e não quer pausar sua vida esperando que ela termine. Então, você pede a Pip para dar um toque a você quando ela estiver pronta para dar uma resposta. Desse modo, você pode seguir sua vida, sair para comprar coisas, ler um livro e assistir TV. Quando Pip avisar você que já tem a resposta, você pode pegá-la e usá-la.</p><p>Isso é o que acontece com as chamadas de API. Você envia uma solicitação de URL para um servidor, solicitando alguns dados. Você espera que o servidor retorne os dados rapidamente, mas não sabe quanto tempo levará. Em vez de fazer seu usuário esperar pacientemente até que o servidor forneça os dados, você usa um manipulador de conclusão. Isso significa que você pode dizer ao seu aplicativo para desligar e fazer outras coisas, como carregar o resto da página.</p><p>Você diz ao manipulador de conclusão para avisar o seu aplicativo assim que ele tiver as informações desejadas. Você pode especificar quais são essas informações. Desse modo, quando seu aplicativo é avisado, ele pode pegar as informações do manipulador de conclusão e fazer algo com elas. Normalmente, o que você fará é recarregar a visualização da tabela para que os dados apareçam para o usuário.</p><p>Aqui está um exemplo da aparência de um manipulador de conclusão. O primeiro exemplo é de quando configuramos a própria chamada da API:</p><figure class="kg-card kg-code-card"><pre><code class="language-swift">func fetchFilms(completionHandler: @escaping ([Film]) -&gt; Void) {
  // Configurar a variável lotsOfFilms
  var lotsOfFilms: [Film]
  
  // Chamar a API com algum código
  
  // Usar os dados da API, atribuir um valor a lotsOfFilms  
  
  // Dar ao manipulador de conclusão a variável lotsOfFilms
  completionHandler(lotsOfFilms)
}</code></pre><figcaption>A function that uses a completion handler</figcaption></figure><p>Agora, podemos invocar a função <code>fetchFilms</code>. Algumas coisas a serem observadas:</p><ul><li>Você não precisa referenciar o <code>completionHandler</code> quando você chama a função. A única vez em que você faz referência ao <code>completionHandler</code> está dentro da declaração da função.</li><li>O manipulador de conclusão nos devolverá alguns dados para usar. Com base na função que escrevemos acima, sabemos esperar dados do tipo <code>[Film]</code>. Precisamos nomear os dados para que possamos nos referir a eles. Abaixo, estou usando o nome <code>films</code>, mas poderia ser <code>randomData</code>, ou qualquer outro nome de variável.</li></ul><p>O código ficará mais ou menos assim:</p><figure class="kg-card kg-code-card"><pre><code class="language-swift">fetchFilms() { (films) in
  // Fazer algo com os dados retornados pelo manipulador de conclusão 
  print(films)
}</code></pre><figcaption>Implementing a function with a completion handler</figcaption></figure><h2 id="urlsession"><strong><strong>URLSession</strong></strong></h2><p><code>URLSession</code> é como o gerente de uma equipe. O gerente não faz nada sozinho. Seu trabalho é compartilhar o trabalho com as pessoas de sua equipe, e eles farão o trabalho. A equipe dela são as <code>dataTasks</code>. Toda vez que você precisar de alguns dados, escreva para o chefe e use <code>URLSession.shared.dataTask</code>.</p><p>Você pode dar ao <code>dataTask</code> diferentes tipos de informações para ajudá-lo a atingir seu objetivo. Dar informações ao <code>dataTask</code> é chamado de inicialização. Eu inicializo meu <code>dataTasks</code> com URLs. As <code>dataTasks</code> também usam manipuladores de conclusão como parte de sua inicialização. Aqui está um exemplo:</p><figure class="kg-card kg-code-card"><pre><code class="language-swift">let url = URL(string: "https://www.swapi.co/api/films")

let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in 
  // Insira seu código aqui
})

task.resume()</code></pre><figcaption>How to use URLSession to fetch some data</figcaption></figure><p>As <code>dataTasks</code> usam manipuladores de conclusão e sempre retornam os mesmos tipos de informações: <code>data</code>, <code>response</code> e <code>error</code>. Você pode dar nomes diferentes a esses tipos de dados, como<code>(data, res, err)</code> ou <code>(someData, someResponse, someError)</code>. Por uma questão de convenção, é melhor se ater a algo óbvio em vez de usar novos nomes de variáveis.</p><p>Vamos começar com <code>error</code>. Se <code>dataTask</code> retorna um <code>error</code>, você vai querer saber isso antecipadamente. Isso significa que você pode direcionar seu código para lidar com o erro normalmente. Isso também significa que você não se incomodará em tentar ler os dados e fazer algo com eles, pois há um erro ao retornar os dados.</p><p>Abaixo, estou lidando com o erro simplesmente imprimindo um erro no console e saindo da função. Existem muitas outras maneiras de lidar com o erro, se desejar. Pense em como esses dados são fundamentais para seu aplicativo. Por exemplo, se você tiver um aplicativo bancário e essa chamada de API mostrar o saldo dos usuários, convém lidar com o erro apresentando um modal ao usuário que diz: "Desculpe, estamos enfrentando um problema agora. Tente de novo mais tarde."</p><figure class="kg-card kg-code-card"><pre><code class="language-swift">if let error = error {
  print("Error accessing swapi.co: /(error)")
  return
}</code></pre><figcaption>Tratamento do erro</figcaption></figure><p> Em seguida, analisamos a resposta. Você pode converter a resposta para que seja um <code>httpResponse</code>. Desse modo, você pode ver os códigos de status e tomar algumas decisões com base no código. Por exemplo, se o código de status for 404, você saberá que a página não foi encontrada.</p><p>O código abaixo usa <code>guard</code> para verificar se existem duas coisas. Se ambos existirem, ele permitirá que o código continue para a próxima instrução após a cláusula de <code>guard</code>. Se qualquer uma das instruções falhar, saímos da função. Este é um caso de uso típico de uma cláusula de <code>guard</code>. Você espera que o código após uma cláusula de <code>guard</code> seja o fluxo ideal (ou seja, o fluxo fácil sem erros).</p><pre><code class="language-swift">  guard let httpResponse = response as? HTTPURLResponse,
            (200...299).contains(httpResponse.statusCode) else {
    print("Erro na resposta. Código de status esperado: \(response)")
    return
  }</code></pre><p>Finalmente, você lida com os dados em si. Observe que não usamos o manipulador de conclusão para <code>error</code> ou para <code>response</code>. Isso ocorre porque o manipulador de conclusão está aguardando dados da API. Se não chegar à parte de dados do código, não há necessidade de invocar o manipulador.</p><p>Estamos usando o <code>JSONDecoder</code> para analisar os dados de uma maneira agradável. Isso é muito bom, mas requer que você tenha estabelecido um modelo. Nosso modelo é chamado <code>FilmSummary</code>. Se o <code>JSONDecoder</code> for novo para você, dê uma olhada on-line para saber como usá-lo e como usar o <code>Codable</code>. É muito simples no Swift 4 e em versões superiores em comparação com a época do Swift 3.</p><p>No código abaixo, primeiro verificamos se os dados existem. Temos certeza de que deve existir, porque não há erros nem respostas HTTP estranhas. Em segundo lugar, verificamos se podemos analisar os dados que recebemos da maneira que esperamos. Se pudermos, devolvemos o resumo do filme ao manipulador de conclusão. Caso não haja dados para retornar da API, temos um plano de retorno (em inglês, <em>fall back</em>) do array vazio.</p><pre><code class="language-swift">if let data = data,
        let filmSummary = try? JSONDecoder().decode(FilmSummary.self, from: data) {
        completionHandler(filmSummary.results ?? [])
      }</code></pre><p>Portanto, o código completo para a chamada da API fica assim:</p><pre><code class="language-swift">func fetchFilms(completionHandler: @escaping ([Film]) -&gt; Void) {
    let url = URL(string: domainUrlString + "films/")!

    let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
      if let error = error {
        print("Erro ao obter os filmes: \(error)")
        return
      }
      
      guard let httpResponse = response as? HTTPURLResponse,
            (200...299).contains(httpResponse.statusCode) else {
        print("Erro na resposta. Código de status esperado: \(response)")
        return
      }

      if let data = data,
        let filmSummary = try? JSONDecoder().decode(FilmSummary.self, from: data) {
        completionHandler(filmSummary.results ?? [])
      }
    })
    task.resume()
  }</code></pre><h2 id="ciclos-de-reten-o"><strong>Ci<strong>cl</strong>o<strong>s</strong> de retenção</strong></h2><p>Aviso: eu estou muito no início dos meus estudos nova para entender os ciclos de retenção! Aqui está a essência do que eu pesquisei on-line.</p><p>Os ciclos de retenção são importantes para o gerenciamento de memória. Basicamente, você quer que seu aplicativo limpe pedaços de memória de que não precisa mais. Suponho que isso torna o aplicativo mais eficiente.<br>Há muitas maneiras de o Swift ajudar você a fazer isso automaticamente.</p><p>No entanto, há muitas maneiras de codificar acidentalmente ciclos de retenção em seu aplicativo. Um ciclo de retenção significa que seu aplicativo sempre manterá a memória para um determinado trecho de código. Geralmente, isso acontece quando você tem duas coisas que têm indicadores fortes uma para a outra.</p><p>Para contornar isso, as pessoas costumam usar <code>weak</code>. Quando um lado do código é <code>weak</code>, você não tem um ciclo de retenção e seu aplicativo poderá liberar a memória.</p><p>Para nosso propósito, um padrão comum é usar <code>[weak self]</code> ao chamar a API. Isso garante que, assim que o manipulador de conclusão retornar algum código, o aplicativo possa liberar a memória.</p><pre><code class="language-swift">fetchFilms { [weak self] (films) in
  // Seu código aqui
}</code></pre><h2 id="fila-de-despacho-dispatchqueue-em-ingl-s-">Fila de despacho (<strong><strong><em>DispatchQueue</em></strong>, em inglês)</strong></h2><p>O Xcode usa diferentes <em>threads </em>para executar código em paralelo. A vantagem de vários <em>threads </em>está no fato de que você não fica parado esperando que uma coisa termine antes de passar para a próxima. Espero que você já esteja vendo a ligação com os manipuladores de conclusão aqui.</p><p>Esses <em>threads</em> também parecem ser chamados de filas de despacho. As chamadas de API são tratadas em uma fila – normalmente, uma fila em segundo plano. Depois de ter os dados de sua chamada de API, provavelmente você desejará mostrar esses dados ao usuário. Isso significa que você desejará atualizar sua visualização de tabela.</p><p>As exibições de tabela fazem parte da interface do usuário. Todas as manipulações da interface do usuário devem ser feitas na fila de despacho principal. Isso significa que, em algum lugar no seu arquivo de controlador de visualização, geralmente, como parte da função <code>viewDidLoad</code>, você deve ter um trecho de código que diga à sua visualização de tabela para atualizar.</p><p>Queremos que a visualização de tabela seja atualizada apenas quando tiver alguns novos dados da API. Isso significa que usaremos um manipulador de conclusão para nos avisar quando a chamada da API for concluída. Vamos esperar até esse aviso antes de atualizar a tabela.</p><p>O código será algo como:</p><pre><code class="language-swift">fetchFilms { [weak self] (films) in
  self.films = films

  // Recarregar a visualização de tabela usando a fila de despacho principal
  DispatchQueue.main.async {
    tableView.reloadData()
  }
}</code></pre><h2 id="viewdidload-x-viewdidappear"><strong><strong>viewDidLoad </strong>x<strong> viewDidAppear</strong></strong></h2><p>Finalmente, você precisa decidir onde chamar sua função <code>fetchfilms</code>. Ele estará dentro de um controlador (em inglês, <em>controller</em>) de visualização, que usará os dados da API. Existem dois lugares óbvios em que você pode fazer essa chamada de API. Um está dentro de <code>viewDidLoad</code> e o outro está dentro de <code>viewDidAppear</code>.</p><p>Esses são dois estados diferentes para seu aplicativo. Meu entendimento é o de que <code>viewDidLoad</code> é chamado na primeira vez em que você carrega essa visualização em primeiro plano. <code>viewDidAppear</code> é chamado toda vez que você volta a essa visualização, por exemplo, quando você pressiona o botão Voltar para voltar à visualização.</p><p>Se você espera que seus dados mudem entre os momentos em que o usuário navegará para e a partir dessa visualização, convém colocar sua chamada de API em <code>viewDidAppear</code>. No entanto, acho que para quase todos os aplicativos <code>viewDidLoad</code> é suficiente. A Apple recomenda <code>viewDidAppear</code> para todas as chamadas de API, mas isso parece um exagero. Imagino que isso tornaria seu aplicativo menos eficiente, pois está fazendo muito mais chamadas de API do que precisa.</p><h2 id="combinando-todas-as-etapas">Combinando todas as etapas</h2><p>Primeiro: escreva a função que chama a API. Acima, essa função é a <code>fetchFilms</code>. Ela terá um manipulador de conclusão, que retornará os dados nos quais você está interessado. No meu exemplo, o manipulador de conclusão retorna um <em>array</em> de filmes.</p><p>Segundo: chame essa função em seu controlador de visualização. Você faz isso aqui porque deseja atualizar a visualização com base nos dados da API. No meu exemplo, estou atualizando uma visualização de tabela assim que a API retornar os dados.</p><p>Terceiro: decida onde em seu controlador de visualização você gostaria de chamar a função. No meu exemplo, eu chamo de <code>viewDidLoad</code>.</p><p>Quarto: decida o que fazer com os dados da API. No meu exemplo, estou atualizando uma visualização de tabela.</p><p>Dentro de <code>NetworkManager.swift</code> (esta função pode ser definida em seu controlador de visualização se você quiser, mas estou usando o padrão MVVM).</p><pre><code class="language-swift">func fetchFilms(completionHandler: @escaping ([Film]) -&gt; Void) {
    let url = URL(string: domainUrlString + "films/")!

    let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
      if let error = error {
        print("Erro ao obter os filmes: \(error)")
        return
      }
      
      guard let httpResponse = response as? HTTPURLResponse,
            (200...299).contains(httpResponse.statusCode) else {
        print("Erro na responta. Código de status inesperado: \(response)")
        return
      }

      if let data = data,
        let filmSummary = try? JSONDecoder().decode(FilmSummary.self, from: data) {
        completionHandler(filmSummary.results ?? [])
      }
    })
    task.resume()
  }</code></pre><p>Dentro de <code>FilmsViewController.swift</code>:</p><pre><code class="language-swift">final class FilmsViewController: UIViewController {
  private var films: [Film]?

  override func viewDidLoad() {
    super.viewDidLoad()
    
    NetworkManager().fetchFilms { [weak self] (films) in
      self?.films = films
      DispatchQueue.main.async {
        self?.tableView.reloadData()
      }
    }
  }
  
  // o resto do código para o controlador de visualizações
}</code></pre><p>Puxa, conseguimos! Obrigado por ficar comigo até o final da leitura.</p><h4 id="se-essa-publica-o-foi-til-para-voc-compartilhe-obrigada-"><strong><strong>Se essa publicação foi útil para você, compartilhe! Obrigad</strong>a<strong>!</strong></strong></h4> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como personalizar arquivos .env do Node.js para diferentes estágios do ambiente ]]>
                </title>
                <description>
                    <![CDATA[ Escrito por: Erisan Olasheni > Você já se viu em uma situação em que precisava de variáveis de ambiente personalizadas para diferentes estágios de desenvolvimento do seu aplicativo? Aqui está uma solução de uma linha. O desenvolvimento tem sido muito mais fácil desde a invenção do arquivo .env. Você pode ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-personalizar-arquivos-envdo-node-js-para-diferentes-estagios-do-ambiente/</link>
                <guid isPermaLink="false">630340f7883bbf06e4bea191</guid>
                
                    <category>
                        <![CDATA[ Node.js ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paula Flávia Pagotto Simionato ]]>
                </dc:creator>
                <pubDate>Mon, 19 Sep 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/1_s20L9h0d1TmrZGrxLZAZ7Q.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/nodejs-custom-env-files-in-your-apps-fa7b3e67abe1/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to customize Node.js .env files for different environment stages</a>
      </p><p>Escrito por: Erisan Olasheni</p><blockquote><strong>Você já se viu em uma situação em que precisava de variáveis de ambiente personalizadas para diferentes estágios de desenvolvimento do seu aplicativo? Aqui está uma solução de uma linha.</strong></blockquote><p>O desenvolvimento tem sido muito mais fácil desde a invenção do arquivo <code>.env</code>. Você pode definir facilmente suas variáveis e valores de ambiente com a sintaxe <code>VARIAVEL_DE_AMBIENTE=VALOR</code> e pronto! Essas variáveis foram carregadas como suas variáveis de ambiente, possibilitando acesso rápido a elas :</p><pre><code class="language-bash">console.log(process.env.VARIAVEL_DE_AMBIENTE)</code></pre><p>Caso você ainda esteja se perguntando o que tudo isso significa, bem, você provavelmente não conhece o arquivo <code>.env</code>. Na verdade, é um arquivo de texto de configuração simples, que é usado para definir algumas variáveis que você deseja passar para o ambiente do seu aplicativo.</p><p>Este arquivo precisa de algo como um <strong>analisador</strong> para fazê-lo funcionar. O analisador lê as definições de variáveis<strong> uma a uma</strong> e as analisa para o ambiente. Ele usa o formato <strong>VARIAVEL_DE_AMBIENTE=VALOR</strong> (no caso do Node.js: <code>process.env[VARIAVEL_DE_AMBIENTE]=VALOR</code>).</p><p>Obviamente, esse não é um recurso interno do Node.js. Você precisa projetá-lo com um módulo popular chamado <strong>dotenv</strong>.</p><p>É uma boa solução alternativa, pois realmente facilitou o desenvolvimento entre co-desenvolvedores e em toda a comunidade de desenvolvedores como um todo. Eu, pessoalmente, estava usando o módulo <strong>dotenv</strong>. Até que fiquei preso tentando obter uma solução que pudesse me fazer usar um arquivo de configuração diferente para um ambiente específico. Isso seria ainda mais legal... certo? Sim! Infelizmente, porém, o módulo<strong> dotenv </strong>não nos fornece essa vantagem.</p><p><strong>Então, o que vem depois? Precisamos disso para facilitar o desenvolvimento e os testes em diferentes estágios de desenvolvimento!</strong></p><h3 id="que-tal-arquivos-env-personalizados-para-diferentes-est-gios-do-ambiente">Que tal arquivos .env personalizados para diferentes estágios do ambiente?</h3><p>Você não acha que seria uma boa solução? Definir variáveis de ambiente personalizadas apenas criando um arquivo .env.nome_do_ambiente? Legal! Isso é o que custom-env veio fazer.</p><p><strong>Custom-env é uma biblioteca criada para facilitar o desenvolvimento, permitindo várias configurações de .env para diferentes ambientes. </strong>Isso é feito carregando variáveis de ambiente de um arquivo .env.nome_do_ambiente no objeto <code>process.env</code> &nbsp;do Node.</p><h4 id="instala-o"><strong><strong>Instala</strong>ção</strong></h4><p>Basta usar o seguinte comando:</p><pre><code class="language-bash">npm i custom-env</code></pre><h4 id="uso"><strong><strong>Us</strong>o</strong></h4><pre><code class="language-bash">require('custom-env').env()</code></pre><p>Por padrão, custom-env escolhe o arquivo .env para seu estágio do desenvolvimento. No entanto, para personalizar para um estágio diferente, adicione o nome como um sufixo, como em .env.nome_do_ambiente.</p><p><strong><strong>Ex</strong>e<strong>mpl</strong>o</strong></p><p>Podemos definir uma variável de ambiente personalizada para um <strong>desenvolvimento de teste.</strong></p><ul><li>Crie um arquivo .env.staging</li><li>Defina suas variáveis</li></ul><pre><code class="language-bash">APP_ENV=staging
APP_NAME=custom environment app
DB_HOST=localhost
DB_USER=user
DB_PASS=pass</code></pre><ul><li><strong>Acesse suas variáveis</strong></li></ul><pre><code class="language-js">// Solicite o custom-env e defina seu arquivo env preferencial

require ('custom-env').env('staging')

console.log(process.env.APP_ENV)

console.log(process.env.APP_NAME)

console.log(process.env.DB_HOST)

console.log(process.env.DB_PASS)</code></pre><p><strong><strong> </strong>Resultado esperado</strong></p><pre><code class="language-bash">staging
custom environment app
localhost
user
pass</code></pre><p>É isso, bem fácil. Sinta-se à vontade para definir mais variáveis para diferentes estágios que você achar necessário, como:</p><p><em><em>.env.test</em>es<em>, .env.staging, .env.serv</em>idor<em>1, .env.serv</em>idor<em>2, .env.localhost</em></em></p><h3 id="definir-para-o-ambiente-atual">Definir para o ambiente atual</h3><p>Você pode dizer ao<em> custom-env</em> para usar uma configuração que corresponda ao seu estágio de desenvolvimento atual passando<strong> true</strong> para o método &nbsp;<code><em><em>env()</em></em></code><em>.<em> </em></em></p><p><strong><strong>Ex</strong>e<strong>mpl</strong>o</strong></p><p><strong>Arquivo<strong>: index.js</strong></strong></p><pre><code class="language-js">// Passe true para env() para fazer o método usar o estágio de ambiente atual.

require('custom-env').env(true)

console.log(process.env.APP_NAME)
console.log(process.env.USERNAME)
console.log(process.env.PASSKEY)</code></pre><p>Agora, vamos definir um arquivo de configuração de staging:</p><p><strong>Arquivo<strong>: .env.staging</strong></strong></p><pre><code class="language-bash">APP_NAME=Staging Node App
USER_NAME=John
PASSKEY=J*h*</code></pre><p>Vamos servir com o Node usando o arquivo de staging:</p><pre><code class="language-bash">NODE_ENV=staging node index.js</code></pre><p><strong><strong> </strong>Resultado esperado</strong></p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/7tb8GikXlYKDDLXQoSaVwvOKfAxsG9iOVcNz.png" class="kg-image" alt="7tb8GikXlYKDDLXQoSaVwvOKfAxsG9iOVcNz" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/7tb8GikXlYKDDLXQoSaVwvOKfAxsG9iOVcNz.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/7tb8GikXlYKDDLXQoSaVwvOKfAxsG9iOVcNz.png 800w" sizes="(min-width: 720px) 720px" width="800" height="130" loading="lazy"><figcaption>Obtém as variáveis de acordo com o ambiente de <strong>staging</strong>.</figcaption></figure><p><strong>Ai está!</strong></p><h3 id="documenta-o-completa">Documentação completa</h3><p>Para a documentação completa do <em><em>custom-env, </em></em>visite a página do <strong><strong>npm <em><em> </em></em></strong></strong><a href="https://www.npmjs.com/package/custom-env" rel="noopener">https://www.npmjs.com/package/custom-env</a></p><h3 id="c-digo-fonte"><strong>Código-fonte</strong></h3><p>Você pode contribuir com o código fonte do <em><em>custom-env</em> em<em><strong><strong> </strong></strong></em></em> <a href="https://github.com/erisanolasheni/custom-env" rel="noopener">https://github.com/erisanolasheni/custom-env</a></p><p><strong>Boa programação!</strong></p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como fazer um NFT em 14 linhas de código ]]>
                </title>
                <description>
                    <![CDATA[ Se você é um desenvolvedor interessado no desenvolvimento de blockchains, deve saber algo sobre NFTs, ou tokens não fungíveis. Portanto, neste artigo, aprenderemos sobre a engenharia por trás deles para que você possa começar a construir o seu próprio blockchain. No final do projeto, você terá sua própria carteira Ethereum, ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-fazer-um-nft-com-14-linhas-de-codigo/</link>
                <guid isPermaLink="false">62f627eb714c9406b6625afb</guid>
                
                    <category>
                        <![CDATA[ Blockchain ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paula Flávia Pagotto Simionato ]]>
                </dc:creator>
                <pubDate>Sun, 18 Sep 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/nft.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-make-an-nft/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Make an NFT in 14 Lines of Code</a>
      </p><p>Se você é um desenvolvedor interessado no desenvolvimento de blockchains, deve saber algo sobre NFTs, ou tokens não fungíveis. Portanto, neste artigo, aprenderemos sobre a engenharia por trás deles para que você possa começar a construir o seu próprio blockchain.</p><p>No final do projeto, você terá sua própria carteira Ethereum, com um novo NFT dentro dela. Este tutorial é amigável para iniciantes e não requer nenhum conhecimento prévio da rede Ethereum ou de contratos inteligentes (em inglês, <em>smart contracts</em>).</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-46.png" class="kg-image" alt="image-46" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/image-46.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/image-46.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-46.png 1112w" sizes="(min-width: 720px) 720px" width="1112" height="884" loading="lazy"><figcaption>O contrato do NFT tem apenas 14 linhas de código</figcaption></figure><h2 id="o-que-um-nft"><strong>O que é um NFT?</strong></h2><p>NFT significa token não fungível. <a href="https://ethereum.org/en/nft/">Esta citação da ethereum.org</a> explica bem:<br></p><blockquote><em><em>NFTs </em></em>são tokens que podemos usar para representar a propriedade de itens exclusivos. Eles nos permitem tokenizar coisas como arte, colecionáveis e até imóveis. Eles só podem ter um proprietário oficial de cada vez e são protegidos pelo blockchain Ethereum – ninguém pode modificar o registro de propriedade ou copiar/colar um novo NFT para fazê-lo existir.</blockquote><h2 id="o-que-um-nft-padr-o-ou-erc-721"><strong>O que é um<strong> NFT </strong>padrão<strong> o</strong>u<strong> ERC-721?</strong></strong></h2><p>O ERC-721 é o padrão NFT mais comum. Se o seu contrato inteligente implementar determinados métodos de API padronizados, ele poderá ser chamado de contrato de token não fungível ERC-721.<br>Esses métodos são especificados no <a href="https://eips.ethereum.org/EIPS/eip-721">EIP-721</a>. Projetos de código aberto, como o OpenZeppelin, simplificaram o processo de desenvolvimento ao implementar os padrões ERC mais comuns como uma biblioteca reutilizável.</p><h2 id="o-que-cunhar-um-nft">O que é cunhar um NFT?</h2><p>Ao cunhar um NFT, você publica um token exclusivo em um blockchain. Este token é uma instância do seu contrato inteligente.</p><p>Cada token tem um tokenURI exclusivo, que contém metadados de seu ativo em um arquivo JSON em conformidade com determinado esquema. Os metadados são onde você armazena informações sobre seu NFT, como nome, imagem, descrição e outros atributos.</p><p>Um exemplo de arquivo JSON para o "ERC721 Metadata Schema" se parece com este:</p><pre><code class="language-json">{
	"attributes": [
		{
			"trait_type": "Shape",
			"value": "Circle"
		},
		{
			"trait_type": "Mood",
			"value": "Sad"
		}
	],
	"description": "A sad circle.",
	"image": "https://i.imgur.com/Qkw9N0A.jpeg",
	"name": "Sad Circle"
}</code></pre><h2 id="como-armazeno-os-metadados-do-meu-nft"><strong>C<strong>o</strong>mo armazeno os metadados do meu<strong> NFT?</strong></strong></h2><p>Existem três maneiras principais de armazenar os metadados de um NFT.</p><p>Primeiro, você pode armazenar as informações on-chain (em cadeia). Em outras palavras, você pode estender seu ERC-721 e armazenar os metadados no blockchain, o que pode ser caro.</p><p>O segundo método é usar <a href="https://docs.ipfs.io/concepts/what-is-ipfs/">IPFS</a>. A terceira maneira é simplesmente fazer com que sua API retorne o arquivo JSON.</p><p>O primeiro e o segundo métodos geralmente são os preferidos, pois você não pode modificar o arquivo JSON subjacente. Para o escopo deste projeto, optaremos pelo terceiro método.</p><p>Para um bom tutorial sobre como usar NFTs com IPFS, leia &nbsp;<a href="https://docs.alchemy.com/alchemy/tutorials/how-to-create-an-nft/how-to-mint-a-nft#step-4-configure-the-metadata-for-your-nft-using-ipfs">este artigo</a> da equipe Alchemy.</p><h2 id="o-que-vamos-construir">O que vamos construir</h2><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/emotionalshapes.png" class="kg-image" alt="emotionalshapes" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/emotionalshapes.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/emotionalshapes.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/emotionalshapes.png 1284w" sizes="(min-width: 720px) 720px" width="1284" height="1847" loading="lazy"></figure><p>Neste tutorial, criaremos e cunharemos nosso próprio NFT. O tutorial é simples para iniciantes e não requer nenhum conhecimento prévio da rede Ethereum ou de contratos inteligentes. Ainda assim, ter uma boa compreensão desses conceitos ajudará você a entender o que está acontecendo nos bastidores.</p><p>Em um próximo tutorial, construiremos um aplicativo em React para a web totalmente funcional, onde você poderá exibir e vender seus NFTs.</p><p><br>Se você está apenas começando com o desenvolvimento de dApps, comece lendo os <a href="https://ethereum.org/en/developers/docs/intro-to-ethereum/">tópicos principais</a> e assista a <a href="https://www.youtube.com/watch?v=M576WGiDBdQ">este curso incrível</a> de Patrick Collins.</p><p><em>Este projeto foi escrito intencionalmente com código de fácil compreensão e não é adequado para uso em produção.</em></p><h2 id="pr-requisitos">Pré-requisitos</h2><h3 id="metamask"><strong><strong>Metamask</strong></strong></h3><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-32.png" class="kg-image" alt="image-32" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/image-32.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/image-32.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/09/image-32.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-32.png 1990w" sizes="(min-width: 720px) 720px" width="1990" height="1364" loading="lazy"></figure><p>Precisamos de um endereço Ethereum para interagir com nosso contrato inteligente. Usaremos o <a href="https://metamask.io/">Metamask</a> como nossa carteira. É uma carteira virtual gratuita que gerencia seus endereços Ethereum. Vamos precisar dele para enviar e receber transações (leia mais sobre isso <a href="https://ethereum.org/en/developers/docs/transactions/">aqui</a>). Por exemplo, cunhar um NFT é uma transação.</p><p>Faça o download da extensão do Chrome e do aplicativo para dispositivos móveis. Precisaremos de ambos, pois a extensão do Chrome não exibe seus NFTs.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-34.png" class="kg-image" alt="image-34" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/image-34.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-34.png 680w" width="680" height="712" loading="lazy"></figure><p>Certifique-se de alterar a rede para "Ropsten Test Network" para fins de desenvolvimento. Você precisará de algum Eth para cobrir as taxas de implantação e cunhagem de seu NFT. Vá para o <a href="https://faucet.ropsten.be/">Ropsten Ethereum Faucet</a> e digite seu endereço. Você logo deverá ver alguns Eth de teste em sua conta do Metamask.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-35.png" class="kg-image" alt="image-35" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/image-35.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/image-35.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/09/image-35.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-35.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="554" loading="lazy"></figure><h3 id="alchemy"><strong><strong>Alchemy</strong></strong></h3><p>Para interagir com a rede Ethereum, você precisará estar conectado a um Ethereum Node.</p><p>Executar seu próprio Node e manter a infraestrutura é um projeto à parte. Felizmente, existem provedores do tipo <em>node-as-a-service </em> que hospedam a infraestrutura para você<strong>.</strong> Existem muitas opções, como Infura, BlockDaemon e Moralis. Usaremos a <a href="https://www.alchemy.com/">Alchemy</a> como nosso provedor de nodes.</p><p>Vá até o site deles, crie uma conta, escolha Ethereum como sua rede e crie seu aplicativo. Escolha Ropsten como sua rede.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-36.png" class="kg-image" alt="image-36" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/image-36.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/image-36.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/09/image-36.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-36.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1012" loading="lazy"></figure><p>No seu painel, clique em "ver detalhes" no seu aplicativo e, em seguida, clique em "ver chave". Salve sua chave http em algum lugar, pois precisaremos disso mais tarde.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-38.png" class="kg-image" alt="image-38" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/image-38.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/image-38.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/09/image-38.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-38.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="643" loading="lazy"></figure><h3 id="nodejs-npm"><strong><strong>NodeJS/NPM</strong></strong></h3><p>Usaremos NodeJS para o projeto. Se você não o tiver instalado, siga este <a href="https://www.freecodecamp.org/news/how-to-install-node-in-your-machines-macos-linux-windows/">tutorial</a> simples do freeCodeCamp (texto em inglês).</p><h2 id="inicialize-o-projeto"><strong><strong>Ini</strong>c<strong>ialize </strong>o<strong> projet</strong>o</strong></h2><p>No seu terminal, execute este comando para criar um novo diretório para seu projeto:</p><pre><code>mkdir nft-project
cd nft-project</code></pre><p>Agora, vamos criar outro diretório, ethereum/, dentro de nft-project/ e inicializá-lo com o <a href="https://hardhat.org/getting-started/">Hardhat</a>. O Hardhat é uma ferramenta de desenvolvimento que facilita a implantação e o teste do seu software Ethereum.</p><pre><code>mkdir ethereum
cd ethereum
npm init
</code></pre><p>Responda as perguntas como quiser. Em seguida, execute esses comandos para criar um projeto Hardhat:</p><pre><code>npm install --save-dev hardhat
npx hardhat</code></pre><p>Você verá este prompt:</p><pre><code>888    888                      888 888               888
888    888                      888 888               888
888    888                      888 888               888
8888888888  8888b.  888d888 .d88888 88888b.   8888b.  888888
888    888     "88b 888P"  d88" 888 888 "88b     "88b 888
888    888 .d888888 888    888  888 888  888 .d888888 888
888    888 888  888 888    Y88b 888 888  888 888  888 Y88b.
888    888 "Y888888 888     "Y88888 888  888 "Y888888  "Y888

Welcome to Hardhat v2.0.8

? What do you want to do? …
  Create a sample project
❯ Create an empty hardhat.config.js
  Quit</code></pre><p>Selecione <em>Create an empty hardhat.config.js</em>. Isso gerará um arquivo vazio <code>hardhat.config.js</code> que atualizaremos posteriormente.</p><p>Para a aplicação da web, usaremos o Next.js para inicializar uma aplicação da web totalmente funcional. Volte para o diretório raiz <code>nft-project/</code> e inicialize um <em>boilerplate</em> do Next.js app, chamado <code>web</code>:</p><pre><code>cd ..
mkdir web
cd web
npx create-next-app@latest</code></pre><p>Seu projeto, agora, tem esta aparência:</p><pre><code>nft-project/
	ethereum/
	web/</code></pre><p>Ótimo! Estamos prontos para entrar na parte da programação de verdade.</p><h2 id="como-definir-nossas-vari-veis-env"><strong>Como definir nossas variáveis<strong> .env </strong></strong></h2><p>Você se lembra da chave de Alchemy que pegamos em nosso projeto de teste anterior? Nós a usaremos junto com as chaves públicas e privadas da nossa conta Metamask para interagir com o blockchain.</p><p>Execute os comandos a seguir, crie um arquivo chamado<code>.env</code> &nbsp;dentro do seu diretório <code>ethereum/</code>, e instale o <a href="https://www.npmjs.com/package/dotenv">dotenv</a>. Vamos usá-los mais tarde.</p><pre><code>cd ..
cd ethereum
touch .env
npm install dotenv --save</code></pre><p>Para o seu arquivo <code>.env</code>, &nbsp;coloque a chave que você exportou do Alchemy e <a href="https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key">siga estas instruções</a> para pegar a chave privada do seu Metamask.</p><p>Aqui está seu arquivo .env :</p><pre><code>DEV_API_URL = YOUR_ALCHEMY_KEY
PRIVATE_KEY = YOUR_METAMASK_PRIVATE_KEY
PUBLIC_KEY = YOUR_METAMASK_ADDRESS</code></pre><h2 id="o-smart-contract-para-nft">O Smart Contract para NFT</h2><p>Na pasta <code>ethereum/</code> crie mais dois diretórios: <code>contracts</code> e <code>scripts</code>. Um projeto hardhat simples contém essas pastas. </p><ul><li><code>contracts/</code> contém os arquivos de origem de seus contratos</li><li><code>scripts/</code> contém os scripts para implantar e cunhar nossos NFTs</li></ul><pre><code>mkdir contracts
mkdir scripts
</code></pre><p>Então, instale o OpenZeppelin. O <a href="https://docs.openzeppelin.com/contracts/4.x/">OpenZeppelin Contract</a> é uma biblioteca de código aberto com código reutilizável pré-testado para facilitar o desenvolvimento dos Smart Contracts (contratos inteligentes).</p><pre><code>npm install @openzeppelin/contracts</code></pre><p>Por fim, escreveremos o Smart Contract para o nosso NFT. Navegue até o diretório de contratos e crie um arquivo intitulado <code>EmotionalShapes.sol</code>. &nbsp;Você pode nomear seus NFTs como achar melhor.</p><p>A extensão <code>.sol</code> &nbsp;refere-se à linguagem Solidity, que usaremos para programar nosso Smart Contract. Escreveremos apenas 14 linhas de código com o Solidity. Então, não se preocupe se você ainda não viu isso antes.<br>Comece com <a href="https://ethereum.org/en/developers/docs/smart-contracts/languages/">este artigo</a> para saber mais sobre as linguagens de<strong> </strong>Smart Contract<strong>.</strong> Você também pode pular diretamente <a href="https://reference.auditless.com/cheatsheet/">para esta ficha informativa</a> do Solidity, que contém a sintaxe principal.</p><pre><code>cd contracts
touch EmotionalShapes.sol</code></pre><p>Este é o nosso Smart Contract:</p><pre><code class="language-solidity">// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract EmotionalShapes is ERC721 {
    using Counters for Counters.Counter;
    Counters.Counter private _tokenIdCounter;

    constructor() ERC721("EmotionalShapes", "ESS") {}

    function _baseURI() internal pure override returns (string memory) {
        return "YOUR_API_URL/api/erc721/";
    }

    function mint(address to)
        public returns (uint256)
    {
        require(_tokenIdCounter.current() &lt; 3); 
        _tokenIdCounter.increment();
        _safeMint(to, _tokenIdCounter.current());

        return _tokenIdCounter.current();
    }
}
</code></pre><p>Vamos passar pelo código e entender o que está acontecendo.</p><ol><li>Na parte superior do arquivo, especificamos qual módulo do OpenZeppelin importar. Precisamos do contrato ERC721, pois é a 'base' do nosso Smart Contract. Ele já implementou todos os métodos especificados no <a href="https://eips.ethereum.org/EIPS/eip-721">EIP-721</a> para que possamos usá-lo com segurança.</li><li>Um contador é útil para gerar ids incrementais para nossos NFTs. Nós nomeamos a variável <code>_tokenIdCounter</code></li><li>No construtor, inicializamos nosso ERC721 com seu nome e seu símbolo. Eu escolhi EmotionalShapes e ESS.</li><li>Substituímos a função padrão <em><code>baseURI</code>, </em>retornando a nossa. Vamos começar a construir isso logo após. Em resumo, é o URL que será adicionado como 'prefixo' a todos os nossos tokenURIs. No exemplo acima, os metadados de nossos NFTs ficarão em um arquivo JSON em<em> </em><code>URL_DA_SUA_API/<a href="https://e110-99-121-58-31.ngrok.io/api/erc721/">api/erc721/</a>1</code>. &nbsp;</li><li>Implementamos a função 'mint'. É a função que permite publicar uma instância desse Smart Contract no blockchain. Eu exigi que a variável <code>_tokenIdCounter</code> fosse menor que 3, pois criarei apenas três instâncias do meu NFT. Você pode remover isso se quiser cunhar mais.</li><li>Finalmente, dentro da função mint, incrementamos a variável <code>_tokenIdCounter</code> em 1. Então, nosso id será 1, seguido de 2, depois de 3. Então, chamamos a função fornecida pelo OpenZeppelin <code>_safeMint</code> para publicar o token.</li></ol><p>Não se preocupe se você se sentir perdido. Você pode participar de um workshop liderado por voluntários do freeCodeCamp, onde convidamos desenvolvedores de níveis de habilidade semelhantes para construir coisas juntos, incluindo esse projeto de NFT.</p><p>Os eventos são gratuitos e remotos, então você pode tirar qualquer dúvida diretamente. Você pode se registrar <a href="https://equia.io/">aqui</a>. As vagas são limitadas, então você será convidado para os próximos eventos disponíveis.</p><h2 id="como-criar-os-metadados-para-nosso-nft"><strong>Como criar os<strong> </strong>m<strong>etada</strong>dos<strong> </strong>para nosso<strong> NFT</strong></strong></h2><p>Como mencionado anteriormente, existem três maneiras principais de armazenar seu tokenURI. Construiremos um endpoint de API simples <strong>que resolve as informações do nosso NFT como JSON.</strong></p><p>Nosso projeto do Next.js nos oferece uma maneira prática de desenvolver rotas de API. Vá para a pasta <code>web/</code>, encontre a pasta <code>api/</code> dentro da pasta <code>pages/</code> &nbsp;e faça nossa rota dinâmica <code>[id].js</code> em uma pasta <code>erc721/</code> &nbsp;(leia mais sobre roteamento &nbsp;<a href="https://www.freecodecamp.org/news/p/18513919-9e93-4ab3-9f52-2448aafa8835/develop%20API%20routes">aqui</a>):</p><pre><code class="language-javascript">// web/pages/api/erc721/[id].js

const metadata = {
  1: {
    attributes: [
      {
        trait_type: "Shape",
        value: "Circle",
      },
      {
        trait_type: "Mood",
        value: "Sad",
      },
    ],
    description: "A sad circle.",
    image: "https://i.imgur.com/Qkw9N0A.jpeg",
    name: "Sad Circle",
  },
  2: {
    attributes: [
      {
        trait_type: "Shape",
        value: "Rectangle",
      },
      {
        trait_type: "Mood",
        value: "Angry",
      },
    ],
    description: "An angry rectangle.",
    image: "https://i.imgur.com/SMneO6k.jpeg",
    name: "Angry Rectangle",
  },
  3: {
    attributes: [
      {
        trait_type: "Shape",
        value: "Triangle",
      },
      {
        trait_type: "Mood",
        value: "Bored",
      },
    ],
    description: "An bored triangle.",
    image: "https://i.imgur.com/hMVRFoJ.jpeg",
    name: "Bored Triangle",
  },
};

export default function handler(req, res) {
  res.status(200).json(metadata[req.query.id] || {});
}</code></pre><p>Para fins deste projeto, tornei o código o mais fácil de entender possível. Isso definitivamente não é adequado para produção (por favor, não use um URL do Imgur para o seu NFT). Certifique-se de definir os metadados para todos os NFTs que você pretende cunhar.</p><p>Agora, vá para o diretório da web e inicie seu aplicativo Next.js com este comando:</p><pre><code>npm run dev</code></pre><p>Sua aplicação deve ser executada no localhost:3000. Para garantir que nosso endpoint funcione, vá para <a href="http://localhost:3000/api/erc721/1">http://localhost:3000/api/erc721/1</a> e ele deve ser resolvido com um objeto JSON dos metadados do seu primeiro NFT.</p><h2 id="como-expor-os-metadados-para-nosso-nft">Como expor os metadados para nosso NFT</h2><p>Como nossa aplicação está hospedada localmente, outras aplicações não podem acessá-la. Usando uma ferramenta como o <a href="https://ngrok.com/">ngrok</a>, podemos expor nosso host local a um URL acessível publicamente.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-39.png" class="kg-image" alt="image-39" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/image-39.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/image-39.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/09/image-39.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/image-39.png 2000w" sizes="(min-width: 720px) 720px" width="2000" height="1057" loading="lazy"></figure><ol><li>Vá para <a href="https://ngrok.com/">ngrok.com</a> e complete o processo de registro</li><li>Descompacte o pacote baixado</li><li>No seu terminal, certifique-se que você executou o comando <code>cd</code> na pasta que você descomprimiu seu pacote do ngrok</li><li>Siga as instruções do painel de controle e execute </li></ol><pre><code>./ngrok authtoken SEU_TOKEN_DE_AUTENTICACAO</code></pre><p>5. &nbsp;Então, execute este comando para criar um túnel para sua aplicação da web, hospedada em localhost:3000</p><pre><code>./ngrok http 3000</code></pre><p>6. &nbsp;Você está quase lá! Em seu terminal, você deverá ver algo como isto:</p><pre><code>ngrok by @inconshreveable                                                                            (Ctrl+C to quit)
                                                                                                                     
Session Status                online                                                                                 
Account                       YOUR_ACCOUNT (Plan: Free)                                                                       
Version                       2.3.40                                                                                 
Region                        United States (us)                                                                     
Web Interface                 http://127.0.0.1:4040                                                                  
Forwarding                    http://SEU_ENDERECO_DO_NGROK -&gt; http://localhost:3000                             
Forwarding                    https://SEU_ENDERECO_DO_NGROK -&gt; http://localhost:3000                             </code></pre><p>Vá para &nbsp;<code>SEU_ENDERECO_DO_NGROK/api/erc721/1</code> para ter certeza que o endpoint funciona corretamente.</p><h2 id="como-fazer-o-deploy-de-nosso-nft"><strong>Como fazer o d<strong>eploy </strong>de nosso<strong> NFT</strong></strong></h2><p>Agora que fizemos todo o trabalho de base (ufa), vamos voltar para nossa pasta e &nbsp;<code>ethereum/</code> e nos preparar para implantar nosso &nbsp;NFT.</p><p>Mude a função <code>_baseURI</code> no seu arquivo <code>ethreum/contracts/NOME_DO_SEU_NFT.sol</code> para retornar ao seu endereço do ngrok.</p><pre><code>// ethereum/conrtacts/EmotionalShapes.sol

contract EmotionalShapes is ERC721 {
...
	function _baseURI() internal pure override returns (string memory) {
		return "https://SEU_ENDERECO_DO_NGROK/api/erc721/";
	}
...
}</code></pre><p>Para fazer o deploy do nosso NFT, precisamos primeiro <a href="https://hardhat.org/guides/compile-contracts.html">compilá-lo usando Hardhat</a>. Para que o processo seja mais fácil, instalaremos o <a href="https://docs.ethers.io/v5/">ethers.js</a>.</p><pre><code>npm install @nomiclabs/hardhat-ethers --save-dev</code></pre><p>Vamos atualizar nosso hardhat.config.js:</p><pre><code>require("dotenv").config();
require("@nomiclabs/hardhat-ethers");

module.exports = {
  solidity: "0.8.0",
  defaultNetwork: "ropsten",
  networks: {
    hardhat: {},
    ropsten: {
      url: process.env.DEV_API_URL,
      accounts: [`0x${process.env.PRIVATE_KEY}`],
    },
  },
};
</code></pre><p>Para saber mais sobre a configuração do arquivo hardhat dê uma olhada na sua &nbsp;<a href="https://hardhat.org/config/">documentação</a>. Configuramos a rede ropsten com nosso URL do Alchemy e fornecemos a chave privada de sua conta do metamask.</p><p>Finalmente, execute:</p><pre><code>npx hardhat compile</code></pre><p>Isto permite que o hardhat gere dois arquivos por contrato compilado. Devemos ver uma pasta recém-criada <code>artifacts/</code>, que contém seus contratos compilados na pasta <code>contracts/</code>. Para saber mais sobre como isso funciona, leia <a href="https://hardhat.org/guides/compile-contracts.html">este tutorial</a> da equipe do Hardhat.</p><p>Agora, vamos escrever um script para finalmente implantar nosso NFT na rede de teste. Na pasta <code>scripts/</code> , crie um arquivo chamado <code>deploy.js</code>.</p><pre><code class="language-javascript">// ethereum/scripts/deploy.js

async function main() {
  const EmotionalShapes = await ethers.getContractFactory("EmotionalShapes");
  const emotionalShapes = await EmotionalShapes.deploy();

  console.log("EmotionalShapes deployed:", emotionalShapes.address);
}

main()
  .then(() =&gt; process.exit(0))
  .catch((error) =&gt; {
    console.error(error);
    process.exit(1);
  });
</code></pre><p>Este código é &nbsp;inspirado pelo <a href="https://hardhat.org/guides/deploying.html">tutorial de deploy do hardhat</a>.</p><blockquote>Uma <code>ContractFactory</code> em ethers.js é uma abstração usada para implantar novos contratos inteligentes, então <code>EmotionalShapes</code> aqui é uma factory para instâncias do nosso contrato de token. Invocar <code>deploy()</code> na <code>ContractFactory</code> iniciará o deploy e retornará uma <code>Promise</code> que então é resolvida para <code>Contract</code>. Este é o objeto que possui um método para cada uma de suas funções de contrato inteligente.</blockquote><h3 id="como-visualizar-o-nft-no-blockchain">Como visualizar o NFT no blockchain</h3><p>Execute o script de deploy:</p><pre><code>node ./scripts/deploy.js</code></pre><p>Você deverá ver em seu terminal <code>EmotionalShapes deployed: UM_ENDERECO</code>. Este é o endereço onde seu Smart Contract está implantado na rede de teste ropsten.</p><p>Se você for para <code>https://ropsten.etherscan.io/address/UM_ENDERECO</code>, você deve ver seu NFT recém-implantado. Sim! Você conseguiu!</p><p>Se você estiver confuso em algum ponto do tutorial ou se sentindo perdido, novamente, pode <a href="https://equia.io/">participar de nossos workshops ao vivo</a>, onde construiremos este projeto juntos em uma chamada de Zoom.</p><h2 id="como-cunhar-seu-nft">Como cunhar seu NFT</h2><p>Agora que você fez o deploy do seu NFT, é hora de cunhá-lo para você! Crie um novo arquivo chamado <code>mint.js</code> na sua pasta <code>scripts/</code>.Usaremos o ethers.js para nos auxiliar.</p><p>Comece adicionando o pacote <code>ethers.js</code> :</p><pre><code>npm install --save ethers</code></pre><p>Em seguida, preencha o arquivo <code>mint.js</code> :</p><pre><code class="language-javascript">require("dotenv").config();
const { ethers } = require("ethers");

const contract = require("../artifacts/contracts/EmotionalShapes.sol/EmotionalShapes.json");
const contractInterface = contract.abi;

// https://docs.ethers.io/v5/api/providers
const provider = ethers.getDefaultProvider("ropsten", {
  alchemy: process.env.DEV_API_URL,
});

// https://docs.ethers.io/v5/api/signer/#Wallet
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);

//https://docs.ethers.io/v5/api/contract/contract
const emotionalShapes = new ethers.Contract(
  YOUR_NFT_ADDRESS,
  contractInterface,
  wallet
);

const main = () =&gt; {
  emotionalShapes
    .mint(process.env.PUBLIC_KEY)
    .then((transaction) =&gt; console.log(transaction))
    .catch((e) =&gt; console.log("something went wrong", e));
};

main();
</code></pre><p>Eu deixei comentários para onde você pode encontrar mais informações sobre os diferentes métodos. Primeiro, pegamos a interface do contrato (ABI). Na ethereum.org, vemos que:</p><blockquote>Uma interface binária de aplicativo, ou ABI, é a maneira padrão de interagir com contratos no ecossistema Ethereum, tanto de fora do blockchain quanto para interações contrato a contrato.</blockquote><p>Sua ABI define como os outros interagem com seu contrato. Então, criamos nosso provedor com Alchemy (lembre-se dos node-as-a-service). Por fim, inicializamos nossa carteira com nossa chave privada.</p><p>A função &nbsp;<code>main()</code> executa o método <code>mint</code> no Smart Contract que acabamos de implementar. O método <code>mint</code> recebe apenas um parâmetro, <code>to</code>, que indica o receptor do token. Como estamos cunhando para nós mesmos, colocamos o endereço público da nossa conta Metamask.</p><p>Se tudo correr bem, você deverá ver a transação registrada em seu terminal. Pegue a propriedade <code>hash</code> vá para <code>https://ropsten.etherscan.io/tx/SEU_HASH</code>. Você deve ver a transação de cunhagem lá!</p><h2 id="como-visualizar-o-nft-em-sua-carteira-metamask">Como visualizar o NFT em sua carteira Metamask</h2><p>Você precisa começar baixando a versão móvel do Metamask. Em seguida, faça login na sua conta.</p><p>Você deve ver uma guia de NFTs junto com um botão <em>Add NFT</em>. Clique no botão e insira o endereço do seu Smart Contract junto com os ids que você cunhou. Se você seguiu o tutorial, você deve começar com um id de <code>1</code>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/IMG_0376.jpeg" class="kg-image" alt="IMG_0376" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/IMG_0376.jpeg 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/IMG_0376.jpeg 1000w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/IMG_0376.jpeg 1284w" sizes="(min-width: 720px) 720px" width="1284" height="2778" loading="lazy"><figcaption>Veja os NFTs em sua carteira do Metamask</figcaption></figure><h2 id="conclus-o"><strong><strong>Conclus</strong>ão</strong></h2><p>Parabéns! Você acabou de cunhar seu próprio NFT. Na próxima parte do projeto, construiremos o aplicativo em React para o front-end que interaja com nosso contrato. O objetivo final é construir um aplicativo da web totalmente funcional onde você possa vender seus próprios NFTs.</p><p>Por fim, você pode &nbsp;<a href="https://equia.io/">participar de nossos workshops</a> ao vivo com voluntários do freeCodeCamp, onde construiremos este projeto junto com outros.</p><p>Os eventos são gratuitos para todos em qualquer lugar do mundo e os convites são enviados por ordem de chegada. Se você gostaria de liderar os workshops, envie uma mensagem <a href="https://twitter.com/aly4alyssa">no Twitter</a>, adoraríamos contar com você! Também organizamos outros tipos de eventos como feiras de contratação e encontros sociais.</p><p>Gostaria de saber o que você quer criar. Os NFTs ainda estão em seus estágios iniciais e novas ideias são mais do que bem-vindas. Mal posso esperar para ver que ideia maluca você tem!</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Git Reset para Remote Head – como redefinir uma branch remota para a origem ]]>
                </title>
                <description>
                    <![CDATA[ A ramificação é um conceito central no Git. Ela pode ajudá-lo a configurar um fluxo de trabalho distribuído para colaboração em equipe e tornar seu processo de desenvolvimento mais eficiente. Quando você está usando o controle de versão e distribuindo recursos entre branches, há muita comunicação entre seu computador local ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/git-reset-para-remote-head-como-redefinir-uma-branch-remota-para-a-origem/</link>
                <guid isPermaLink="false">62ffef26714c9406b66270cf</guid>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paula Flávia Pagotto Simionato ]]>
                </dc:creator>
                <pubDate>Wed, 14 Sep 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/article-banner--1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/git-reset-to-remote-head-how-to-reset-a-remote-branch-to-origin/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Git Reset to Remote Head – How to Reset a Remote Branch to Origin</a>
      </p><p>A ramificação é um conceito central no Git. Ela pode ajudá-lo a configurar um fluxo de trabalho distribuído para colaboração em equipe e tornar seu processo de desenvolvimento mais eficiente.</p><p>Quando você está usando o controle de versão e distribuindo recursos entre branches, há muita comunicação entre seu computador local e seu repositório on-line no GitHub. Durante esse processo, talvez seja necessário redefinir a cópia original do projeto.</p><p>Se redefinir uma ramificação (em inglês, <em>branch</em>) assusta você, não se preocupe – este artigo apresentará <em>branches</em> remotas, <em>remote head</em> e como você pode redefinir facilmente uma <em>branch</em> remota para <em>remote head</em>.</p><h2 id="pr-requisitos"><strong><strong><strong><strong>Pr</strong></strong></strong>é-<strong><strong><strong>requisit</strong></strong></strong>o<strong><strong><strong>s</strong></strong></strong></strong></h2><ul><li>Conhecimento básico de como usar um terminal.</li><li>Git instalado (aprenda <a href="https://www.freecodecamp.org/portuguese/news/git-clone-branch-como-clonar-um-branch-especifico/">como instalar Git aqui</a>, caso ainda não o tenha instalado).</li><li>Conhecimento básico de GitHub e repositórios.</li><li>Um sorriso em seu rosto. 😉</li></ul><h2 id="o-que-uma-branch-no-git"><strong>O que é uma<strong> </strong>b<strong>ranch n</strong>o<strong> Git?</strong></strong></h2><p>Uma <em>branch</em> é um conceito central no Git e no GitHub que você usará o tempo todo. As <em>branches</em> ajudam você a gerenciar diferentes versões de um projeto.</p><p>A <em>branch </em><code>main</code> &nbsp;é sempre a <em>branch</em> padrão em um repositório e é considerada o "código de produção e implementável". Você pode criar novas <em>branches </em>como <code>prod-staging</code> ou <code>prod-current</code> a partir da <em>branch </em><code>main</code>.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot-2021-02-27-at-7.19.26-PM.png" class="kg-image" alt="Screenshot-2021-02-27-at-7.19.26-PM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screenshot-2021-02-27-at-7.19.26-PM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screenshot-2021-02-27-at-7.19.26-PM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/09/Screenshot-2021-02-27-at-7.19.26-PM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot-2021-02-27-at-7.19.26-PM.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1274" loading="lazy"><figcaption>Todas as branches em https://github.com/freeCodeCamp/freeCodeCamp</figcaption></figure><h3 id="o-que-uma-branch-remota-no-git"><strong>O que é uma branch remota no<strong> Git?</strong></strong></h3><p>Uma<strong> branch remota</strong> é uma referência ao estado das <em>branches </em>em um repositório remoto (uma versão do seu projeto hospedada na internet ou em uma rede como o GitHub).</p><p>Quando você clona um repositório, você extrai dados de um repositório na Internet ou de um servidor interno conhecido como <strong>remote</strong> (algo como <code>(remote)/(branch)</code>).</p><h2 id="o-que-origin-ou-remote-head-no-git"><strong>O que é<strong> </strong>o<strong>rigin (o</strong>u<strong> </strong>r<strong>emote </strong>h<strong>ead) n</strong>o<strong> Git?</strong></strong></h2><p>A palavra <em>origin</em> é um alias que o Git criou para substituir o URL remoto de um repositório remoto. Ele representa a <em>branch</em> padrão em um repositório remoto e é uma referência local que representa uma cópia local do HEAD no repositório remoto.</p><p><br>Em resumo, origin/HEAD representa a <em>branch</em> padrão no repositório remoto, que é definida automaticamente quando você clona um repositório da Internet.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot-2021-03-08-at-8.23.47-AM.png" class="kg-image" alt="Screenshot-2021-03-08-at-8.23.47-AM" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/09/Screenshot-2021-03-08-at-8.23.47-AM.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1000/2022/09/Screenshot-2021-03-08-at-8.23.47-AM.png 1000w, https://www.freecodecamp.org/portuguese/news/content/images/size/w1600/2022/09/Screenshot-2021-03-08-at-8.23.47-AM.png 1600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/09/Screenshot-2021-03-08-at-8.23.47-AM.png 2000w" sizes="(min-width: 1200px) 1200px" width="2000" height="1274" loading="lazy"></figure><h2 id="como-redefinir-uma-branch-remota-para-origin-no-git"><strong>Como redefinir uma branch remota para origin no Git </strong></h2><p>Agora que você tem conhecimento prévio de como os repositórios remotos e <em>branches </em>funcionam, vamos resolver nosso problema e redefinir uma <em>branch </em>remota para a origem usando o comando <code>git reset --hard</code> .</p><p>Antes de fazer isso (se for a primeira vez), certifique-se de fazer back-up de sua <em>branch</em> antes de redefini-la caso algo dê errado. Você pode fazer back-up assim:</p><pre><code class="language-bash">git commit -a -m "Branch de back-up"
git branch branch-backup</code></pre><p>Agora, execute o comando abaixo para redefinir sua <em>branch</em> remota para a origem. Se você tiver um nome de <em>branch</em> remota e padrão diferente (que não seja <code>origin</code> ou <code>main</code>, respectivamente), basta substituí-los pelo nome apropriado.</p><pre><code class="language-bash">git fetch origin
git reset --hard origin/main</code></pre><p>Se você criou alguns arquivos ou diretórios novos, eles ainda podem permanecer após a redefinição. Você pode usar o comando abaixo para limpar a árvore de trabalho removendo recursivamente os arquivos da ramificação anterior que não estão sob controle de versão.</p><pre><code>git clean -xdf</code></pre><ul><li>A <em>flag</em> <code>-x</code> &nbsp; remove todos os arquivos não rastreados, incluindo diretórios de compilação ignorados.</li><li>A <em>flag</em> <code>-d</code> &nbsp;permite que o Git verifique recursivamente diretórios não rastreados quando nenhum caminho for especificado.</li><li>A <em>flag</em> <code>-f</code> &nbsp; substitui a configuração de limpeza padrão do Git e inicia a limpeza de arquivos e diretórios não rastreados.</li></ul><h2 id="conclus-o"><strong><strong>Conclus</strong>ão</strong></h2><p>Se o nome do seu repositório remoto não for "origin" e se a <em>branch</em> nomeada não for "main" no repositório remoto, não se esqueça de atualizar os comandos acima com os nomes apropriados. Você sempre pode executar &nbsp;<code>git remote show origin</code> para verificar isso.</p><p>Espero que este artigo tenha deixado você mais à vontade para trabalhar com <em>branches </em>e redefini-las. Não se esqueça ingressar no novo servidor de bate-papo do freeCodeCamp para interagir com outros alunos e fazer perguntas. Obrigado pela leitura! 💙</p> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como fazer sua aplicação em React Native responder normalmente quando o teclado aparecer ]]>
                </title>
                <description>
                    <![CDATA[ por Spencer Carli Quando você está trabalhando com aplicações do React Native, um problema comum é que o teclado aparecerá e ocultará as entradas de texto quando você focar nelas. Algo assim: Existem algumas maneiras de evitar isso. Algumas são simples, outras nem tanto. Algumas podem ser personalizadas. Outras, não. ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-fazer-sua-aplicacao-em-react-native-responder-normalmente-quando-o-teclado-aparecer/</link>
                <guid isPermaLink="false">62ecf8bdfea2f10707d6a5d2</guid>
                
                    <category>
                        <![CDATA[ React Native ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paula Flávia Pagotto Simionato ]]>
                </dc:creator>
                <pubDate>Thu, 08 Sep 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_gQEm5r-73VpwmSrHYRi0AQ.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/how-to-make-your-react-native-app-respond-gracefully-when-the-keyboard-pops-up-7442c1535580/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to make your React Native app respond gracefully when the keyboard pops up</a>
      </p><p>por Spencer Carli</p><p>Quando você está trabalhando com aplicações do React Native, um problema comum é que o teclado aparecerá e ocultará as entradas de texto quando você focar nelas. Algo assim:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_dcFgfha_NfuPIi4YqEnsmQ.gif" class="kg-image" alt="1_dcFgfha_NfuPIi4YqEnsmQ" width="368" height="674" loading="lazy"></figure><p>Existem algumas maneiras de evitar isso. Algumas são simples, outras nem tanto. Algumas podem ser personalizadas. Outras, não. Hoje, vou mostrar três maneiras diferentes de evitar o teclado no React Native.</p><blockquote>Eu coloquei todo o código-fonte para este tutorial <a href="https://github.com/spencercarli/react-native-keyboard-avoidance-examples">no Github</a>.</blockquote><h4 id="keyboardavoidingview"><strong><strong>KeyboardAvoidingView</strong></strong></h4><p>A solução mais simples e mais fácil de instalar é o <a href="https://facebook.github.io/react-native/docs/keyboardavoidingview.html">KeyboardAvoidingView</a>. É um componente central, mas também é bastante simples no que faz.</p><p>Você pode pegar o <a href="https://gist.github.com/spencercarli/8acb7208090f759b0fc2fda3394796f1">código de base</a>, que tem o teclado cobrindo as entradas, e atualizá-lo para que as entradas não sejam mais cobertas. A primeira coisa que você precisa fazer é substituir o contêiner <code>View</code> pelo <code>KeyboardAvoidingView</code> e, em seguida, adicionar uma prop <code>behavior</code> a ele. Se você olhar a documentação, verá que ela aceita três valores diferentes – altura, preenchimento, posição. Descobri que o preenchimento funciona da maneira mais previsível. Então, é isso que eu vou usar.</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">import React from 'react';
import { View, TextInput, Image, KeyboardAvoidingView } from 'react-native';
import styles from './styles';
import logo from './logo.png';

const Demo = () =&gt; {
  return (
    &lt;KeyboardAvoidingView
      style={styles.container}
      behavior="padding"
    &gt;
      &lt;Image source={logo} style={styles.logo} /&gt;
      &lt;TextInput
        placeholder="Email"
        style={styles.input}
      /&gt;
      &lt;TextInput
        placeholder="Username"
        style={styles.input}
      /&gt;
      &lt;TextInput
        placeholder="Password"
        style={styles.input}
      /&gt;
      &lt;TextInput
        placeholder="Confirm Password"
        style={styles.input}
      /&gt;
      &lt;View style={{ height: 60 }} /&gt;
    &lt;/KeyboardAvoidingView&gt;
  );
};

export default Demo;</code></pre><figcaption>KeyboardAvoidingView.js</figcaption></figure><p>Isso nos dá o resultado que se vê abaixo. Não é perfeito, mas pelo pouquíssimo trabalho que dá, é muito bom.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_YrvCTP6RN8zn7r7W1lJtuQ.gif" class="kg-image" alt="1_YrvCTP6RN8zn7r7W1lJtuQ" width="368" height="674" loading="lazy"></figure><p>Uma coisa a ser notada é que, na linha 30, você verá uma <code>View</code> que tem uma altura definida como 60px. Descobri que a Key Avoiding View não funciona com o último elemento e a configuração de preenchimento e margem (<em>padding</em> e <em>margin</em>, em inglês) não funcionou. Então, eu adicionei um novo elemento para "aumentar" tudo em alguns pixels.</p><p>A imagem na parte superior é empurrada para fora da visualização ao usar essa implementação simples. Eu vou mostrar como você pode consertar isso no final.</p><blockquote>Usuários do Android: descobri que essa é a melhor/única opção. Ao adicionar <code>android:windowSoftInputMode="adjustResize"</code> ao seu AndroidManifest.xml, o sistema operacional cuidará da maior parte do trabalho para você e o KeyboardAvoidingView cuidará do resto (<a href="https://gist.github.com/spencercarli/e1b9575c1c8845c2c20b86415dfba3db#file-androidmanifest-xml-L23">exemplo de AndroidManifest.xml</a>). O restante deste artigo provavelmente não se aplicará a você.</blockquote><h4 id="keyboard-aware-scrollview"><strong><strong>Keyboard Aware ScrollView</strong></strong></h4><p>A próxima opção é a <a href="https://github.com/APSL/react-native-keyboard-aware-scroll-view">react-native-keyboard-aware-scroll-view</a>, que oferece muito retorno pelo seu investimento. Nos bastidores, você estará usando ScrollView ou ListView para lidar com tudo (dependendo do componente que você escolher), o que torna a interação de rolagem bastante perfeita. O outro grande benefício desse pacote é que ele rolará para a entrada que está em foco, o que proporciona ao usuário uma experiência agradável.</p><p>O uso também é muito fácil — você só precisa trocar o contêiner <code>View</code>, começando novamente com o <a href="https://gist.github.com/spencercarli/8acb7208090f759b0fc2fda3394796f1">código de base</a>, e definir algumas opções. Aqui está o código, então eu vou descrevê-lo.</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">import React from 'react';
import { View, TextInput, Image } from 'react-native';
import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'
import styles from './styles';
import logo from './logo.png';

const Demo = () =&gt; {
  return (
    &lt;KeyboardAwareScrollView
      style={{ backgroundColor: '#4c69a5' }}
      resetScrollToCoords={{ x: 0, y: 0 }}
      contentContainerStyle={styles.container}
      scrollEnabled={false}
    &gt;
        &lt;Image source={logo} style={styles.logo} /&gt;
        &lt;TextInput
          placeholder="Email"
          style={styles.input}
        /&gt;
        &lt;TextInput
          placeholder="Username"
          style={styles.input}
        /&gt;
        &lt;TextInput
          placeholder="Password"
          style={styles.input}
        /&gt;
        &lt;TextInput
          placeholder="Confirm Password"
          style={styles.input}
        /&gt;
    &lt;/KeyboardAwareScrollView&gt;
  );
};

export default Demo;</code></pre><figcaption>KeyboardAwareScrollView.js</figcaption></figure><p>Primeiro, você deve definir a <em>backgroundColor</em> do ScrollView. Dessa maneira (como se você fosse reativar a rolagem), a <em>backgroundColor</em> será sempre a mesma. Em seguida, você deve dizer ao componente onde está a posição padrão para que, uma vez que o teclado seja fechado, ele volte a esse ponto - omitindo esse suporte, a visualização deve ficar presa no topo depois de fechar o teclado, assim.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_WzOzG3P9npDpHpFj896nXA.png" class="kg-image" alt="1_WzOzG3P9npDpHpFj896nXA" width="361" height="650" loading="lazy"></figure><p>Após a prop <em>resetScrollToCoords</em>, você deve definir o <em>contentContainerStyle</em> - que, basicamente, substitui os estilos de exibição que você tinha antes. A última coisa que estou fazendo é desabilitar a ScrollView da interação do usuário. Isso pode nem sempre fazer sentido para sua UI (interface do usuário) – como no caso de uma interface em que um usuário edita muitos campos de perfil – mas, para esta, faz muito sentido. O que não faz sentido é permitir que o usuário role manualmente, pois não há para onde rolar.</p><p>Combinando essas props, você obtém o seguinte resultado, que funciona muito bem.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_M64W128GRs8X2IaBbSv7sA.gif" class="kg-image" alt="1_M64W128GRs8X2IaBbSv7sA" width="368" height="674" loading="lazy"></figure><h4 id="keyboard-module"><strong><strong>Keyboard Module</strong></strong></h4><p>Esta é, de longe, a opção mais manual, mas é, também, a que dá mais controle. Você usará a biblioteca <em>Animated </em>para ajudar a proporcionar interações suaves, como você viu antes.</p><p>O módulo Keyboard, que não está documentado no site do React Native, permite que você escute eventos de teclado emitidos pelo dispositivo. Os eventos que você usará são <em>keyboardWillShow</em> e <em>keyboardWillHide</em>, que retornam o tempo de duração da animação e a posição final do teclado (entre outras informações).</p><blockquote>Se você estiver no Android, convém usar keyboardDidShow e o keyboardDidHide.</blockquote><p>Quando o evento <em>keyboardWillShow</em> for emitido, você definirá uma variável <em>animated</em> para a altura final do teclado e fará com que ela seja animada pela mesma duração da animação de rolagem do teclado. Em seguida, você usa esse valor de <em>animated</em> para definir o preenchimento na parte inferior do contêiner para aumentar todo o conteúdo.</p><p>Mostrarei o código em um momento, mas fazer o que descrevi acima nos deixa com a seguinte experiência.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_mOhomWU9OwZN8Kieq3Pezw.gif" class="kg-image" alt="1_mOhomWU9OwZN8Kieq3Pezw" width="368" height="674" loading="lazy"></figure><p>Eu quero consertar essa imagem desta vez. Para isso, você usará um valor animado para gerenciar a altura da imagem, que você ajustará quando o teclado for aberto. Aqui está o código.</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">import React, { Component } from 'react';
import { View, TextInput, Image, Animated, Keyboard } from 'react-native';
import styles, { IMAGE_HEIGHT, IMAGE_HEIGHT_SMALL} from './styles';
import logo from './logo.png';

class Demo extends Component {
  constructor(props) {
    super(props);

    this.keyboardHeight = new Animated.Value(0);
    this.imageHeight = new Animated.Value(IMAGE_HEIGHT);
  }

  componentWillMount () {
    this.keyboardWillShowSub = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow);
    this.keyboardWillHideSub = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide);
  }

  componentWillUnmount() {
    this.keyboardWillShowSub.remove();
    this.keyboardWillHideSub.remove();
  }

  keyboardWillShow = (event) =&gt; {
    Animated.parallel([
      Animated.timing(this.keyboardHeight, {
        duration: event.duration,
        toValue: event.endCoordinates.height,
      }),
      Animated.timing(this.imageHeight, {
        duration: event.duration,
        toValue: IMAGE_HEIGHT_SMALL,
      }),
    ]).start();
  };

  keyboardWillHide = (event) =&gt; {
    Animated.parallel([
      Animated.timing(this.keyboardHeight, {
        duration: event.duration,
        toValue: 0,
      }),
      Animated.timing(this.imageHeight, {
        duration: event.duration,
        toValue: IMAGE_HEIGHT,
      }),
    ]).start();
  };

  render() {
    return (
      &lt;Animated.View style={[styles.container, { paddingBottom: this.keyboardHeight }]}&gt;
        &lt;Animated.Image source={logo} style={[styles.logo, { height: this.imageHeight }]} /&gt;
        &lt;TextInput
          placeholder="Email"
          style={styles.input}
        /&gt;
        &lt;TextInput
          placeholder="Username"
          style={styles.input}
        /&gt;
        &lt;TextInput
          placeholder="Password"
          style={styles.input}
        /&gt;
        &lt;TextInput
          placeholder="Confirm Password"
          style={styles.input}
        /&gt;
      &lt;/Animated.View&gt;
    );
  }
};

export default Demo;</code></pre><figcaption>KeyboardModule.js</figcaption></figure><p>Certamente, há muito mais aqui do que nas outras soluções. Em vez de uma <code>View</code> ou <code>Image</code>, você está usando <code>Animated.View</code> e <code>Animated.Image</code> para que os valores de <em>animated</em> possam ser aproveitados. A parte divertida está realmente nas funções <em>keyboardWillShow</em> e <em>keyboardWillHide,</em> onde os valores de <em>animated</em> estão mudando.</p><p>O que está acontecendo é que os dois valores de <em>animated</em> estão mudando em paralelo, os quais estão sendo usados para orientar a interface do usuário. Isso deixa você com o resultado abaixo.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_Fj87SXCLXlkKsG7aAi_5mg.gif" class="kg-image" alt="1_Fj87SXCLXlkKsG7aAi_5mg" width="368" height="674" loading="lazy"></figure><p>É uma quantidade razoável de código, mas fica muito bom. Você tem muitas opções para o que pode fazer e pode realmente personalizar a interação para o conteúdo do seu coração.</p><h4 id="combinando-op-es">Combinando opções</h4><p>Se você quiser diminuir um pouco o código, pode combinar algumas opções, que é o que costumo fazer. Por exemplo, combinando a primeira e a terceira opções, você precisa apenas se preocupar em gerenciar e animar a altura da imagem. </p><p>O código não é muito menor do que a fonte da terceira opção, mas à medida que uma interface do usuário cresce em complexidade, ele pode ajudá-lo um pouco mais.</p><figure class="kg-card kg-code-card"><pre><code class="language-jsx">import React, { Component } from 'react';
import { View, TextInput, Image, Animated, Keyboard, KeyboardAvoidingView } from 'react-native';
import styles, { IMAGE_HEIGHT, IMAGE_HEIGHT_SMALL } from './styles';
import logo from './logo.png';

class Demo extends Component {
  constructor(props) {
    super(props);

    this.imageHeight = new Animated.Value(IMAGE_HEIGHT);
  }

  componentWillMount () {
    this.keyboardWillShowSub = Keyboard.addListener('keyboardWillShow', this.keyboardWillShow);
    this.keyboardWillHideSub = Keyboard.addListener('keyboardWillHide', this.keyboardWillHide);
  }

  componentWillUnmount() {
    this.keyboardWillShowSub.remove();
    this.keyboardWillHideSub.remove();
  }

  keyboardWillShow = (event) =&gt; {
    Animated.timing(this.imageHeight, {
      duration: event.duration,
      toValue: IMAGE_HEIGHT_SMALL,
    }).start();
  };

  keyboardWillHide = (event) =&gt; {
    Animated.timing(this.imageHeight, {
      duration: event.duration,
      toValue: IMAGE_HEIGHT,
    }).start();
  };

  render() {
    return (
      &lt;KeyboardAvoidingView
        style={styles.container}
        behavior="padding"
      &gt;
          &lt;Animated.Image source={logo} style={[styles.logo, { height: this.imageHeight }]} /&gt;
          &lt;TextInput
            placeholder="Email"
            style={styles.input}
          /&gt;
          &lt;TextInput
            placeholder="Username"
            style={styles.input}
          /&gt;
          &lt;TextInput
            placeholder="Password"
            style={styles.input}
          /&gt;
          &lt;TextInput
            placeholder="Confirm Password"
            style={styles.input}
          /&gt;
      &lt;/KeyboardAvoidingView&gt;
    );
  }
};

export default Demo;</code></pre><figcaption>Combo.js</figcaption></figure><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_g3clh5FFPJzBWt9egIY2cA.gif" class="kg-image" alt="1_g3clh5FFPJzBWt9egIY2cA" width="368" height="674" loading="lazy"></figure><p>Cada uma dessas implementações tem seus prós e contras – você terá que escolher a mais apropriada, de acordo com a experiência do usuário que deseja</p><blockquote>Quer aprender mais sobre como usar o React Native para criar aplicações para dispositivos móveis de alta qualidade? <a href="http://learn.handlebarlabs.com/p/react-native-basics-build-a-currency-converter">Inscreva-se no curso de React Native gratuito do autor</a>!</blockquote> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Como animar seu terminal do Bash - Um guia passo a passo com imagens ]]>
                </title>
                <description>
                    <![CDATA[ por rajaraodv Nesta publicação, vou mostrar os passos para adicionar temas, Powerline, fontes e powerline-gitstatus para tornar seu terminal convencional do Bash útil e bonito, como na imagem inicial. Se você estiver usando um Mac, precisará passar por muitos obstáculos para fazer isso funcionar, pois muitas das instruções são para ]]>
                </description>
                <link>https://www.freecodecamp.org/portuguese/news/como-animar-seu-terminal-do-bash-um-guia-passo-a-passo-com-imagens/</link>
                <guid isPermaLink="false">62e3d7c5fea2f10707d6819c</guid>
                
                    <category>
                        <![CDATA[ Terminal ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Paula Flávia Pagotto Simionato ]]>
                </dc:creator>
                <pubDate>Sun, 04 Sep 2022 21:00:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_QRJ9_60oCmcwRGfYqCbqSw.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>Artigo original:</strong> <a href="https://www.freecodecamp.org/news/jazz-up-your-bash-terminal-a-step-by-step-guide-with-pictures-80267554cb22/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">How to Jazz Up Your Bash Terminal — A Step By Step Guide With Pictures</a>
      </p><h3 id="por-rajaraodv">por rajaraodv</h3><p>Nesta publicação, vou mostrar os passos para adicionar temas, Powerline, fontes e powerline-gitstatus para tornar seu terminal convencional do Bash útil e bonito, como na imagem inicial.</p><p>Se você estiver usando um Mac, precisará passar por muitos obstáculos para fazer isso funcionar, pois muitas das instruções são para o Linux ou estão desatualizadas. Então, eu pensei em escrever sobre isso - espero que ajude você.</p><blockquote>Observações:<br><br>1. Siga os passos cuidadosamente, pois qualquer equivoco causará muita dor de cabeça.<br><br>2. Isso vale para o MacOS e para o Bash regular no Terminal.app. Não estou abrangendo o ZSH ou o Hyper neste artigo – pretendo escrever artigos diferentes para eles.<br><br>3. Minhas versões: Mac High Sierra; versão do git 2.14.3 (Apple Git-98); Python 2.7.10</blockquote><p>Certo, quando você tem um Mac novo, por padrão, seu Terminal.app será parecido com algo como a imagem abaixo. Então, vamos em frente e adicionar temas, fontes e assim por diante.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_A2RjRAGXHeUQtIIy5XIBwQ.png" class="kg-image" alt="1_A2RjRAGXHeUQtIIy5XIBwQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_A2RjRAGXHeUQtIIy5XIBwQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_A2RjRAGXHeUQtIIy5XIBwQ.png 800w" width="800" height="629" loading="lazy"></figure><h3 id="passo-1-adicionar-um-novo-tema"><strong>Passo<strong> 1 — </strong>Adicionar um novo tema</strong></h3><p>O primeiro passo óbvio é aprimorar o tema. O Terminal não fornece todos os temas legais e sofisticados que você vê outros desenvolvedores usarem. Vamos baixar um tema e adicioná-lo ao Terminal.</p><p>Neste blog, vou adicionar o tema Solarized-Dark ao Terminal.</p><blockquote>Observação: você pode baixar vários temas (.terminal files) deste repositório git. Basta abrir o arquivo &nbsp;<code><em><em>*.terminal</em></em></code> &nbsp;para instalá-lo, ou seja, clicar com o botão direito em <code><em><em>*.terminal file &gt; </em>"O<em>pen with" &gt;</em> terminal</em></code><em>.</em></blockquote><ol><li>Vá para <a href="http://ethanschoonover.com/solarized" rel="noopener">http://ethanschoonover.com/solarized</a> (texto em inglês)</li><li>Role o mouse até o tema (solarized.zip)</li><li>Extraia o arquivo solarized.zip </li><li>Abra a pasta &nbsp;<strong><strong>osx-terminal.app-colors-solarized</strong></strong> . Esta pasta contém o tema para o terminal.</li><li>Clique duas vezes no arquivo <em>"</em><strong><strong><em><em>Solarized Dark ansi.terminal</em></em></strong></strong><em>"</em><strong><strong> &nbsp;— </strong></strong>Este arquivo é o tema específico para Terminal.app. <em>Observação<em>: </em>caso você receba um aviso de que o arquivo é de um desenvolvedor não identificado<em>, </em> clique com o botão direito do mouse no arquivo e selecione Open with &gt; Terminal</em>.</li><li>Nesse momento, você já está com o tema instalado no terminal. Agora é necessário, apenas, torná-lo o tema padrão.</li><li>Abra o Terminal &gt; Preferences &gt; Text, selecione o tema &nbsp;"Solarized Dark …" e clique em "Default".</li></ol><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_0hPqERUbwhdAXVQfdQih1A.png" class="kg-image" alt="1_0hPqERUbwhdAXVQfdQih1A" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_0hPqERUbwhdAXVQfdQih1A.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_0hPqERUbwhdAXVQfdQih1A.png 800w" sizes="(min-width: 720px) 720px" width="800" height="707" loading="lazy"></figure><p>De agora em diante, seu terminal se parecerá como o da imagem abaixo.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_hvkwX_GZIXHQxuYY2987GQ.png" class="kg-image" alt="1_hvkwX_GZIXHQxuYY2987GQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_hvkwX_GZIXHQxuYY2987GQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_hvkwX_GZIXHQxuYY2987GQ.png 800w" sizes="(min-width: 720px) 720px" width="800" height="526" loading="lazy"></figure><h3 id="passo-2-instalar-o-powerline"><strong>Passo<strong> 2 — Instal</strong>ar o <strong>Powerline</strong></strong></h3><p>Powerline é uma aplicação do Python e é um plug-in de linha de status para o vim que fornece linhas de status e prompts para vários outros aplicativos, incluindo zsh, bash, tmux, IPython, Awesome e Qtile.</p><p>Ele faz com que o prompt do terminal se pareça como abaixo.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_7SLVI9-_IBwEcmZpGaDvmw.png" class="kg-image" alt="1_7SLVI9-_IBwEcmZpGaDvmw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_7SLVI9-_IBwEcmZpGaDvmw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_7SLVI9-_IBwEcmZpGaDvmw.png 800w" sizes="(min-width: 720px) 720px" width="800" height="360" loading="lazy"></figure><h4 id="2-1-instalar-python"><strong><strong>2.1 Instal</strong>ar<strong> Python</strong></strong></h4><p>Devido ao fato de o Powerline ser uma aplicação do Python, é necessário ter o Python instalado, bem como uma versão apropriada do Python.</p><ul><li>O MacOS já vem com Python instalado.<strong><strong> </strong>Assegure-se de que a versão do<strong> Python</strong> seja, pelo menos, a<strong> 2.7.x </strong>digitando<strong> </strong></strong><code>python -V</code> no terminal.</li><li>Caso não seja a versão 2.7, instale o <a href="https://brew.sh/" rel="noopener">Homebrew</a>, que permite instalar vários softwares de CLI (interface de comandos de linha), executando:<code>/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"</code></li><li>Execute <code>brew install python</code> para instalar a última versão do Python via Homebrew</li></ul><h4 id="2-2-instalar-o-pip-um-gerenciador-de-pacotes-para-python-similar-ao-npm-"><strong><strong>2.2 </strong>Instalar o <strong>pip —</strong> Um gerenciador de pacotes para<strong> Python (similar </strong>ao<strong> npm)</strong></strong></h4><p>Instale o pip executando o seguinte comando:</p><p><code>$ sudo easy_install pip</code></p><h4 id="2-3-instalar-ferramentas-de-desenvolvedor-para-a-cli-do-xcode"><strong><strong>2.3 Instal</strong>ar<strong> </strong>ferramentas de desenvolvedor para a CLI do XCode</strong></h4><p>As ferramentas de desenvolvedor para a CLI do XCode são usadas pelo Powerline e outras aplicações que que manipulam os principais recursos do OSX. Portanto, certifique-se de instalar as ferramentas da CLI do XCode executando o comando a seguir. </p><p><code>$ xcode-select —-install</code></p><blockquote>Observação: o comando acima abre o instalador do Mac e instala as ferramentas do desenvolvedor para CLI da &nbsp;XCode. Caso não funcione, tente: <code><em><em>xcode-select -r</em></em></code> para resetar.</blockquote><h4 id="2-4-instalar-o-powerline"><strong><strong>2.4 Instal</strong>ar o<strong> Powerline</strong></strong></h4><p>Finalmente, instale o Powerline (versão estável) com o pip executando o seguinte comando:</p><pre><code class="language-bash">$ pip install --user powerline-status</code></pre><p>Caso você queira instalar a última branch desenvolvida, execute o seguinte:</p><pre><code class="language-bash">$ pip install --user git+git://github.com/powerline/powerline  //dev</code></pre><h4 id="2-5-adicionar-o-powerline-daemon-ao-bash"><strong><strong>2.5 Ad</strong>icionar o P<strong>owerline daemon </strong>a<strong>o bash</strong></strong></h4><p>Agora, é preciso adicionar o Powerline daemon ao bash para que ele possa monitorar o prompt do Terminal e fazer alterações.</p><p><strong><strong>2.5.1</strong> Copie o local de instalação do Powerline</strong></p><p>Você pode encontrar o local da instalação do Powerline executando o seguinte comando: <code>pip show powerline-status</code>. Copie o valor do campo <code>Location</code>.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_1Hi5bB475XFf-Iu43tAFvA.png" class="kg-image" alt="1_1Hi5bB475XFf-Iu43tAFvA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_1Hi5bB475XFf-Iu43tAFvA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_1Hi5bB475XFf-Iu43tAFvA.png 800w" sizes="(min-width: 720px) 720px" width="800" height="183" loading="lazy"></figure><p><strong><strong>2.5.2 Ad</strong>icionar o <strong>daemon </strong>no local adequado para o<strong> .bash_profile</strong></strong></p><ol><li>Certifique-se de que você tem o arquivo <code>.bash_profile</code> no seu diretório raiz. Caso ele não exista, prossiga criando o arquivo digitando o comando: <code>cd ~ &amp;&amp; touch ~/.bash_profile</code></li></ol><p>2. Abra o <code>.bash_profile</code> &nbsp;e adicione o seguinte comando:</p><pre><code class="language-bash">export PATH=$PATH:$HOME/Library/Python/2.7/bin
powerline-daemon -q
POWERLINE_BASH_CONTINUATION=1
POWERLINE_BASH_SELECT=1
. /Users/rupa/Library/Python/2.7/lib/python/site-packages/powerline/bindings/bash/powerline.sh</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_QY-1dEQtAn6SUOpgOTQcsg.png" class="kg-image" alt="1_QY-1dEQtAn6SUOpgOTQcsg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_QY-1dEQtAn6SUOpgOTQcsg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_QY-1dEQtAn6SUOpgOTQcsg.png 800w" sizes="(min-width: 720px) 720px" width="800" height="159" loading="lazy"><figcaption>Alguns detalhes sobre bash_profile</figcaption></figure><blockquote><em><em>Not</em>a<em>: </em>o caminho<em> /Users/rupa/Library/Python/2.7/lib/python/site-packages/ </em>vem do passo anterior<em> (2.5.1). </em>Altere-o para se adequar ao caminho do seu computador.</em></blockquote><p><strong><strong>2.5.3. Re</strong>inicie o<strong> Terminal</strong></strong></p><p>Feche completamente o terminal, se estiver aberto: (Terminal &gt; Quit Terminal). Inicie o terminal novamente.</p><blockquote>Você deve poder usar <code><em><em>$ source ~/.bash_profile</em></em></code> para atualizar as configurações. Porém, recebe algo estranho como "o <code><em><em>powerline-config</em></em></code> está sem um arquivo!" Normalmente, você recebe esse erro se não tiver $HOME/Library/Python/2.7/bin em seu PATH.</blockquote><p><strong><strong>2.5.4 </strong>Seu novo terminal</strong></p><p>Seu novo terminal, agora, deve se parecer com a figura abaixo. Deve estar usando o tema "Solarized Dark ansi" &nbsp;e deve mostrar o Powerline no prompt de comando. Mas observe que também existe um caractere "?" ! Isso ocorre porque o Powerline usa vários ícones e fontes que não estão disponíveis por padrão. Então, precisamos instalar as fontes.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_fVqgdIqo7AIw7EJdcHZZxw-1.png" class="kg-image" alt="1_fVqgdIqo7AIw7EJdcHZZxw-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_fVqgdIqo7AIw7EJdcHZZxw-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_fVqgdIqo7AIw7EJdcHZZxw-1.png 800w" sizes="(min-width: 720px) 720px" width="800" height="473" loading="lazy"></figure><h3 id="passo-3-instalar-as-fontes-do-powerline"><strong>Passo<strong> 3 — Instal</strong>ar as fontes do<strong> Powerline </strong></strong></h3><p>Para instalar as fontes do Powerline, acesse: <a href="https://github.com/powerline/fonts" rel="noopener">https://github.com/powerline/fonts</a>. Lá, você verá diversas pastas. Cada uma é uma fonte, também conhecidas como "Fontes corrigidas" ("Patched fonts").</p><blockquote>São chamadas de “Fontes corrigidas” porque as pessoas usaram fontes regulares e adicionaram a elas, ou corrigiram nelas, ícones e fontes específicos do Powerline.</blockquote><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_sYBQZYzxe37bkmtBUw_Oww.png" class="kg-image" alt="1_sYBQZYzxe37bkmtBUw_Oww" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_sYBQZYzxe37bkmtBUw_Oww.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_sYBQZYzxe37bkmtBUw_Oww.png 800w" sizes="(min-width: 720px) 720px" width="800" height="398" loading="lazy"></figure><h4 id="3-1-baixar-o-reposit-rio-inteiro-e-descompact-lo"><strong><strong>3.1 </strong></strong>Baixar o repositório inteiro e descompactá-lo</h4><ul><li>Clique no botão "Clone or download" e baixe todo o repositório para experimentar várias fontes.</li><li>Descompacte o fonts-master.zip</li></ul><h4 id="3-2-instalar-algumas-fontes"><strong><strong>3.2 Instal</strong>ar<strong> </strong>algumas<strong> font</strong>e<strong>s</strong></strong></h4><p>Vamos abrir a pasta de fontes <strong><strong>Meslo dotted</strong></strong>. Ficará como abaixo. Você verá diversos arquivos .ttf. Cada um deles é uma fonte, mas alguns são a versão em "negrito" da fonte, alguns são a versão "regular" e assim por diante.</p><p>Basta clicar duas vezes no arquivo .ttf e pressionar "Install font" para instalar a fonte em seu computador.</p><p>Para o nosso caso, vamos instalar "Meslo LG L DZ Regular for Powerline.ttf" e "Meslo LG L DZ Italic for Powerline.ttf". Isso adicionará uma versão <strong><em>regular</em></strong> e uma versão <strong><em>itálica</em> </strong>da fonte <strong><em>Meslo.</em></strong></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_zmoF1ksmDJfRH0lGK00GKg.png" class="kg-image" alt="1_zmoF1ksmDJfRH0lGK00GKg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_zmoF1ksmDJfRH0lGK00GKg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_zmoF1ksmDJfRH0lGK00GKg.png 800w" sizes="(min-width: 720px) 720px" width="800" height="447" loading="lazy"></figure><h4 id="3-3-selecione-a-fonte-no-tema-do-terminal"><strong><strong>3.3 S</strong></strong>elecione a fonte no tema do Terminal</h4><p>Você lembra que adicionamos o tema "Solarized Dark" no passo 1? Não havia nenhuma fonte ali e o MacOS tem uma fonte padrão. Tudo o que precisamos fazer é definir nossa fonte <strong><strong>Meslo dotted</strong></strong> para este tema e pronto!</p><ol><li>Abra Terminal &gt; Preferences &gt; Text</li><li>Selecione o tema &nbsp;<strong><strong>Solarized Dark ansi </strong></strong></li><li>Clique no botão "Font" - Isso abre a caixa de diálogo "Fonts"</li><li>Na caixa de diálogo "Fonts", selecione "Meslo LG L DZ for Powerline" na Família e também selecione o tamanho da fonte 14 (para facilitar a leitura).</li></ol><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_SbKUVJxHJ_PR8yh2cbSESw.png" class="kg-image" alt="1_SbKUVJxHJ_PR8yh2cbSESw" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_SbKUVJxHJ_PR8yh2cbSESw.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_SbKUVJxHJ_PR8yh2cbSESw.png 800w" sizes="(min-width: 720px) 720px" width="800" height="359" loading="lazy"></figure><h4 id="3-4-reiniciar-o-terminal"><strong><strong>3.4 Re</strong>iniciar o t<strong>erminal</strong></strong></h4><p>Feche completamente o terminal (Terminal &gt; Quit Terminal) e reabra-o novamente.</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_5pfC372U2Uz9Q5SQJSqKzA.png" class="kg-image" alt="1_5pfC372U2Uz9Q5SQJSqKzA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_5pfC372U2Uz9Q5SQJSqKzA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_5pfC372U2Uz9Q5SQJSqKzA.png 800w" sizes="(min-width: 720px) 720px" width="800" height="713" loading="lazy"></figure><h3 id="passo-4-adicionando-informa-es-do-git-ao-prompt"><strong>Passo<strong> 4 — </strong></strong>Adicionando informações do Git ao prompt</h3><p>Para exibir vários status do Git no prompt, precisamos instalar o &nbsp;<a href="https://github.com/jaspernbrouwer/powerline-gitstatus" rel="noopener">powerline-gitstatus</a>, que é um complemento simples para o Powerline que adiciona várias cores e temas para exibir várias informações de status do git.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_NKRx9-fVCZIiWKW_Tb0lhA.png" class="kg-image" alt="1_NKRx9-fVCZIiWKW_Tb0lhA" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_NKRx9-fVCZIiWKW_Tb0lhA.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_NKRx9-fVCZIiWKW_Tb0lhA.png 800w" sizes="(min-width: 720px) 720px" width="800" height="192" loading="lazy"><figcaption>Trataremos dos arquivos nas pastas "color schemes" e "themes"</figcaption></figure><h4 id="4-1-instalar-o-powerline-gitstatus"><strong><strong>4.1 Instal</strong>ar o<strong> powerline-gitstatus</strong></strong></h4><pre><code class="language-bash">pip install --user powerline-gitstatus</code></pre><blockquote>Observação: o comando "—user" é necessário para instalá-lo no perfil do usuário. </blockquote><h4 id="4-2-adicionar-esquema-de-cores-powerline-gitstatus-ao-powerline"><strong><strong>4.2 Ad</strong>icionar esquema de cores<strong> powerline-gitstatus </strong>ao<strong> Powerline</strong></strong></h4><p>4.2.1 Abra a pasta <code>colorschemes/shell/default.json</code> </p><pre><code class="language-bash">${powerline-install-directory}/powerline/config_files/colorschemes/shell/default.json

//For example:
/Users/rupa/Library/Python/2.7/lib/python/site-packages/powerline/config_files/colorschemes/shell/default.json</code></pre><p>4.2.2 Adicione as cores abaixo:</p><p>Conforme é mencionado no arquivo <a href="https://github.com/jaspernbrouwer/powerline-gitstatus#installation">readme</a> do powerline-gitstatus. Apenas copie as cores dentro de "groups" e acrescente-as ao default.json, conforme mostrado abaixo.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_shKgrO87LFrjoGMb2uOEVg.png" class="kg-image" alt="1_shKgrO87LFrjoGMb2uOEVg" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_shKgrO87LFrjoGMb2uOEVg.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_shKgrO87LFrjoGMb2uOEVg.png 800w" width="800" height="348" loading="lazy"><figcaption>Texto em inglês: "Adicione as cores do git de primeiro e de segundo plano do powerline-gitstatus na parte inferior da seção 'groups'."</figcaption></figure><p>Aqui estão meus esquemas de cores do default.json (que você pode copiar e colar):</p><pre><code class="language-json">{
	"name": "Default color scheme for shell prompts",
	"groups": {
		"hostname": {
			"fg": "brightyellow",
			"bg": "mediumorange",
			"attrs": []
		},
		"environment": {
			"fg": "white",
			"bg": "darkestgreen",
			"attrs": []
		},
		"mode": {
			"fg": "darkestgreen",
			"bg": "brightgreen",
			"attrs": ["bold"]
		},
		"attached_clients": {
			"fg": "white",
			"bg": "darkestgreen",
			"attrs": []
		},

		"gitstatus": {
			"fg": "gray8",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_branch": {
			"fg": "gray8",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_branch_clean": {
			"fg": "green",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_branch_dirty": {
			"fg": "gray8",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_branch_detached": {
			"fg": "mediumpurple",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_tag": {
			"fg": "darkcyan",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_behind": {
			"fg": "gray10",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_ahead": {
			"fg": "gray10",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_staged": {
			"fg": "green",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_unmerged": {
			"fg": "brightred",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_changed": {
			"fg": "mediumorange",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_untracked": {
			"fg": "brightestorange",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus_stashed": {
			"fg": "darkblue",
			"bg": "gray2",
			"attrs": []
		},
		"gitstatus:divider": {
			"fg": "gray8",
			"bg": "gray2",
			"attrs": []
		}
	},
	"mode_translations": {
		"vicmd": {
			"groups": {
				"mode": {
					"fg": "darkestcyan",
					"bg": "white",
					"attrs": ["bold"]
				}
			}
		}
	}
}</code></pre><h4 id="4-3-ativar-o-tema"><strong><strong>4.3 A</strong>tivar o tema</strong></h4><p>4.3.1 Abra o arquivo do tema do default.json </p><pre><code class="language-bash">${powerline-install-directory}/powerline/config_files/themes/shell/default.json

//For example:
/Users/rupa/Library/Python/2.7/lib/python/site-packages/powerline/config_files/themes/shell/default.json</code></pre><p>4.3.2 Adicione o seguinte ao default.json</p><pre><code class="language-json">{
    "function": "powerline_gitstatus.gitstatus",
    "priority": 40
}</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_QJIvX5hfNpUWZgoHTQ_nbQ.png" class="kg-image" alt="1_QJIvX5hfNpUWZgoHTQ_nbQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_QJIvX5hfNpUWZgoHTQ_nbQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_QJIvX5hfNpUWZgoHTQ_nbQ.png 800w" sizes="(min-width: 720px) 720px" width="800" height="713" loading="lazy"><figcaption>Texto em inglês: "Adicione o powerline_gitstatus como o último segmento do lado 'esquerdo'."</figcaption></figure><p>Abaixo está o tema default.json do meu Powerline (você pode copiar e colar isso):</p><blockquote>Observação: eu removi tudo da seção "direita" e também removi o número da tarefa, ou "job number" ("jobnum"), para manter tudo limpo. Caso contrário, você veria um pequeno artefato na borda direita do prompt.</blockquote><pre><code class="language-json">{
	"segments": {
		"left": [{
				"function": "powerline.segments.shell.mode"
			},
			{
				"function": "powerline.segments.common.net.hostname",
				"priority": 10
			},
			{
				"function": "powerline.segments.common.env.user",
				"priority": 30
			},
			{
				"function": "powerline.segments.shell.cwd",
				"priority": 10
			}, {
				"function": "powerline_gitstatus.gitstatus",
				"priority": 40
			}
		],
		"right": []
	}
}</code></pre><h4 id="4-4-reiniciar-o-daemon"><strong><strong>4.4 R</strong>einiciar o<strong> Daemon</strong></strong></h4><p>Salve o arquivo e execute o seguinte comando no terminal: <code><em><em>powerline-daemon —-replace</em></em></code><em>.</em></p><blockquote><strong>Observação importante<strong>:</strong></strong> toda vez que você fizer alterações na configuração do Powerline, além de reiniciar o Terminal, você também precisará <strong>reiniciar o daemon para ver as alterações refletidas</strong> executando: <code><em><em>powerline-daemon —-replace</em></em></code>.</blockquote><h4 id="4-5-reiniciar-o-terminal"><strong><strong>4.5 R</strong>einiciar o terminal</strong></h4><p>Feche o terminal (Terminal &gt; Quit Terminal) e inicie novamente.</p><p>Neste ponto, estamos com tudo pronto! Aí está! Se você abrir o Terminal e navegar para qualquer repositório git e colocar em funcionamento, ele deve se parecer com o seguinte:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_QRJ9_60oCmcwRGfYqCbqSw-1.png" class="kg-image" alt="1_QRJ9_60oCmcwRGfYqCbqSw-1" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_QRJ9_60oCmcwRGfYqCbqSw-1.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_QRJ9_60oCmcwRGfYqCbqSw-1.png 800w" sizes="(min-width: 720px) 720px" width="800" height="213" loading="lazy"></figure><p>Aqui é como se parece com o tema Solarized-Light:</p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_8yii2h-RBMX3j5dtMagr2Q.png" class="kg-image" alt="1_8yii2h-RBMX3j5dtMagr2Q" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_8yii2h-RBMX3j5dtMagr2Q.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_8yii2h-RBMX3j5dtMagr2Q.png 800w" sizes="(min-width: 720px) 720px" width="800" height="199" loading="lazy"></figure><p>Aqui é como se parece com o tema <a href="https://raw.githubusercontent.com/lysyi3m/osx-terminal-themes/master/schemes/Cobalt2.terminal" rel="noopener">Cobalt2:</a></p><figure class="kg-card kg-image-card"><img src="https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_hYHwy__bxYoA8cji8E3plQ.png" class="kg-image" alt="1_hYHwy__bxYoA8cji8E3plQ" srcset="https://www.freecodecamp.org/portuguese/news/content/images/size/w600/2022/08/1_hYHwy__bxYoA8cji8E3plQ.png 600w, https://www.freecodecamp.org/portuguese/news/content/images/2022/08/1_hYHwy__bxYoA8cji8E3plQ.png 800w" sizes="(min-width: 720px) 720px" width="800" height="167" loading="lazy"></figure><p>Obrigado!</p><p>Caso tenha dúvidas ou questões, pergunte-me no Twitter: <a href="https://twitter.com/rajaraodv" rel="noopener">https://twitter.com/rajaraodv</a></p><h4 id="outras-publica-es-do-autor-"><strong>Outras publicações do autor:</strong></h4><p><strong>(os links abaixo são para as publicações originais em inglês)</strong></p><p><a href="https://medium.com/@rajaraodv/latest" rel="noopener"><em><em>https://medium.com/@rajaraodv/latest</em></em></a></p><h4 id="ecmascript-2015-"><strong><strong>ECMAScript 2015+</strong></strong></h4><ol><li><em><em><a href="https://www.freecodecamp.org/news/check-out-these-useful-ecmascript-2015-es6-tips-and-tricks-6db105590377/">Check out these useful ECMAScript 2015 (ES6) tips and tricks</a></em></em></li><li><a href="https://medium.com/@rajaraodv/5-javascript-bad-parts-that-are-fixed-in-es6-c7c45d44fd81#.7e2s6cghy" rel="noopener"><em><em>5 JavaScript “Bad” Parts That Are Fixed In ES6</em></em></a></li><li><a href="https://medium.com/@rajaraodv/is-class-in-es6-the-new-bad-part-6c4e6fe1ee65#.4hqgpj2uv" rel="noopener"><em><em>Is “Class” In ES6 The New “Bad” Part?</em></em></a></li></ol><h4 id="melhorias-para-o-terminal"><strong>Melhorias para o t<strong>erminal</strong></strong></h4><ol><li><em><em><a href="https://www.freecodecamp.org/news/jazz-up-your-bash-terminal-a-step-by-step-guide-with-pictures-80267554cb22/">How to Jazz Up Your Terminal — A Step By Step Guide With Pictures</a></em></em></li><li><em><em><a href="https://www.freecodecamp.org/news/jazz-up-your-zsh-terminal-in-seven-steps-a-visual-guide-e81a8fd59a38/">Jazz Up Your “ZSH” Terminal In Seven Steps — A Visual Guide</a></em></em></li></ol><h4 id="www"><strong><strong>WWW</strong></strong></h4><ol><li><em><em><a href="https://www.freecodecamp.org/news/a-fascinating-and-messy-history-of-the-web-and-javascript-video-8978dc7bda75/">A Fascinating And Messy History Of The Web And JavaScript</a></em></em></li></ol><h4 id="virtual-dom"><strong><strong>Virtual DOM</strong></strong></h4><ol><li><a href="https://medium.com/@rajaraodv/the-inner-workings-of-virtual-dom-666ee7ad47cf" rel="noopener"><em><em>Inner Workings Of The Virtual DOM</em></em></a></li></ol><h4 id="desempenho-no-react"><strong>Desempenho no <strong>React</strong></strong></h4><ol><li><a href="https://medium.com/@rajaraodv/two-quick-ways-to-reduce-react-apps-size-in-production-82226605771a#.6lepbl7ae" rel="noopener"><em><em>Two Quick Ways To Reduce React App’s Size In Production</em></em></a></li><li><a href="https://medium.com/@rajaraodv/using-preact-instead-of-react-70f40f53107c#.7fzp0lyo3" rel="noopener"><em><em>Using Preact Instead Of React</em></em></a></li></ol><h4 id="programa-o-funcional"><strong>Programação funcional</strong></h4><ol><li><a href="https://medium.com/@rajaraodv/javascript-is-turing-complete-explained-41a34287d263#.6t0b2w66p" rel="noopener"><em><em>JavaScript Is Turing Complete — Explained</em></em></a></li><li><a href="https://medium.com/@rajaraodv/functional-programming-in-js-with-practical-examples-part-1-87c2b0dbc276#.fbgrmoa7g" rel="noopener"><em><em>Functional Programming In JS — With Practical Examples (Part 1)</em></em></a></li><li><em><em><a href="https://www.freecodecamp.org/news/functional-programming-in-js-with-practical-examples-part-2-429d2e8ccc9e/">Functional Programming In JS — With Practical Examples (Part 2)</a></em></em></li><li><a href="https://medium.com/@rajaraodv/why-redux-needs-reducers-to-be-pure-functions-d438c58ae468#.bntrywxrf" rel="noopener"><em><em>Why Redux Need Reducers To Be “Pure Functions”</em></em></a></li></ol><h4 id="webpack"><strong><strong>WebPack</strong></strong></h4><ol><li><a href="https://medium.com/@rajaraodv/webpack-the-confusing-parts-58712f8fcad9#.6ot6deo2b" rel="noopener"><em><em>Webpack — The Confusing Parts</em></em></a></li><li><a href="https://medium.com/@rajaraodv/webpack-hot-module-replacement-hmr-e756a726a07#.y667mx4lg" rel="noopener"><em><em>Webpack &amp; Hot Module Replacement [HMR]</em></em></a><em><em> (under-the-hood)</em></em></li><li><a href="https://medium.com/@rajaraodv/webpacks-hmr-react-hot-loader-the-missing-manual-232336dc0d96#.fbb1e7ehl" rel="noopener"><em><em>Webpack’s HMR And React-Hot-Loader — The Missing Manual</em></em></a></li></ol><h4 id="draft-js"><strong><strong>Draft.js</strong></strong></h4><ol><li><a href="https://medium.com/@rajaraodv/why-draft-js-and-why-you-should-contribute-460c4a69e6c8#.jp1tsvsqc" rel="noopener"><em><em>Why Draft.js And Why You Should Contribute</em></em></a></li><li><a href="https://medium.com/@rajaraodv/how-draft-js-represents-rich-text-data-eeabb5f25cf2#.hh0ue85lo" rel="noopener"><em><em>How Draft.js Represents Rich Text Data</em></em></a></li></ol><h4 id="react-e-redux"><strong><strong>React </strong>e <strong>Redux</strong></strong></h4><ol><li><a href="https://medium.com/@rajaraodv/step-by-step-guide-to-building-react-redux-apps-using-mocks-48ca0f47f9a#.s7zsgq3u1" rel="noopener"><em><em>Step by Step Guide To Building React Redux Apps</em></em></a></li><li><a href="https://medium.com/@rajaraodv/a-guide-for-building-a-react-redux-crud-app-7fe0b8943d0f#.g99gruhdz" rel="noopener"><em><em>A Guide For Building A React Redux CRUD App</em></em></a><em><em> (3-page app)</em></em></li><li><a href="https://medium.com/@rajaraodv/using-middlewares-in-react-redux-apps-f7c9652610c6#.oentrjqpj" rel="noopener"><em><em>Using Middlewares In React Redux Apps</em></em></a></li><li><a href="https://medium.com/@rajaraodv/adding-a-robust-form-validation-to-react-redux-apps-616ca240c124#.jq013tkr1" rel="noopener"><em><em>Adding A Robust Form Validation To React Redux Apps</em></em></a></li><li><a href="https://medium.com/@rajaraodv/securing-react-redux-apps-with-jwt-tokens-fcfe81356ea0#.xci6o9s6w" rel="noopener"><em><em>Securing React Redux Apps With JWT Tokens</em></em></a></li><li><a href="https://medium.com/@rajaraodv/handling-transactional-emails-in-react-redux-apps-8b1134748f76#.a24nenmnt" rel="noopener"><em><em>Handling Transactional Emails In React Redux Apps</em></em></a></li><li><a href="https://medium.com/@rajaraodv/the-anatomy-of-a-react-redux-app-759282368c5a#.7wwjs8eqo" rel="noopener"><em><em>The Anatomy Of A React Redux App</em></em></a></li><li><a href="https://medium.com/@rajaraodv/why-redux-needs-reducers-to-be-pure-functions-d438c58ae468#.bntrywxrf" rel="noopener"><em><em>Why Redux Need Reducers To Be </em>"<em>Pure Functions</em>"</em></a></li><li><a href="https://medium.com/@rajaraodv/two-quick-ways-to-reduce-react-apps-size-in-production-82226605771a#.6lepbl7ae" rel="noopener"><em><em>Two Quick Ways To Reduce React App’s Size In Production</em></em></a></li></ol><h4 id="se-essa-publica-o-foi-til-para-voc-compartilhe-obrigado-">Se essa publicação foi útil para você, compartilhe! Obrigado!</h4> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
