<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Allan Ramos</title>
    <description>The latest articles on DEV Community by Allan Ramos (@allangrds).</description>
    <link>https://dev.to/allangrds</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F470942%2F28d33352-6fed-404a-8472-81d61f5d95b5.jpeg</url>
      <title>DEV Community: Allan Ramos</title>
      <link>https://dev.to/allangrds</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/allangrds"/>
    <language>en</language>
    <item>
      <title>React será compilado</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Thu, 22 Feb 2024 20:37:50 +0000</pubDate>
      <link>https://dev.to/allangrds/react-sera-compilado-1dc1</link>
      <guid>https://dev.to/allangrds/react-sera-compilado-1dc1</guid>
      <description>&lt;p&gt;Este artigo é uma tradução do artigo &lt;a href="https://reacttraining.com/blog/react-19-will-be-compiled?ref=dailydev"&gt;React Will Be Compiled&lt;/a&gt; de Brad Westfall.&lt;/p&gt;

&lt;p&gt;Ontem, a equipe do React fez uma postagem no blog anunciando no que têm trabalhado para o React. Andrew Clark, da equipe do React, nos fornece uma boa análise das mudanças:&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1758229889595977824-684" src="https://platform.twitter.com/embed/Tweet.html?id=1758229889595977824"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1758229889595977824-684');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1758229889595977824&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Correção: Anteriormente, afirmei que seria a versão 19 que seria compilada. O anúncio da equipe do React mencionou o React compilado e eu assumi (assim como outros) que isso se referia à versão 19. Parece que a versão 19 terá muitos recursos mencionados em sua postagem, mas a compilação provavelmente será na próxima versão (como indica Andrew, provavelmente até o final deste ano, 2024).&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1760433969118769654-741" src="https://platform.twitter.com/embed/Tweet.html?id=1760433969118769654"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1760433969118769654-741');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1760433969118769654&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Seja qual for a versão, espero que esta postagem ajude qualquer pessoa que se sinta confusa sobre o que significa o React se tornar "compilado". Tentarei mostrar exemplos e contexto histórico sobre como chegamos a este ponto, pois tem sido um tópico muito discutido e às vezes é difícil acompanhar, especialmente se você não viu toda a história do React se desenrolar.&lt;/p&gt;

&lt;h2&gt;
  
  
  O React compilado resolverá os principais problemas dos hooks
&lt;/h2&gt;

&lt;p&gt;Conforme continuamos, mantenha em mente estes princípios do React que não mudarão quando compilarmos o React:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O estado do React é imutável.&lt;/li&gt;
&lt;li&gt;A interface do usuário é uma função do estado.&lt;/li&gt;
&lt;li&gt;Rerrenderizar quando o estado muda para produzir uma nova interface do usuário.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Além dos números de versão, penso no React como tendo três eras distintas.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A era dos componentes de classe&lt;/strong&gt; (sem primitivo para abstração)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A era dos Hooks&lt;/strong&gt; (precisamos memoizar)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A era compilada&lt;/strong&gt; (auto-memoização)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estamos prestes a entrar na era compilada, mas como chegamos até aqui?&lt;/p&gt;

&lt;p&gt;Para aqueles de nós que criaram projetos com class components, lembramos dos problemas que as classes nos causavam quando queríamos abstrair e reutilizar nosso código. O React estava carente de um "primitivo" para reutilização de código, então a comunidade inventou padrões como HOCs (Higher-Order Components) e Render Props, que &lt;a href="https://gist.github.com/bradwestfall/4fa683c8f4fcd781a38a8d623bec20e7"&gt;eram menos do que ideais&lt;/a&gt;. Acontece que o problema em criar um primitivo era que as próprias classes não nos forneciam o nível de composição de que precisávamos. Então, a equipe do React começou a buscar alternativas às classes e a se concentrar na composição funcional.&lt;/p&gt;

&lt;p&gt;Naquela época, componentes funcionais já existiam, mas o chamávamos de Stateless Functional Components porque não podiam ter estado ou outros aspectos de ciclo de vida que as classes tinham. A equipe do React viu os componentes funcionais como uma forma de nos dar o primitivo que precisávamos. Se ao menos eles pudessem descobrir uma maneira de permitir que os componentes funcionais "se conectassem" aos ciclos de vida do React 😉&lt;/p&gt;

&lt;p&gt;Sim, daí vem o termo "hooks".&lt;/p&gt;

&lt;p&gt;Quando os hooks foram anunciados em 2018, eu estava na conferência. Lembro-me de quando Ryan Florence subiu ao palco para falar logo após o anúncio e fez uma refatoração de &lt;a href="https://www.youtube.com/watch?v=wXLf18DsV-I"&gt;"render props para hooks" na frente de todos&lt;/a&gt;. Ficamos impressionados. Hooks, e especificamente hooks personalizados, seriam o primitivo que estávamos perdendo.&lt;/p&gt;

&lt;p&gt;O que não percebemos na época foi que misturar todo o nosso código em uma única função poderia nos fornecer composição, mas viria como uma compensação porque agora teríamos que memoizar. Não percebemos que as classes naturalmente nos protegiam da memoização, dada a natureza do rerenderização.&lt;/p&gt;

&lt;p&gt;Nos class components, o método de renderização isola seu código dos outros &lt;a href="https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/"&gt;métodos do ciclo de vida&lt;/a&gt;, o que por sua vez significa que uma rerenderização não afetará adversamente o código que não faz parte da fase de renderização. Isso provavelmente foi menos uma decisão de design e mais uma característica de como as classes funcionam. 🧐 Isso parece quase bobo de mencionar, mas desempenha um papel nas evoluções que viriam a seguir.&lt;/p&gt;

&lt;h2&gt;
  
  
  React com Memoização
&lt;/h2&gt;

&lt;p&gt;Para ser honesto, os class components eram terríveis. Lembro-me de quando mudamos nosso currículo de workshop de dois dias para hooks e metade de nossos tópicos simplesmente evaporaram porque os class components introduziam tanta complexidade nas aplicações que não precisávamos mais ensinar.&lt;/p&gt;

&lt;p&gt;Se criássemos um class component com um método para lidar com o envio de formulário, o método nunca precisaria ser "memoizado". Vamos ver o que acontece quando fazemos algo semelhante com componentes funcionais:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// lógica do evento&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Talvez você não tenha percebido imediatamente, mas esta função será recriada toda vez que houver uma rerenderização, o que significa que será uma nova função na memória. Normalmente, não é um problema que as funções se recriem e, neste exemplo, não está causando nenhum problema para nós. Vale ressaltar, no entanto, que isso não aconteceria em classes porque seria um método separado da fase de renderização.&lt;/p&gt;

&lt;p&gt;Também vale ressaltar que a ideia geral de coisas precisarem se recriar em JavaScript não é específica do React. Posso mostrar-lhe meu código jQuery de 2008 que também recriaria funções e objetos. Estou apenas brincando, não faço ideia de onde está meu código de 2008.&lt;/p&gt;

&lt;p&gt;Agora vamos refatorar o código um pouco:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// lógica do evento&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ainda não é um problema que `onSubmit será uma nova função em cada renderização.&lt;/p&gt;

&lt;p&gt;A rerrenderização de &lt;code&gt;App&lt;/code&gt; causará uma rerrenderização de &lt;code&gt;Form&lt;/code&gt; neste caso. Alguns dirão que um componente receberá uma rerrenderização apenas se suas props mudarem. Isso não é verdade. O &lt;code&gt;Form&lt;/code&gt; receberá uma rerenderização quando o &lt;code&gt;App&lt;/code&gt; receber uma rerenderização, independentemente das props. Por enquanto, simplesmente não importa se a propriedade &lt;code&gt;onSubmit&lt;/code&gt; está mudando.&lt;/p&gt;

&lt;p&gt;Agora, digamos que tenhamos alguma razão para evitar que &lt;code&gt;Form&lt;/code&gt; seja rerenderizado quando &lt;code&gt;App&lt;/code&gt; é rerenderizado. Este exemplo é demasiadamente simplista, mas digamos que memoizamos &lt;code&gt;Form&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;jsx&lt;br&gt;
// Agora, Form só será rerenderizado se suas props específicas mudarem. Não a cada&lt;br&gt;
// vez que App for rerenderizado&lt;br&gt;
const Form = React.memo(({ onSubmit }) =&amp;gt; {&lt;br&gt;
  // ...&lt;br&gt;
})&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Agora temos um problema.&lt;/p&gt;

&lt;p&gt;O React depende fortemente de &lt;a href="https://reacttraining.com/blog/state-in-react-is-immutable"&gt;verificações de igualdade estrita&lt;/a&gt; para saber se uma variável mudou, o que é uma maneira sofisticada de dizer que eles usam &lt;code&gt;===&lt;/code&gt; e &lt;code&gt;Object.is()&lt;/code&gt; para comparar o antigo com o novo. Quando você compara primitivos do JavaScript (como strings) entre si com &lt;code&gt;===&lt;/code&gt;, o JavaScript os compara pelos valores (você já sabia disso). Mas quando o JavaScript compara arrays, objetos ou funções entre si, o uso de === está comparando suas identidades, em outras palavras, sua alocação de memória. É por isso que &lt;code&gt;{} === {}&lt;/code&gt; é &lt;code&gt;false&lt;/code&gt; no JavaScript porque esses são dois identidades de objeto diferentes na memória.&lt;/p&gt;

&lt;p&gt;Fazer &lt;code&gt;Form = React.memo(fn)&lt;/code&gt; é como dizer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ei React, só queremos rerenderizar Form se suas props realmente mudarem de acordo com uma verificação de identidade.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Isso cria um problema porque &lt;code&gt;onSubmit&lt;/code&gt; muda toda vez que &lt;code&gt;App&lt;/code&gt; é rerenderizado. Isso levará a que &lt;code&gt;Form&lt;/code&gt; seja sempre rerenderizado, o que significa que a memoização não nos ajuda em nada. É um sobrecarga sem sentido para o React neste ponto.&lt;/p&gt;

&lt;p&gt;Agora, precisamos voltar e garantir que &lt;code&gt;onSubmit&lt;/code&gt; não mude sua identidade quando App` é rerenderizado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// lógica do evento&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nós usamos o &lt;code&gt;useCallback&lt;/code&gt; para estabilizar a função para que sua identidade não mude. De certa forma, é um tipo de memoização. Em termos excessivamente simplificados, memoização significa "lembrar" ou "armazenar em cache" a resposta de uma função.&lt;/p&gt;

&lt;p&gt;É como se estivéssemos dizendo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ei React, lembre-se da identidade desta função que estou passando para useCallback. Quando tivermos rerenders, estou te dando uma nova função toda vez, mas esqueça isso, me dê a identidade da função original da primeira vez que te chamei.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Memoizar a função &lt;code&gt;onSubmit&lt;/code&gt; não é normalmente necessário, mas se tornou necessário quando &lt;code&gt;Form&lt;/code&gt; foi memoizado e recebeu `onSubmit como uma propriedade. Na React Training, chamamos isso de "sangramento de implementação"(implementation bleed).&lt;/p&gt;

&lt;p&gt;O problema não para por aí. Vamos adicionar mais código:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`jsx&lt;br&gt;
function App() {&lt;br&gt;
  const [state, setState] = useState()&lt;/p&gt;

&lt;p&gt;const settings = {}&lt;br&gt;
  const onSubmit = useCallback(() =&amp;gt; {&lt;br&gt;
    const x = settings.x&lt;br&gt;
    // código&lt;br&gt;
  }, [])&lt;/p&gt;

&lt;p&gt;// código&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;O objeto &lt;code&gt;settings&lt;/code&gt;(configurações) se recria em cada renderização de &lt;code&gt;App&lt;/code&gt;. Isso não é um problema por si só, mas se você conhece bem o React, sabe que o linter pedirá para você colocar &lt;code&gt;settings&lt;/code&gt; no array de dependências do useCallback` neste caso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se fizermos isso, é como se estivéssemos dizendo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Queremos que onSubmit seja estável e não mude a cada renderização. Mas queremos que useCallback recrie onSubmit se qualquer uma das coisas neste array de dependências mudar.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Você pode se perguntar: "por que eu gostaria que &lt;code&gt;onSubmit&lt;/code&gt; mudasse?"&lt;/p&gt;

&lt;p&gt;Eu concordo com você, provavelmente não precisa mudar, mas há muitas situações no React em que coisas como &lt;code&gt;useCallback&lt;/code&gt; e &lt;code&gt;useMemo&lt;/code&gt; precisam re-memoizar e criar uma nova identidade para seu valor de retorno quando seu array de dependências muda. O linter simplesmente não sabe que nunca queremos que &lt;code&gt;onSubmit&lt;/code&gt; seja diferente neste caso.&lt;/p&gt;

&lt;p&gt;Lembre-se de que o linter está quase sempre certo, mas escolhi este exemplo para mostrar como podemos não querer o que o linter quer.&lt;/p&gt;

&lt;p&gt;Se ouvirmos o linter e colocarmos &lt;code&gt;settings&lt;/code&gt; no array de dependências, aqui está o que acontecerá:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quando &lt;code&gt;App&lt;/code&gt; é rerenderizado...&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;settings&lt;/code&gt; se torna um novo objeto que não é &lt;code&gt;===&lt;/code&gt; ao que estava na renderização anterior.&lt;/li&gt;
&lt;li&gt;O array de dependências vê &lt;code&gt;settings&lt;/code&gt; como diferente de acordo com &lt;code&gt;===&lt;/code&gt; mesmo que seus valores não tenham mudado.&lt;/li&gt;
&lt;li&gt;A mudança no array de dependências significa que &lt;code&gt;useCallback&lt;/code&gt; retorna uma nova identidade para onSubmit.&lt;/li&gt;
&lt;li&gt;O &lt;code&gt;Form&lt;/code&gt; é rerenderizado porque &lt;code&gt;onSubmit&lt;/code&gt; muda.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Em resumo, a memoização de &lt;code&gt;Form&lt;/code&gt; é inútil. Ele sempre será rerenderizado quando &lt;code&gt;App&lt;/code&gt; for rerenderizado. Então agora temos mais "sangramento de implementação"(implementation bleed) porque precisamos memoizar &lt;code&gt;settings&lt;/code&gt; com &lt;code&gt;useMemo&lt;/code&gt; apenas para que possamos manter a memoização de &lt;code&gt;onSubmit&lt;/code&gt; intacta.&lt;/p&gt;

&lt;p&gt;Vamos dar um passo atrás para aquela pergunta:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Por que eu gostaria que onSubmit mudasse? Não poderíamos simplesmente desativar o linter nesse caso?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Claro, neste caso, acho que podemos deixar &lt;code&gt;settings&lt;/code&gt; fora do array de dependências ou podemos simplesmente memoizá-lo, que é o que eu provavelmente faria. Ou até mesmo poderíamos argumentar que não precisávamos do formulário memoizado em primeiro lugar, o que teria evitado essa bagunça. Isso não é o ponto, é apenas um exemplo. O ponto é que a memoização no React frequentemente leva a um cascata de "sangramento de implementação"(implementation bleed).&lt;/p&gt;

&lt;p&gt;O tópico dos arrays de dependência e por que o linter quer que você coloque coisas neles vai muito além do escopo deste post. Eu provavelmente poderia falar sobre esse tópico por horas porque é vasto, com muitos detalhes. A verdade é que o linter geralmente está certo e tem boas intenções. O problema é que MUITOS desenvolvedores do React não entendem seu raciocínio e acham que o linter é apenas uma pequena sugestão. Na minha experiência, quando você ignora o linter, provavelmente encontrará bugs.&lt;/p&gt;

&lt;p&gt;Aqui está um exemplo perfeito: Alguns anos atrás, estava conversando com alguém no Twitter que disse que nunca colocava funções no array de dependências de seu &lt;code&gt;useEffect&lt;/code&gt; porque às vezes criava um loop infinito. Eu disse algo como "por que você não usa &lt;code&gt;useCallback&lt;/code&gt; nessas funções, isso evitará o loop. O problema é que a função está mudando com muita frequência".&lt;/p&gt;

&lt;p&gt;Eles disseram "O que é useCallback?"&lt;/p&gt;

&lt;p&gt;É comum as pessoas não entenderem memoização ou React o suficiente e depois ficarem frustradas com o linter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependente de memoização
&lt;/h2&gt;

&lt;p&gt;Se você trabalhou o suficiente com React, sabe que pode ser um incômodo lidar com os arrays de dependências. O linter pode lhe dizer para colocar coisas no array e você não gosta do resultado (como um loop). É fácil ficar irritado com o linter, mas o linter estava certo. Não porque o React "quer" um loop infinito, é claro, mas porque você precisava também memoizar algo agora.&lt;/p&gt;

&lt;p&gt;Os arrays de dependência são uma forma de lidar com o fato de que todo o nosso código está co-localizado em um componente funcional que rerenderiza, e queremos monitorar as mudanças nas variáveis ao longo do tempo. Às vezes, acabamos colocando objetos, arrays e funções no array de dependências, então certifique-se de estabilizá-los com memoização. A maneira como explico o que o React significa por "estável" é "uma variável que não muda a menos que você queira".&lt;/p&gt;

&lt;p&gt;Vamos demonstrar isso com código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;misc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMisc&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;darkMode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setDarkMode&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;darkMode&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;User&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// get user&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos ver que quando o estado misc em &lt;code&gt;App&lt;/code&gt; muda, a consequência em cascata é que &lt;code&gt;options&lt;/code&gt; mudará e, portanto, o &lt;code&gt;useEffect&lt;/code&gt; será executado novamente, mesmo que o efeito não tenha nada a ver com o estado &lt;code&gt;misc&lt;/code&gt;. Portanto, é melhor envolver a variável &lt;code&gt;options&lt;/code&gt; em um &lt;code&gt;useMemo&lt;/code&gt;. Quando você fizer isso, o linter pedirá corretamente para você colocar `darkMode no array de dependências:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;jsx&lt;br&gt;
const [darkMode, setDarkMode] = useState(false)&lt;br&gt;
const options = useMemo(() =&amp;gt; {&lt;br&gt;
  return { darkMode }&lt;br&gt;
}, [darkMode])&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ao fazer isso, estamos dizendo:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Queremos que options seja estável, até que o modo escuro mude. Em seguida, reestabilize-o em uma nova identidade. Mas não faça nada quando o estado misc mudar, porque não está em nosso array (não dependemos dele).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sim, entendi o ponto. No React, a memoização é fundamental e é responsabilidade do desenvolvedor implementá-la corretamente. Caso contrário, podem ocorrer bugs e problemas de desempenho. É importante entender como e quando aplicar a memoização para garantir um código eficiente e livre de erros.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sempre compilamos o React
&lt;/h2&gt;

&lt;p&gt;Dependendo da sua definição do termo, você poderia argumentar que o React sempre teve uma etapa de compilação (JSX). Para mim, parece ser um termo solto no JavaScript que basicamente significa que o código que você escreve é diferente do código que é executado no navegador.&lt;/p&gt;

&lt;p&gt;Minha primeira experiência com o React foi em 2015. Babel e React ainda eram relativamente novos para a maioria dos desenvolvedores. De certa forma, sua popularidade cresceu em conjunto. O React é famosamente conhecido por compilar JSX em chamadas de função. Então, eu acho que o React é tecnicamente compilado, mas sempre senti que era um pequeno syntax sugar e que a semântica de um elemento JSX se tornando uma função muito previsível significa para mim que é uma quantidade de compilação relativamente "leve".&lt;/p&gt;

&lt;p&gt;Hoje em dia, também compilamos TypeScript para JavaScript, o que para mim é engraçado, porque neste caso significa apenas que todo o TypeScript que escrevemos evapora quando salvamos e o código que resta é o JavaScript. Mas eu acho que ainda se encaixa na minha definição de "o que você escreve é o que você obtém".&lt;/p&gt;

&lt;h2&gt;
  
  
  Compilar é um espectro
&lt;/h2&gt;

&lt;p&gt;Para mim, parece que "frameworks compilados" se situam em um espectro onde alguns são compilados um pouco e outros são compilados bastante:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2kx9xbskelgmql1eozl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx2kx9xbskelgmql1eozl.png" alt="Espectro de compilação comparando versões do react" width="704" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O React parece estar mais no lado "não muito" em comparação com alguns outros frameworks JavaScript modernos. Para mim, a regra do "o que você vê é o que você obtém" determinará onde você está neste espectro. O JSX significa que o React é um pouco compilado, mas o outro código que escrevo não é compilado pelo React.&lt;/p&gt;

&lt;p&gt;Por outro lado, o Svelte é tão fortemente compilado que seu criador o &lt;a href="https://gist.github.com/Rich-Harris/0f910048478c2a6505d1c32185b61934"&gt;descreveu como nem mesmo sendo JavaScript&lt;/a&gt;. O Svelte é realmente mais uma linguagem de programação porque a semântica do que você escreve está tão longe da semântica do que você obtém quando ele se transforma em JavaScript.&lt;/p&gt;

&lt;p&gt;Não estou tentando tornar este um post de comparação, ou dizer que um caminho é melhor que o outro, ou que compilar é bom ou ruim. Estou simplesmente dizendo que parece ser um espectro onde diferentes frameworks JavaScript compilam menos, ou compilam mais, ou compilam até o ponto em que nem mesmo são realmente JS mais.&lt;/p&gt;

&lt;p&gt;O anúncio da equipe do React é que o React vai ser mais compilado do que era antes. Será mais do que alguns dos outros? Não tenho certeza. Não importa muito onde ele acaba neste espectro para mim. O que importa mais é por que ele está sendo compilado. A resposta é por razões diferentes das dos outros.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compilando para Auto-Memoização
&lt;/h2&gt;

&lt;p&gt;O React não está abandonando a imutabilidade e indo em rumo para a observabilidade. Ainda terá verificações de identidade e arrays de dependência. Então, o fato de estar compilado agora não faz o React parecer semelhante aos outros. Ele será compilado para que possamos ter auto-memoização. O React é o mesmo de sempre, mas sem as desvantagens da memoização manual, que era um dos principais problemas com hooks e componentes funcionais.&lt;/p&gt;

&lt;p&gt;Pessoalmente, estou acostumado com minha lógica acima do JSX ser deixada intocada. Essa mudança será principalmente desaprender a pensar em termos de memoização manual. Terei que confiar no compilador para tomar boas decisões para mim e ainda estou incerto sobre quanto disso terei que orientar o compilador vs "It Just Works™". Estou otimista e interessado em experimentar.&lt;/p&gt;

&lt;p&gt;Em resumo, vale ressaltar que essa ideia não surgiu do nada. Estamos discutindo isso como uma possibilidade no React há três anos, desde que &lt;a href="https://www.youtube.com/watch?v=lGEMwh32soc"&gt;Xuan Huang introduziu a ideia na React Conf 2021&lt;/a&gt;. Também houve momentos em que foi o tópico quente no Twitter nos círculos do React há alguns anos.&lt;/p&gt;

&lt;p&gt;Minha esperança é que, se você não estava ciente dessas conversas, este post forneça exemplos e contexto justos sobre como chegamos a este ponto. Obrigado por ler!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>tradução</category>
    </item>
    <item>
      <title>Tudo que sei sobre Style Guides, Design Systems, e Biblioteca de Componentes</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Thu, 27 Jul 2023 18:46:08 +0000</pubDate>
      <link>https://dev.to/allangrds/tudo-que-sei-sobre-style-guides-design-systems-e-biblioteca-de-componentes-29pl</link>
      <guid>https://dev.to/allangrds/tudo-que-sei-sobre-style-guides-design-systems-e-biblioteca-de-componentes-29pl</guid>
      <description>&lt;p&gt;Esse artigo é uma tradução do artigo original &lt;a href="https://leerob.io/blog/style-guides-component-libraries-design-systems#what-is-a-style-guide"&gt;Everything I Know About Style Guides, Design Systems, and Component Libraries&lt;/a&gt; criado por &lt;a href="https://leerob.io/"&gt;Lee Robinson&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Durante a maior parte do ano passado, investi arduamente em desenvolvimento front-end e design. Quando iniciei minha nova função, identifiquei a necessidade de uma biblioteca de componentes e a criei. Desde então, aprendi muito sobre style guides, design systems, biblioteca de componentes(component libraries) e suas melhores práticas. Este post será um mergulho profundo em tudo o que aprendi no ano passado.&lt;/p&gt;

&lt;h1&gt;
  
  
  Por que você deveria se importar?
&lt;/h1&gt;

&lt;p&gt;Todo site começa simples. Talvez exista uma página com algumas coisas diferentes, mas ele começará de forma humilde.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6KFODVZ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AdBT4SaUssQT_7Irc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6KFODVZ0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AdBT4SaUssQT_7Irc.png" alt="Site Mockup" width="720" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Então, aos poucos, ele começa a crescer.&lt;/p&gt;

&lt;p&gt;Nova páginas são adicionadas e novas funcionalidades são implementadas. Talvez existam vários times focados em partes específicas do site. Você também por estar focado em mobile.&lt;/p&gt;

&lt;p&gt;Você começa a notar que os botões em uma parte do site são um pouco diferentes dos outros. Uma equipe decide construir uma funcionalidade que outra equipe já fez (sem saber). Falhas de comunicação acontecem. A consistência é perdida.&lt;/p&gt;

&lt;p&gt;Este problema poderia ter sido evitado? Com certeza. No entanto, por que isso sempre acontece? &lt;strong&gt;A menos que você pense em seu processo de design e desenvolvimento de forma atencipada, você terá problemas mais tarde à medida que o projeto aumenta.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para evitar que esse problema aconteça ou corrigir a falta de consistência existente em seus produtos, você precisa de três coisas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Style Guide&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Biblioteca de componentes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Design System&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fique tranquilo se você ainda não tem ideia do que estou falando. No final deste artigo você terá consumido quase um ano de tentativa e erro, pesquisa e desenvolvimento.&lt;/p&gt;

&lt;h1&gt;
  
  
  O que é Style Guide?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I3jWsxyX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2ATivIo7iCTXDkVV3s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I3jWsxyX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2ATivIo7iCTXDkVV3s.png" alt="Style Guide" width="720" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Um &lt;strong&gt;style guide&lt;/strong&gt; é um conjunto de regras sobre como sua marca deve ser exibida. Isso é tanto visual (design e imagens) quanto conteúdo escrito (voz e tom).&lt;/p&gt;

&lt;p&gt;O objetivo de um style guide é &lt;strong&gt;permitir que vários colaboradores criem conteúdo de forma clara que represente a marca de forma coesa&lt;/strong&gt;. Quase todas as grandes marcas têm um style guide, embora nem todas sejam públicas.&lt;/p&gt;

&lt;h1&gt;
  
  
  O que é uma biblioteca de componentes?
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fcZEeMA7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AYvJm1ngOg1MIH1-U.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fcZEeMA7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AYvJm1ngOg1MIH1-U.png" alt="Componentes" width="720" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Uma &lt;strong&gt;biblioteca de componentes&lt;/strong&gt; é uma implementação viva do seu  style guide. É um conjunto compartilhado de componentes que os desenvolvedores podem consumir para criar aplicações que reflitam sua marca. Alguns benefícios notáveis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ter uma biblioteca de componentes significa que quem for utilizar acabará codando menos.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Como há uma centralização, você pode garantir que todos os componentes atendam aos requisitos de acessibilidade.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Os componentes se tornam mais robustos com vários contribuidores enviando correções de bugs e melhorias em um único local.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Menos duplicação de código permitirá que você lance novos produtos e reescreva código legado de forma mais rápida.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  O que é Design System?
&lt;/h1&gt;

&lt;p&gt;Um &lt;strong&gt;design system&lt;/strong&gt; é um conjunto de padrões, documentação e princípios, juntamente com os componentes para atingir esses padrões. É a &lt;strong&gt;junção de seu style guide e a biblioteca de componentes&lt;/strong&gt;. Um dos design systems mais populares é do Google, &lt;a href="https://material.io/design/"&gt;Material Design&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Z_JM_u_t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AghOv9iNjSOcMGdyA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Z_JM_u_t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AghOv9iNjSOcMGdyA.png" alt="Design System" width="720" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Um design system deve conter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Conteúdo&lt;/strong&gt;: A linguagem para projetar uma experiência de produto mais ponderada.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Design&lt;/strong&gt;: Os elementos visuais do design system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Componentes&lt;/strong&gt;: Os blocos de construção para o desenvolvimento de novos produtos e funcionalidades.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Padrões&lt;/strong&gt;: As pequenas partes para criar experiências de produto significativas.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Por onde você deve começar?
&lt;/h1&gt;

&lt;p&gt;Dependendo do estado da sua empresa/produto, você pode ter um ponto de partida diferente. Este é o esboço antes de entrarmos em detalhes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Crie um inventário de padrões de design existentes.&lt;/li&gt;
&lt;li&gt;Estabeleça princípios de design e comece um style guide.&lt;/li&gt;
&lt;li&gt;Defina seus design tokens.&lt;/li&gt;
&lt;li&gt;Crie ou identifique um conjunto de ícones.&lt;/li&gt;
&lt;li&gt;Escolha linguagens/frameworks para dar suporte.&lt;/li&gt;
&lt;li&gt;Avalie entre monorepo ou um único pacote.&lt;/li&gt;
&lt;li&gt;Avalie entre CSS/Sass e CSS-in-JS.&lt;/li&gt;
&lt;li&gt;Crie uma biblioteca de componentes.&lt;/li&gt;
&lt;li&gt;Escolha uma plataforma de documentação.&lt;/li&gt;
&lt;li&gt;Escreva uma documentação do design system.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Construindo um Design System
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Crie um inventário de padrões de design existentes
&lt;/h2&gt;

&lt;p&gt;A não ser que você esteja começando do zero, você precisará identificar todos os padrões de design em uso na sua interface e documentar toda inconsistência. O objetivo deve ser permanecer com a mesma experiência do usuário, independentemente da parte do produto em que o usuário está.&lt;/p&gt;

&lt;p&gt;Comece a documentar e revisar com sua equipe, e identifique os padrões que mais lhe agradam. Isso fará com que vocês tenham uma ideia do que seu style guide precisará.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estabeleça princípios de design e comece um style guide
&lt;/h2&gt;

&lt;p&gt;Chegou a hora de traduzir essas descobertas para um style guide. Você pode usar ferramentas como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.figma.com/"&gt;Figma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sketch.com/"&gt;Sketch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.framer.com/"&gt;Framer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.adobe.com/products/xd.html"&gt;Abobe XD&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Minha recomendação seria o Figma, mas em última análise, depende de sua equipe e empresa. Aqui estão alguns tutoriais úteis do &lt;a href="https://www.youtube.com/playlist?list=PLXDU_eVOJTx7QHLShNqIXL1Cgbxj7HlN4"&gt;Figma para iniciantes&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defina seus design tokens
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FMhgTG7m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AR-mdfooYKUj9PEap.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FMhgTG7m--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AR-mdfooYKUj9PEap.png" alt="Design Tokens" width="720" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Os design tokens são os átomos do design system - especificamente, são entidades nomeadas que armazenam atributos de design. Nós os usamos nos lugares de valores hard-codados(como valores hexadecimais para cor ou valores de pixel para espaçamento) para manter um sistema visual escalável e consistente para o desenvolvimento da interface.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Isso inclui coisas como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://colors.eva.design/"&gt;Cores&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://fonts.google.com/"&gt;Fontes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spencermortensen.com/articles/typographic-scale/"&gt;Tamanhos tipográficos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tanzu.vmware.com/content/built-to-adapt/intro-to-the-8-point-grid-system-2"&gt;Espaçamentos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://material.io/design/environment/light-shadows.html"&gt;Sombras&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por exemplo, vamos dar uma olhada no &lt;a href="https://vercel.com/design"&gt;Design System da Vercel&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;--geist-foreground&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--geist-background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#fff&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--accents-1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#fafafa&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--accents-2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#eaeaea&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--accents-3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#999999&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--accents-4&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#888888&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--accents-5&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#666666&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--accents-6&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#444444&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--accents-7&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#333333&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--accents-8&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#111111&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--geist-success&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#0070&lt;/span&gt;&lt;span class="nt"&gt;f3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--geist-error&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#ee0000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--geist-warning&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#f5a623&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--dropdown-box-shadow&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="nt"&gt;rgba&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;02&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;--dropdown-triangle-stroke&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;#fff&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;--scroller-start&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;var&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;--geist-background&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;--scroller-end&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;rgba&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;255&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;255&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;255&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;--shadow-small&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;5&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;rgba&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;12&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;--shadow-medium&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;8&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;30&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;rgba&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;12&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;--shadow-large&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt; &lt;span class="err"&gt;30&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="err"&gt;60&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;rgba&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;12&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;--portal-opacity&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;25&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora existe uma linguagem comum entre designers e desenvolvedores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Crie ou identifique um conjunto de ícones
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UC3s2Tjz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AmeuL8RurmvyNbfGR.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UC3s2Tjz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AmeuL8RurmvyNbfGR.png" alt="Ícones" width="720" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você já tem ícones, precisará escolher quais você não jogará fora. Talvez não faça sentido você criar seus próprio ícones dependendo do tamanho da sua empresa. Talvez seja melhor utilizar uma biblioteca de ícones open-source. Alguns exemplos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://fontawesome.com/"&gt;Font Awesome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://icons8.com/"&gt;Icons8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mui.com/components/icons/"&gt;Material UI Icons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://akveo.github.io/eva-icons/#/"&gt;Eva Icons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://feathericons.com/"&gt;Feather Icons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://styled-icons.js.org/"&gt;Styled Icons&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ikonate.com/"&gt;Ikonate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mesmo que você construa o seu próprio pacote ou use uma opção open-source, você deve padornizar e identificar padrões de uso. Também vale a pena considerar quem são os usuários finais do seu conjunto de ícones - designers, desenvolvedores e marketing?&lt;/p&gt;

&lt;p&gt;Usando SVGs, você pode tornar a biblioteca de ícones sua única fonte de verdade. Seu processo pode ficar assim:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Os designers criam/fornecem SVGs puros.&lt;/li&gt;
&lt;li&gt;Otimize e comprima os SVGs usando &lt;a href="https://github.com/svg/svgo/"&gt;SVGO&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Crie automaticamente componentes React automaticamente usando &lt;a href="https://github.com/gregberge/svgr"&gt;SVGR&lt;/a&gt; pros desenvolvedores.&lt;/li&gt;
&lt;li&gt;Gere PNGs e JPEGs em diferentes resoluções para marketing.&lt;/li&gt;
&lt;li&gt;Gere SVGs em um &lt;a href="https://www.npmjs.com/package/icon-font-generator"&gt;bundled de fontes&lt;/a&gt; para ser usada em aplicativos mobile.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Escolha linguagens/frameworks para dar suporte
&lt;/h2&gt;

&lt;p&gt;Quais linguagens ou frameworks você está mantendo atualmente? Qual deve ser o suporte da biblioteca de componentes? É importante pensar nisso com antecedência para que você possa arquitetar adequadamente sua biblioteca.&lt;/p&gt;

&lt;p&gt;Se você tiver uma aplicação que usa script tags em vez de ES Modules, então precisará configurar sua biblioteca de componentes para fazer o bundle em um único arquivo. Por exemplo, uma aplicação com JavaScript puro precisaria de algo assim em um arquivo HTML.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/js/component-library.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para fazer isso, você pode usar &lt;a href="https://webpack.js.org/"&gt;Webpack&lt;/a&gt; ou &lt;a href="https://rollupjs.org/"&gt;Rollup&lt;/a&gt;. Eu recomendaria o Webpack, pois é o padrão de mercado. Eu também recomendo o &lt;a href="https://github.com/jaredpalmer/tsdx"&gt;TSDX&lt;/a&gt; se você quiser usar o TypeScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avalie entre monorepo ou um único pacote
&lt;/h2&gt;

&lt;p&gt;Um &lt;a href="https://leerob.io/blog/monorepo-lerna-yarn-workspaces"&gt;monorepo&lt;/a&gt; permite que você crie e publique várias bibliotecas de um único repositório. Embora resolva alguns problemas muito reais, também cria outros. É importante entender os prós e os contras.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6patrn6y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AMq2Fux4t-BUdUWZZ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6patrn6y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AMq2Fux4t-BUdUWZZ.png" alt="Monorepo" width="720" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O monorepo pode ser uma boa pois…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pacotes pequenos através da diminuição do escopo dos componentes incluídos em um pacote.&lt;/li&gt;
&lt;li&gt;Processo compartilhado de build, lint, teste e release para vários pacotes versus repositórios separados com código duplicado.&lt;/li&gt;
&lt;li&gt;Controle mais granular do semver(versionamento semântico) pacote por pacote.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O monorepo pode não ser uma boa pois…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ferramental e infraestrutura adicionais necessárias.&lt;/li&gt;
&lt;li&gt;Quem estiver desenvolvendo será obrigado a importar uma variedade de pacotes em vez de uma única biblioteca de componentes.&lt;/li&gt;
&lt;li&gt;Está no hype, tecnologia de ponta. O mercado está adotando, mas você pode se deparar com problemas que poucos experimentaram sem um caminho claro para uma solução.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Algumas perguntas que o ajudarão a identificar qual solução é a melhor para sua empresa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Você tem múltiplos repositórios sendo publicados via NPM?&lt;/li&gt;
&lt;li&gt;Seu processo de build, test, lint e infraestrutura complexos? Esse processo está duplicado em vários lugares?&lt;/li&gt;
&lt;li&gt;Quantos repositórios você tem (ou planeja ter no próximo ano?)?&lt;/li&gt;
&lt;li&gt;Quão grande é seu time? Quantos farão uso da biblioteca de componentes?&lt;/li&gt;
&lt;li&gt;Será open-source? Você pode aprender com outras pessoas do mercado para ajudar a resolver problemas?&lt;/li&gt;
&lt;li&gt;Você a vê a necessidade de múltiplos pacotes no futuro? (e.g. icons, &lt;a href="https://github.com/facebook/jscodeshift"&gt;codemods&lt;/a&gt;, etc).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para empresas bem pequenas, eu diria que monorepos são desnecessários. Implementá-lo tem seu momento e lugar. &lt;a href="(https://leerob.io/blog/monorepo-lerna-yarn-workspaces)"&gt;Eu já usei&lt;/a&gt; em um lugar com 150 desenvolvedores para distribuir 10 pacotes diferentes de uma vez, abrangendo aplicativos internos e externos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avalie entre CSS/Sass e CSS-in-JS
&lt;/h2&gt;

&lt;p&gt;CSS-in-JS é forma mais fácil para construir estilos e distribuir através do NPM. Para um bom desempenho, considere usar uma solução de tempo de execução quase zero, como &lt;a href="https://stitches.dev/"&gt;Stitches&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Se a sua biblioteca de componentes precisar gerar HTML/CSS puros, eu recomendo ficar com o Sass. Um ótimo exemplo disso é o design system &lt;a href="https://www.carbondesignsystem.com/components/button/code/"&gt;Carbon da IBM&lt;/a&gt;. Você pode usar &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties"&gt;variáveis ​​CSS&lt;/a&gt; para conter seus &lt;a href="https://www.lightningdesignsystem.com/design-tokens/"&gt;design tokens&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MTMkFKYR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2A417-DDzFMcuejSol.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MTMkFKYR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2A417-DDzFMcuejSol.png" alt="Botão" width="720" height="135"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bx--btn bx--btn--primary"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Button&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você usa React, confira meu post &lt;a href="https://leerob.io/blog/css-with-react"&gt;Como eu deveria estilizar minha aplicação React?&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Crie uma biblioteca de componentes
&lt;/h2&gt;

&lt;p&gt;Com seus requisitos técnicos definidos e seu style guide iniciado, agora você poderá começar a construir uma biblioteca de componentes. Minha recomendação seria usar o *&lt;em&gt;React juntamente *&lt;/em&gt; do &lt;a href="https://storybook.js.org/"&gt;Storybook&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--t-NH7zmp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AtCTqFaCjz6vRt06V.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--t-NH7zmp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AtCTqFaCjz6vRt06V.jpeg" alt="Component Driven Development" width="720" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Criar uma biblioteca de componentes é muito mais do que apenas traduzir o style guide em código.&lt;/p&gt;

&lt;p&gt;Você precisa pensar em como quem utilizará seus componentes irão interagir com eles. Que tipo de API eles esperariam? O que fornece mais clareza e é autodocumentado? Por exemplo, considere botões. Você tem diferentes variações de botões - primário, secundário, etc.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WYPVvQ2W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2A5bKLrRuD-ujw3hCm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WYPVvQ2W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2A5bKLrRuD-ujw3hCm.png" alt="Botões" width="720" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você deve ter um componente separado para cada tipo?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PrimaryButton&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/PrimaryButton&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SecondaryButton&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/SecondaryButton&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ou usar uma prop?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;secondary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Continuando, como você deveria chamar essa prop? variant? type? Você chegou a considerar que &lt;code&gt;type&lt;/code&gt; é uma atributo reservado do elemento HTML &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;? Esse é o tipo de decisão que você precisará fazer aos construir sua biblioteca de componentes.&lt;/p&gt;

&lt;p&gt;Algumas outras coisas pra você considerar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Você deveria permitir a quem usar sua biblioteca de &lt;a href="https://evergreen.segment.com/components/layout-primitives"&gt;passar propriedades CSS&lt;/a&gt; pro component React, ou eles deveriam ter que estender/wrappar componentes para alcançar o estilo desejado? Se você escolher o primeiro, considere &lt;a href="https://github.com/styled-system/styled-system"&gt;styled-system&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Você deve construir um comportamento de loading &lt;a href="https://react.carbondesignsystem.com/?path=/story/accordion--skeleton"&gt;direto no componente&lt;/a&gt;, ou deveria existir um &lt;a href="https://www.npmjs.com/package/react-loading-skeleton"&gt;componente genérico&lt;/a&gt; para isso (spinner, skeleton)?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Como vocoê deve testar de forma pura o visual de componentes? &lt;a href="https://jestjs.io/docs/snapshot-testing"&gt;Teste de Snapshot&lt;/a&gt;? &lt;a href="https://www.chromatic.com/"&gt;Visual diff testing&lt;/a&gt;?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Como os desenvolvedores precisarão fazer para integrar sua biblioteca de componentes? Deve haver uma &lt;a href="https://cssdeck.com/blog/what-is-a-css-reset/"&gt;redefinição de estilo global&lt;/a&gt;? Eles devem adicionar algum &lt;a href="https://github.com/umijs/babel-plugin-import"&gt;plugin do Babel&lt;/a&gt;?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Você deveria utilizar &lt;a href="https://www.conventionalcommits.org/en/v1.0.0-beta.4/"&gt;Conventional Commits&lt;/a&gt; para gerar automaticamente um changelog?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Seus componentes precisarão estar presentes no ambiente web e mobile? Considere usar o &lt;a href="https://github.com/necolas/react-native-web"&gt;React Native Web&lt;/a&gt; para compartilhar seus componentes entre as plataformas.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Escolha uma plataforma de documentação
&lt;/h2&gt;

&lt;p&gt;Você precisa de uma plataforma para exibir seu desygn sistem. Se você está apenas começando, eu recomendaria usar o &lt;a href="https://medium.com/storybookjs/storybook-docs-sneak-peak-5be78445094a"&gt;Storybook Docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dna7VEnk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AlHyJCKJ8vsW7r-xP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dna7VEnk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AlHyJCKJ8vsW7r-xP.png" alt="Storybook Docs" width="720" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Essa combinação alcançará o resultado de outras plataformas semelhantes, como &lt;a href="https://github.com/doczjs/docz"&gt;Docz&lt;/a&gt;, &lt;a href="https://react-styleguidist.js.org/"&gt;Styleguidist&lt;/a&gt; e &lt;a href="https://docusaurus.io/"&gt;Docusaurus&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copie facilmente trechos de código de exemplos de componentes&lt;/li&gt;
&lt;li&gt;Gere automaticamente uma tabela de props com base em prop-types e defaultProps&lt;/li&gt;
&lt;li&gt;Facilmente veja as variações de um componente&lt;/li&gt;
&lt;li&gt;Escreva documentação utilizando MDX&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l7K35qIB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AqJ8P3b8FdiwBhXv_.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l7K35qIB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AqJ8P3b8FdiwBhXv_.png" alt="Storybook Flow" width="720" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se você é inflexível em seu design system refletindo sua marca e sua biblioteca de componentes, eu recomendaria uma solução personalizada usando &lt;a href="https://mdxjs.com/"&gt;MDX&lt;/a&gt;. Isso permitirá que você insira componentes React dentro de arquivos Markdown. &lt;a href="https://github.com/leerob/leerob.io"&gt;O blog que você está lendo agora usa isso&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ter uma solução verdadeiramente personalizada permite controle total sobre sua documentação. Um exemplo pelo qual estou extremamente impressionado é o &lt;a href="https://atomizecode.com/docs/react/atoms/"&gt;Atomize React&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YjYqxRSk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AFSKvnb06vafZues_.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YjYqxRSk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fit:720/format:webp/0%2AFSKvnb06vafZues_.png" alt="Atomize React" width="720" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Escreva uma documentação do design system
&lt;/h2&gt;

&lt;p&gt;Agora que você escolheu uma plataforma para documentar, é a hora de escrever. Você deve incluir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Processo de instalação e configuração da biblioteca de componentes&lt;/li&gt;
&lt;li&gt;Definições de props e types para cada componente&lt;/li&gt;
&lt;li&gt;Exemplos de componentes junto com trechos de código copiáveis&lt;/li&gt;
&lt;li&gt;Escolhas de tecnologia e racional das escolhas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Também considere colocar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uma sessão de "Começando" com um tutorial&lt;/li&gt;
&lt;li&gt;Informações sobre como trabalhar com temas&lt;/li&gt;
&lt;li&gt;Um code playground para interagir com os componentes&lt;/li&gt;
&lt;li&gt;Modelos prontos de UI para escolher&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Passei muito tempo no ano passado pensando em design systems. Construir uma biblioteca de componentes do zero me deu uma nova apreciação pela quantidade de trabalho que envolve o desenvolvimento front-end e o design. Abaixo, você encontrará uma lista de design systems que me inspiraram e servem como ótimas referências.&lt;/p&gt;

&lt;p&gt;Sinta-se à vontade para &lt;a href="//mailto:me@leerob.io"&gt;entrar em contato&lt;/a&gt; se quiser conversar sobre a construção de design systems.&lt;/p&gt;

&lt;h1&gt;
  
  
  Referências
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Design Systems
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://polaris.shopify.com/"&gt;Shopify's Polaris&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://evergreen.segment.com"&gt;Segment's Evergreen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://eva.design"&gt;Eva Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vercel.com/design"&gt;Vercel's Design System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ant.design"&gt;Ant Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.carbondesignsystem.com"&gt;IBM's Carbon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/storybookjs/design-system"&gt;Storybook's Design System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.radix-ui.com"&gt;Modulz's Radix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://primer.style"&gt;GitHub's Primer  &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blueprintjs.com"&gt;Palantir's Blueprint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://atlassian.design"&gt;Atlassian's Design System&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://chakra-ui.com"&gt;Chakra UI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Programação AHA</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Fri, 16 Dec 2022 13:59:45 +0000</pubDate>
      <link>https://dev.to/allangrds/programacao-aha-280m</link>
      <guid>https://dev.to/allangrds/programacao-aha-280m</guid>
      <description>&lt;p&gt;Esse artigo é uma tradução do artigo original &lt;a href="https://kentcdodds.com/blog/aha-programming" rel="noopener noreferrer"&gt;AHA Programming&lt;/a&gt; criado por &lt;a href="https://kentcdodds.com/" rel="noopener noreferrer"&gt;Kent C. Dodds&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Veja minha talk: Programação AHA
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/wuVy7rwkCfc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  DRY
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself" rel="noopener noreferrer"&gt;DRY (um acrônimo para "Don't Repeat Yourself", traduzindo "Não se repita")&lt;/a&gt;, é um antigo princípio de software que a Wikipedia resume assim:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cada porção de conhecimento em um sistema deve possuir uma representação única, de autoridade e livre de ambiguidades em todo o sistema.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essa geralmente é uma boa prática que eu adoto(embora de forma menos dogmática do que a definição encoraja). O maior problema que tive com &lt;a href="https://en.wikipedia.org/wiki/Duplicate_code" rel="noopener noreferrer"&gt;duplicação de código&lt;/a&gt;(aka copia/cola, basicamente a antítese do &lt;em&gt;&lt;code&gt;DRY&lt;/code&gt;&lt;/em&gt;) é perceber que tinha um bug, o corrigi, e depois encontrei esse bug de novo em outro lugar, e precisei consertá-lo novamente.&lt;/p&gt;

&lt;p&gt;Teve uma vez que peguei um código que pegava pesado com essa duplicação de código, e precisei corrigir um bug em oito lugares diferentes! Pensa em alguém irritasdo! Abstrair esse código em uma função para ser chgamada de qualquer lugar, teria ajudado MUITO.&lt;/p&gt;

&lt;h2&gt;
  
  
  WET
&lt;/h2&gt;

&lt;p&gt;Aqui outro conceito que a galera chamou de WET(Write Everything Twice, traduzindo "Escreva tudo duas vezes"). Ele é igualmente dogmático e normativo. &lt;a href="https://twitter.com/CallMeWuz" rel="noopener noreferrer"&gt;Conlin Durbin&lt;/a&gt; &lt;a href="https://dev.to/wuz/stop-trying-to-be-so-dry-instead-write-everything-twice-wet-5g33"&gt;a definiu como&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Você pode se perguntar "Eu não escrevi isso antes?" duas vezes, mas nunca três.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nessa mesma codebase, existiam abstrações que chegavam ao extremo, mais atrapalhando do que ajudando. Era um código em AngularJS com muitos controllers, e era passado o &lt;code&gt;this&lt;/code&gt; para uma função que poderia corrigir métodos e propriedades para &lt;em&gt;&lt;code&gt;this&lt;/code&gt;&lt;/em&gt; de uma forma aprimorando a instância do controller com certas habilidades. Uma espécie de pseudo-herança, eu acho. Foi SUPER confuso, difícil de entender, e eu fiquei com medo de fazer qualquer alteração nessa área da codebase.&lt;/p&gt;

&lt;p&gt;O código foi reutilizado em muito mais que três lugares, mas a abstração era ruim e desejei que o código tivesse sido duplicado.&lt;/p&gt;

&lt;h2&gt;
  
  
  AHA
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;&lt;code&gt;AHA&lt;/code&gt;&lt;/em&gt; (se pronuncia "Aha!" mesmo) é um acrônico que &lt;a href="https://twitter.com/cherthedev/status/1112819136147742720" rel="noopener noreferrer"&gt;eu consegui de&lt;/a&gt; &lt;a href="https://twitter.com/cherthedev" rel="noopener noreferrer"&gt;Cher Scarlett&lt;/a&gt; que significa&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Avoid Hasty Abstractions(Evite abstrações precipitadas)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A maneira como penso nesse princípio foi lindamente descrita por &lt;a href="https://twitter.com/sandimetz" rel="noopener noreferrer"&gt;Sandi Metz&lt;/a&gt;, que &lt;a href="https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction" rel="noopener noreferrer"&gt;escreveu&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;prefira duplicação a uma abstração errada&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Essa é uma regra de ouro muito boa, e quero que você a leia novamente, então leia o post de Sandi sobre o assunto: &lt;a href="https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction" rel="noopener noreferrer"&gt;A Abstração Errada&lt;/a&gt;. É fantástico.&lt;/p&gt;

&lt;p&gt;Aqui está outro importante princípio relacionado que desejo te mostrar:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Optimize for change first&lt;br&gt;
Otimize para mudar primeiro&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Acho que o ponto chave é que não sabemos pra onde irá nosso código. Podemos investir semanas otimizando e deixando o código mais performático, ou criando a melhor API para nossa nova abstraçnao, apenas apra descobrir que no dia seguinte nós assumimos suposições erradas, e a API precisará ser completamente refeita, ou a funcionalidade para o qual o código foi escrito não é mais necessária. Não sabemos com certeza. Tudo o que podemos realmente ter certeza é que as coisas provavelmente mudarão, e se nunca mudarem, não tocaremos no código de qualquer maneira, então quem se importa com sua aparência?&lt;/p&gt;

&lt;p&gt;Agora, não me entenda errado, não estou sugerindo anarquia. Estou sugerindo que devemos ficar atentos ao fato de que não sabemos quais requisitos serão colocados em nosso código no futuro.&lt;/p&gt;

&lt;p&gt;Então, estou tranquilo com duplicação de código até que você esteja bem confiante dos casos de uso desse código duplicado. Quais partes do código são diferentes que dariam bons argumentos para sua função? assim que você tiver alguns lugares onde esse código está, as semelhanças gritarão com você por abstração e você estará no estado de espírito para fornecer essa abstração.&lt;/p&gt;

&lt;p&gt;Se você abstrair cedo, porém, achará que a função ou componente é perfeito para seu caso de uso e, portanto, apenas dobrará o código para se adequar ao seu novo caso de uso. Isso continuará várias vezes até que a abstração seja basicamente toda a sua aplicação em instruções de &lt;em&gt;&lt;code&gt;if&lt;/code&gt;&lt;/em&gt; e loops 😂😭&lt;/p&gt;

&lt;p&gt;Há alguns anos, fui contratado para revisar a codebase de uma empresa e usei uma ferramenta chamada &lt;a href="https://github.com/danielstjules/jsinspect" rel="noopener noreferrer"&gt;jsinspect&lt;/a&gt; para identificar pedaços de código copiado/colado, e mostrar a eles oportunidades de abstração. Eles tinham um monte de código duplicado e, da minha perspectiva, era óbvio como as abstrações deveriam ser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Acho que a grande lição&lt;/strong&gt; sobre programação "AHA" é que você não deve ser dogmático sobre quando começar a escrever abstrações, mas sim escrever a abstração quando parecer certo, e não ter medo de duplicar o código até chegar lá.&lt;/p&gt;

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

&lt;p&gt;Sinto que uma abordagem comedida e pragmática aos princípios de software é importante. Por isso eu prefiro &lt;em&gt;&lt;code&gt;AHA&lt;/code&gt;&lt;/em&gt; ao invés de &lt;em&gt;&lt;code&gt;DRY&lt;/code&gt;&lt;/em&gt; ou &lt;em&gt;&lt;code&gt;WET&lt;/code&gt;&lt;/em&gt;. Elá é focada em te ajudar a ficar ligado em suas abstrações, sem fornecer regras rígidas para quando é ou não certo abstrair algum código em uma função ou módulo.&lt;/p&gt;

&lt;p&gt;Espero que tenha te ajudado. Se você está com abstrações ruins até o talo, fique de boas. A Sandi tem algumas dicas pra você de como sair disso! &lt;a href="https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction" rel="noopener noreferrer"&gt;Basta ler a postagem de seu blog&lt;/a&gt;. Boa sorte!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
    </item>
    <item>
      <title>Automatizando a criação de arquivos com Plop.js</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Fri, 16 Dec 2022 13:19:07 +0000</pubDate>
      <link>https://dev.to/allangrds/automatizando-a-criacao-de-arquivos-com-plopjs-558h</link>
      <guid>https://dev.to/allangrds/automatizando-a-criacao-de-arquivos-com-plopjs-558h</guid>
      <description>&lt;h2&gt;
  
  
  Repetição que poderia não existir
&lt;/h2&gt;

&lt;p&gt;Não é que eu me esforce muito para tal, mas criar sempre aquela mesma estruturinha e conteúdo base de arquivos é aquele tipo de tarefa que poderia não existir.&lt;/p&gt;

&lt;p&gt;Segue abaixo um exemplo do que eu crio quando insiro um novo componente em meu projeto React:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//index.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./MyComponent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MyComponentProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./MyComponent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//MyComponent.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;MyComponentProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;MyComponentProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//MyComponent.stories.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ComponentStory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ComponentMeta&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@storybook/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MyComponentProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Components/MyComponent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ComponentMeta&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ComponentStory&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MyComponentProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyComponent&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Default&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;
&lt;span class="nx"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;João Banana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;//MyComponent.test.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MyComponentProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;João Banana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defaultProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MyComponentProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defaultProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MyComponent&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;)&lt;/span&gt;

  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should render the component correctly&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;renderComponent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No final das contas o que eu tenho é um componente, arquivo do storybook e arquivo do teste. Por mais que cada componente seja diferente e os testes e suas propriedades mudem, existe uma base de código presente em todos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conhecendo o Plop.js
&lt;/h2&gt;

&lt;p&gt;O &lt;a href="https://plopjs.com"&gt;Plop.js&lt;/a&gt; permite criarmos comandos para gerar arquivos com a estrutura que desejarmos.&lt;/p&gt;

&lt;p&gt;Basta rodar um &lt;code&gt;npm run plop&lt;/code&gt; para ver algo como a imagem abaixo, escrever algumas informações e ter toda aquela estrutura que mostrei anteriormente em uma pasta nova de meu projeto.&lt;/p&gt;

&lt;p&gt;&lt;a href="/assets/uploads/posts/plop/plop.png" class="article-body-image-wrapper"&gt;&lt;img src="/assets/uploads/posts/plop/plop.png" alt="plop cli"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalando
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; plop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Insira o comando abaixo em seu &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"plop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"plop"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Criando nosso gerador de componentes
&lt;/h2&gt;

&lt;p&gt;Na raíz de seu projeto, crie o arquivo &lt;code&gt;plopfile.js&lt;/code&gt; com o seguinte conteúdo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;componentGenerator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./plop/component/index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;componentGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estamos criando uma função que o Plop.js executará passando o objeto &lt;code&gt;plop&lt;/code&gt; como parâmetro. Com esse objeto executaremos funções para criar nosso gerador.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando um arquivo gerador base para componentes
&lt;/h2&gt;

&lt;p&gt;O que eu desejo com o Plop.js é que apenas com o nome de meu componente ele crie uma pasta com toda a estrutura de código e arquivos. Para isso, vamos criar um arquivo no caminho &lt;code&gt;plop/component/index.js&lt;/code&gt; com o seguinte conteúdo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;plop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;this is a skeleton plopfile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;prompts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="c1"&gt;// array com perguntas que serão mostradas no terminal&lt;/span&gt;
    &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;  &lt;span class="c1"&gt;// array de ações para serem executadas após respoder as perguntas&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse é o conteúdo base de um gerador. Você usa a função &lt;code&gt;setGenerator&lt;/code&gt; com 2 parâmetros. O primeiro, o nome do gerador, e o segundo, um objeto com 3 opções:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;description&lt;/code&gt;: descrição do gerador;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;prompts&lt;/code&gt;: array com perguntas que serão mostradas no terminal;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;actions&lt;/code&gt;: array de ações para serem executadas após respoder as perguntas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sabendo disso, vamos começar a primeira e única pergunta de nosso gerador, que é saber qual o nome do componente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;plop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;React component generator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;prompts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;component_name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter the component name: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="/assets/uploads/posts/plop/plop.png" class="article-body-image-wrapper"&gt;&lt;img src="/assets/uploads/posts/plop/plop.png" alt="plop cli"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com esse código estamos configurando justamente isso que você está vendo. Um input com o texto "Enter the component name:" e com o nome "component_name", que usaremos nas actions.&lt;/p&gt;

&lt;p&gt;Para finalizarmos essa parte, agora precisamos definir as ações. O que eu desejo é que sejam criados 4 arquivos diferentes, cada um com sua configuração e código diferente. Para isso, vamos deixar o código assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;plop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;React component generator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;prompts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;component_name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter the component name: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/components/{{pascalCase component_name}}/index.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;plop/component/index-template.hbs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/components/{{pascalCase component_name}}/{{pascalCase component_name}}.tsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;plop/component/component-template.hbs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/components/{{pascalCase component_name}}/{{pascalCase component_name}}.stories.tsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;plop/component/stories-template.hbs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;add&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/components/{{pascalCase component_name}}/{{pascalCase component_name}}.test.tsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;templateFile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;plop/component/test-template.hbs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos entender cada um das chaves presentes nesse objeto:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;type: 'add'&lt;/code&gt;: estou dizendo que desejo adicionar um único arquivo em determinado caminho de meu projeto;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;path: './src/components/{{pascalCase component_name}}/index.ts'&lt;/code&gt;: aqui eu informo o caminho de meu arquivo, e perceba uma coisa, como desejo criar o arquivo &lt;code&gt;index.ts&lt;/code&gt; dentro de uma nova pasta, eu preciso pegar o nome do componente que foi colocado na CLI, e para isso coloco seu nome(&lt;code&gt;component_name&lt;/code&gt;) entre colchetes duplos. Como desejo que a pasta siga o padrão &lt;code&gt;PascalCase&lt;/code&gt;, coloco essa informação com espaço antes do valor que desejo formatar.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;templateFile: 'plop/component/index-template.hbs'&lt;/code&gt;: o caminho do arquivo de template que será usado para criar esse arquivo.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Criando nossos templates de arquivos
&lt;/h2&gt;

&lt;p&gt;Para usar o código abaixo crie o arquivo &lt;code&gt;index-template.hbs&lt;/code&gt; na raíz de &lt;code&gt;plop/component/&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight handlebars"&gt;&lt;code&gt;//index-template.hbs
export { &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt; } from './&lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os valores obtidos no preenchimento pela CLI também estão disponíveis aqui, e também com funções de formatação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight handlebars"&gt;&lt;code&gt;//component-template.hbs
import * as React from 'react'

export type &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;Props = {
  name: string;
}

export const &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt; = ({ name }: &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;Props) =&amp;gt; (
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
    { name }
  &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight handlebars"&gt;&lt;code&gt;//stories-template.hbs
import * as React from 'react'
import { ComponentStory, ComponentMeta } from '@storybook/react'

import { &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt; } from './&lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;'
import type { &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;Props } from './&lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;'

export default {
  title: 'Components/&lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;',
  component: &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;,
} as ComponentMeta&lt;span class="nt"&gt;&amp;lt;typeof&lt;/span&gt; &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

const Template: ComponentStory&lt;span class="nt"&gt;&amp;lt;typeof&lt;/span&gt; &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; = (args: &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;Props) =&amp;gt; (
  &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt; &lt;span class="err"&gt;{...&lt;/span&gt;&lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
)

export const Default = Template.bind({})
Default.args = {
  name: 'João Banana',
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight handlebars"&gt;&lt;code&gt;//test-template.hbs

import * as React from 'react'
import { render, screen } from '@testing-library/react'

import { &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt; } from '.'
import type { &lt;span class="k"&gt;{{&lt;/span&gt;&lt;span class="nv"&gt;pascalCase&lt;/span&gt; &lt;span class="nv"&gt;component_name&lt;/span&gt;&lt;span class="k"&gt;}}&lt;/span&gt;Props } from '.'

const defaultProps = {
  name: 'João Banana',
}

const selectors = {
  name: (name = defaultProps.name) =&amp;gt; screen.getByText(name),
}

const renderComponent = (props: MyComponentProps = defaultProps) =&amp;gt;
  render(&lt;span class="nt"&gt;&amp;lt;MyComponent&lt;/span&gt; &lt;span class="err"&gt;{...&lt;/span&gt;&lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;)

test('should render the component correctly', async () =&amp;gt; {
  renderComponent()

  expect(selectors.name()).toBeInTheDocument()
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>useEffect vs useLayoutEffect</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Thu, 03 Feb 2022 12:16:14 +0000</pubDate>
      <link>https://dev.to/allangrds/useeffect-vs-uselayouteffect-1dh2</link>
      <guid>https://dev.to/allangrds/useeffect-vs-uselayouteffect-1dh2</guid>
      <description>&lt;p&gt;Esse artigo é uma tradução do artigo original &lt;a href="https://kentcdodds.com/blog/useeffect-vs-uselayouteffect"&gt;useEffect vs useLayoutEffect&lt;/a&gt; criado por &lt;a href="https://kentcdodds.com/blog/useeffect-vs-uselayouteffect"&gt;Kent C. Dodds&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ambas opções podem ser usadas para fazer a mesma coisa, mas elas tem casos de uso ligeiramente diferentes. Então, aqui estão algumas regras para você considerar ao decidir qual &lt;a href="https://reactjs.org/docs/hooks-intro.html"&gt;React Hook&lt;/a&gt; usar.&lt;/p&gt;

&lt;h1&gt;
  
  
  useEffect
&lt;/h1&gt;

&lt;p&gt;99% das vezes é esse que você precisará usar. Quando seus hooks são estáveis e você refatora as suas class components para hooks, aos poucos você irá mudar códigos de &lt;code&gt;componentDidMount&lt;/code&gt;, &lt;code&gt;componentDidUpdate&lt;/code&gt; e &lt;code&gt;componentWillUnmount&lt;/code&gt; para &lt;code&gt;useEffect&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O único problema dele é ser apenas executado após o React renderizar seu componente, garantindo que ele não bloqueie a renderização do navegador. Isso é diferente do comportamento de class components onde &lt;code&gt;componentDidMount&lt;/code&gt; e &lt;code&gt;componentDidUpdate&lt;/code&gt; rodam de forma síncrona após a renderização. É mais eficiente dessa maneira e na maioria das vezes é isso que você precisará.&lt;/p&gt;

&lt;p&gt;Entretanto, se o uso desse hook estiver mudando o DOM(via DOM node ref) &lt;strong&gt;e&lt;/strong&gt; a mutação do DOM alterar a aparência do nó do DOM entre o momento que ele é renderizado e o momento que seu hook o altera, então você não deseja usar o &lt;code&gt;useEffect&lt;/code&gt;. Você na verdade quer usar o &lt;code&gt;useLayoutEffect&lt;/code&gt;. Caso contrário, o usuário poderá ver uma mudança rápida na interface quando suas mudanças do DOM forem realizadas. Essa é praticamente a única vez que você deseja evitar &lt;code&gt;useEffect&lt;/code&gt; e usar &lt;code&gt;useLayoutEffect&lt;/code&gt; em vez disso.&lt;/p&gt;

&lt;h1&gt;
  
  
  useLayoutEffect
&lt;/h1&gt;

&lt;p&gt;Executado de forma síncrona imediatamente após o React fazer todas as alterações no DOM. Pode ser útil se você precisar fazer medições DOM (como obter a posição de rolagem ou outros estilos para um elemento) e depois fazer alterações no DOM ou acionar uma nova renderização síncrona atualizando o estado.&lt;/p&gt;

&lt;p&gt;No que diz respeito ao momento, ele funciona da mesma forma que &lt;code&gt;componentDidMount&lt;/code&gt; e &lt;code&gt;componentDidUpdate&lt;/code&gt;. Seu código é executado imediamente após o DOM ser atualizado, mas antes que o navegador tenha a chance de "renderizar" essas alterações (o usuário não vê as atualizações até que o navegador tenha re-renderizado).&lt;/p&gt;

&lt;h1&gt;
  
  
  Resumo
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;useLayoutEffect&lt;/code&gt;: Se você precisar alterar o DOM e/ou precisar realizar medições.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;useEffect&lt;/code&gt;: Se você não precisa interagir com o DOM ou suas alterações no DOM não são observáveis (sério, na maioria das vezes você deve usar isso).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Um caso diferente
&lt;/h1&gt;

&lt;p&gt;Um caso onde você possa querer usar &lt;code&gt;useLayoutEffect&lt;/code&gt; ao invés de &lt;code&gt;useEffect&lt;/code&gt; é quando você está atualizando um valor(como &lt;code&gt;ref&lt;/code&gt;) e você quer ter certeza de que está atualizado antes que qualquer outro código seja executado. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;valor qualquer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// depois, em outro hook ou algo do tipo&lt;/span&gt;
&lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useLayoutEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- isso aqui loga o valor antigo pois é executado primeiro!&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em casos como esse, use &lt;code&gt;useLayoutEffect&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;É tudo sobre padrões. O comportamento padrão é permitir que o navegador renderize novamente com base nas atualizações do DOM antes que o React execute seu código. Isso significa que seu código não bloqueará o navegador e o usuário verá as atualizações do DOM mais cedo. Portanto, fique com &lt;code&gt;useEffect&lt;/code&gt; na maioria das vezes.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Explicando a coerção de tipos em Javascript</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Thu, 15 Apr 2021 14:44:12 +0000</pubDate>
      <link>https://dev.to/allangrds/explicando-a-coercao-de-tipos-em-javascript-1j12</link>
      <guid>https://dev.to/allangrds/explicando-a-coercao-de-tipos-em-javascript-1j12</guid>
      <description>&lt;p&gt;Esse texto é uma tradução livre do artigo&lt;a href="https://medium.freecodecamp.org/js-type-coercion-explained-27ba3d9a2839"&gt;JavaScript type coercion explained&lt;/a&gt;de&lt;a href="https://medium.freecodecamp.org/@alexeysamoshkin?source=post_header_lockup"&gt;Alexey Samoshkin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[Edit 02/05/2018]&lt;/strong&gt;: Esse post está&lt;a href="https://medium.com/@sergeybulavyk/%D0%BF%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%82%D0%B8%D0%BF%D0%BE%D0%B2-%D0%B2-javascript-35a15ddfc333"&gt;disponível em Russo&lt;/a&gt;. Palmas a&lt;a href="https://medium.com/u/8ce091dcbd92?source=post_page-----d6c9203c4e5----------------------"&gt;Serj Bulavyk&lt;/a&gt;por seus esforços.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coerção de tipos (type coercion)&lt;/strong&gt;é o processo de conversão de um valor de um tipo, para outro (como a conversão de uma string para um número, um objeto para um booleano e etc). Qualquer tipo, seja primitivo ou um objeto, é um sujeito válido para coerção de tipo. Para recordar, os primitivos são: number, string, booleano, null, undefined + Symbol (adicionado no ES6).&lt;/p&gt;

&lt;p&gt;Como um exemplo de coerção de tipo em prática, veja o link&lt;a href="https://dorey.github.io/JavaScript-Equality-Table/"&gt;JavaScript Comparison Table&lt;/a&gt;, que mostra como o operador de igualdade&lt;code&gt;==&lt;/code&gt;se comporta para diferentes tipos. Essa matriz parece assustadora devido à coerção de tipo implícita que o operador&lt;code&gt;==&lt;/code&gt;faz, e dificilmente será possível lembrar de todas essas combinações. E você não precisa fazer isso — apenas aprenda os princípios básicos da coerção de tipos.&lt;/p&gt;

&lt;p&gt;Esse artigo vai a fundo de como a coerção de tipos funciona no Javascript, e irá prepará-lo com o conhecimento básico para que você possa sentir-se confiante ao explicar sobre as expressões. Ao final do artigo, mostrarei as respostas e as explicarei.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;false&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;false&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;
&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;!+&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;+!&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sim, essa é uma lista boba de coisas que você pode fazer como desenvolvedor. Em 90% dos casos é melhor evitar a coerção de tipos implícita. Considere essa lista como exercícios para aprendizagem para testar seu conhecimento de como a coerção de tipos funciona. Se estiver entendiado, você pode encontrar mais em&lt;a href="https://wtfjs.com/"&gt;wtfjs.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A propósito, você pode encontrar perguntas disso em entrevistas para vagas de Javascript. Então continue lendo 😄.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coerção Implícita vs Explícita
&lt;/h2&gt;

&lt;p&gt;Coerção de tipos pode ser explícita ou implícita.&lt;/p&gt;

&lt;p&gt;Quando um desenvolvedor deseja converter um tipo escrevendo algo como,&lt;code&gt;Number(valor)&lt;/code&gt;, isso é chamado de*&lt;em&gt;coerção de tipos explícita&lt;/em&gt;&lt;em&gt;(&lt;/em&gt;&lt;em&gt;explicit type coercion&lt;/em&gt;&lt;em&gt;ou&lt;/em&gt;&lt;em&gt;type casting.&lt;/em&gt;*&lt;/p&gt;

&lt;p&gt;Já que o Javascript é uma linguagem fracamente tipada (weakly-typed language), valores também podem ser convertidos entre diferentes tipos automaticamente, e isso é chamado de*&lt;em&gt;coerção de tipos implícita (implicit type coercion).&lt;/em&gt;*Isso acontece quando você atribui operados para valores de diferentes tipos, como&lt;code&gt;1 == null&lt;/code&gt;,&lt;code&gt;2/’5'&lt;/code&gt;,&lt;code&gt;null + new Date()&lt;/code&gt;, ou isso pode decorrer do contexto, como usar&lt;code&gt;if (value) {…}&lt;/code&gt;, onde&lt;code&gt;value&lt;/code&gt;é forçado a retornar um booleano.&lt;/p&gt;

&lt;p&gt;Um operador que não desencadeia a coerção de tipos implítica é&lt;code&gt;===&lt;/code&gt;, que é chamado de operador restrito de igualdade (strict equality operator). O operador de igualdade&lt;code&gt;==&lt;/code&gt;por outro lado, faz a comparação e ativa a coerção de tipos, se necessário.&lt;/p&gt;

&lt;p&gt;Coerção de tipo implícito é uma faca de dois gumes: é uma grande fonte de frustração e defeitos, mas também um mecanismo útil que nos permite escrever menos código sem perder a legibilidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Três tipos de conversão
&lt;/h2&gt;

&lt;p&gt;A primeira regra que precisamos saber é que existem apenas 3 tipos de conversão no Javascript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;para string;&lt;/li&gt;
&lt;li&gt;para boolean;&lt;/li&gt;
&lt;li&gt;para number.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A segunda, é que a lógica para conversão de tipos primitivos e objetos funcionam de forma diferente, mas ambos só podem ser convertido nessas 3 maneiras.&lt;/p&gt;

&lt;p&gt;Vamos começar primeiro com os primitivos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conversão de String
&lt;/h2&gt;

&lt;p&gt;Para indicar a conversão explícita de valores para string use a função&lt;code&gt;String()&lt;/code&gt;. A coerção implícita é ativada pelo operador binário&lt;code&gt;+&lt;/code&gt;, quando qualquer operando é uma string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// explícito&lt;/span&gt;
&lt;span class="mi"&gt;123&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;    &lt;span class="c1"&gt;// implícito&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Todos os valores primitivos são convertidos em strings naturalmente, como você poderia esperar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                   &lt;span class="c1"&gt;// '123'&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;12.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;// '-12.3'&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="c1"&gt;// 'null'&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;             &lt;span class="c1"&gt;// 'undefined'&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="c1"&gt;// 'true'&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;// 'false'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A conversão de Symbol é um pouco complicada, porque só pode ser convertida explicitamente, mas não implicitamente. Leia mais nas regras de coerção de tipos do&lt;a href="https://leanpub.com/understandinges6/read/#leanpub-auto-symbol-coercion"&gt;Symbol&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my symbol&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;// 'Symbol(my symbol)'&lt;/span&gt;
&lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my symbol&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;// TypeError é lançado&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conversão de Boolean
&lt;/h2&gt;

&lt;p&gt;Para indicar a conversão explícita de valores para boolean use a função&lt;code&gt;Boolean()&lt;/code&gt;. A conversão implícita ocorre no contexto lógico ou é ativada por operadores lógicos (&lt;code&gt;||&amp;amp;&amp;amp;!&lt;/code&gt;) .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="c1"&gt;// explícito&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;      &lt;span class="c1"&gt;// implícito devido ao contexto lógico&lt;/span&gt;
&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;                 &lt;span class="c1"&gt;// implícito devido ao operador lógico&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;        &lt;span class="c1"&gt;// implícito devido ao operador lógico&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Observação&lt;/strong&gt;: Operadores lógicos como&lt;code&gt;||&lt;/code&gt;e&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;fazem conversões booleanas internamente, mas&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Logical_operators"&gt;na verdade retornam o valor dos operandos&lt;/a&gt;originais, mesmo que eles não sejam booleanos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// retorna o número 123 ao invés de true&lt;/span&gt;
&lt;span class="c1"&gt;// 'hello' e 123 são convertidos para boolean internamente para calcular a expressão&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;//x === 123 é true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assim que houver apenas dois resultados possíveis da conversão booleana:&lt;code&gt;true&lt;/code&gt;ou&lt;code&gt;false&lt;/code&gt;, é mais fácil lembrar a lista de valores falsos (falsy values).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="c1"&gt;// false     &lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;           &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;        &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Qualquer valor não inserido nessa lista ao ser convertido será&lt;code&gt;true&lt;/code&gt;, incluindo objetos, funções,&lt;code&gt;Array&lt;/code&gt;,&lt;code&gt;Date&lt;/code&gt;, tipos definidos pelo usuário e assim por diante. Symbols são considerados como valores verdadeiros (truthy values). Objetos vazios e arrays também:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;             &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;             &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;       &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;              &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conversão Numérica
&lt;/h2&gt;

&lt;p&gt;Para uma conversão explícita aplique a função&lt;code&gt;Number()&lt;/code&gt;, assim como feito com&lt;code&gt;Boolean()&lt;/code&gt;e&lt;code&gt;String()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A conversão implícita é complicada, pois é acionada em mais casos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;operadores de comparação (comparison operators)(&lt;code&gt;&amp;gt;&lt;/code&gt;,&lt;code&gt;&amp;lt;&lt;/code&gt;,&lt;code&gt;&amp;lt;=&lt;/code&gt;,&lt;code&gt;&amp;gt;=&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;operadores bitwise (&lt;code&gt;|&amp;amp;^~&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;operadores aritméticos (&lt;code&gt;-+*/%&lt;/code&gt;). Saiba que usar&lt;code&gt;+&lt;/code&gt;não irá ativar a conversão numérica quando qualquer operando for uma string.&lt;/li&gt;
&lt;li&gt;operador unário&lt;code&gt;+&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;operador de igualdade&lt;code&gt;==&lt;/code&gt;(incl.&lt;code&gt;!=&lt;/code&gt;).\
Perceba que&lt;code&gt;==&lt;/code&gt;não ativa a conversão numérica quando ambos operandos são strings.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;// explícito&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;          &lt;span class="c1"&gt;// implícito&lt;/span&gt;
&lt;span class="mi"&gt;123&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;456&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;    &lt;span class="c1"&gt;// implícito&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;         &lt;span class="c1"&gt;// implícito&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;          &lt;span class="c1"&gt;// implícito&lt;/span&gt;
&lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;        &lt;span class="c1"&gt;// implícito&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abaixo como valores primitivos são convertido para números:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                   &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;              &lt;span class="c1"&gt;// NaN&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                   &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; 12 &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;// 12&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-12.34&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;               &lt;span class="c1"&gt;// -12.34&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                   &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; 12s &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                &lt;span class="c1"&gt;// NaN&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                    &lt;span class="c1"&gt;// 123&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ao converter uma string em número, a engine primeiro remove os espaços em branco com os caracteres&lt;code&gt;\n&lt;/code&gt;e&lt;code&gt;\t&lt;/code&gt;, retornando&lt;code&gt;NaN&lt;/code&gt;se a string tratada não representar um número válido. Se a string estiver vazia, retornará&lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;null&lt;/code&gt;e&lt;code&gt;undefined&lt;/code&gt;são tratados de forma diferentes:&lt;code&gt;null&lt;/code&gt;vira 0, enquanto&lt;code&gt;undefined&lt;/code&gt;se torna&lt;code&gt;NaN&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Symbols não podem ser convertidos em números nem explicitamente nem implicitamente. Além disse,&lt;code&gt;TypeError&lt;/code&gt;é lançado ao invés de silenciosamente converter para&lt;code&gt;NaN&lt;/code&gt;, como acontece para&lt;code&gt;undefined&lt;/code&gt;. Veja mais sobre as regras de conversão de símbolo no MDN.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my symbol&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;    &lt;span class="c1"&gt;// TypeError é lançado&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                 &lt;span class="c1"&gt;// TypeError é lançado&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Existem*&lt;em&gt;duas regras especiais&lt;/em&gt;*para relembrar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Quando aplicamos&lt;code&gt;==&lt;/code&gt;para&lt;code&gt;null&lt;/code&gt;ou&lt;code&gt;undefined&lt;/code&gt;, a conversão numérico não ocorre.&lt;code&gt;null&lt;/code&gt;é apenas igual a&lt;code&gt;null&lt;/code&gt;ou&lt;code&gt;undefined&lt;/code&gt;, e não é igual a mais nada.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;               &lt;span class="c1"&gt;// false, null is not converted to 0&lt;/span&gt;
&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;            &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;       &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.&lt;code&gt;NaN&lt;/code&gt;não é igual a nada que não seja ele mesmo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;we're dealing with NaN here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Coerção de tipos para objetos
&lt;/h2&gt;

&lt;p&gt;Até agora, analisamos a coerção de tipos para valores primitivos. Isso não é muito empolgante.&lt;/p&gt;

&lt;p&gt;Quando isso ocorre com objetos, e a engine encontra expressões como&lt;code&gt;[1] + [2,3]&lt;/code&gt;, primeiramente será preciso converter o objeto para um valor primitivo, que é então convertido pro tipo final. E ainda assim existem apenas três tipos de conversão: numérico, string e booleano.&lt;/p&gt;

&lt;p&gt;O caso mais simples é a conversão para booleano: qualquer valor não primitivo sempre será convertido para&lt;code&gt;true&lt;/code&gt;, não importa se um objeto ou array está vazio ou não.&lt;/p&gt;

&lt;p&gt;Objetos são convertidos para primitivos através da função&lt;code&gt;[[ToPrimitive]]&lt;/code&gt;, que é responsável pela conversão numérica e string.&lt;/p&gt;

&lt;p&gt;Abaixo uma pseudo implementação do método&lt;code&gt;[[ToPrimitive]]&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ToPrimitive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;preferredType&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;preferredType&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;toNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;toNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isPrimitive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isPrimitive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isPrimitive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;toNumber&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isPrimitive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isPrimitive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;[[ToPrimitive]]&lt;/code&gt;é invocado passando dois argumentos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;input: valor a ser convertido;&lt;/li&gt;
&lt;li&gt;preferredType: Tipo escolhido para conversão, podendo ser&lt;code&gt;Number&lt;/code&gt;ou&lt;code&gt;String&lt;/code&gt;. Esse argumento é opcional.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ambas conversões, número e string fazem uso de dois métodos do objeto de entrada (input):&lt;code&gt;valueOf&lt;/code&gt;e&lt;code&gt;toString&lt;/code&gt;. Ambas funções são declaradas no&lt;code&gt;Object.prototype&lt;/code&gt;e, portanto, disponível para qualquer tipo derivado, como&lt;code&gt;Date&lt;/code&gt;,&lt;code&gt;Array&lt;/code&gt;, e etc.&lt;/p&gt;

&lt;p&gt;Em geral, o algoritmo é o seguinte:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Se o input já é do tipo primitivo, retorne-o;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chame a função&lt;code&gt;input.toString()&lt;/code&gt;, se o resultado for do tipo primitivo, retorne-o;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chame a função&lt;code&gt;input.valueOf()&lt;/code&gt;, se o resultado for do tipo primitivo, retorne-o;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Se nem a função&lt;code&gt;input.toString()&lt;/code&gt;ou&lt;code&gt;input.valueOf()&lt;/code&gt;retornar um tipo primitivo, lance&lt;code&gt;TypeError&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Conversões numéricas primeiro chamam a função&lt;code&gt;valueOf&lt;/code&gt;(3) com o fallback&lt;code&gt;toString&lt;/code&gt;(2).&lt;/p&gt;

&lt;p&gt;A conversão de string faz exatamente o oposto:&lt;code&gt;toString&lt;/code&gt;(2) seguido de&lt;code&gt;valueOf&lt;/code&gt;(3).&lt;/p&gt;

&lt;p&gt;A maioria dos tipos internos(built-in) não possui a função&lt;code&gt;valueOf&lt;/code&gt;, ou possui&lt;code&gt;valueOf&lt;/code&gt;retornando o próprio objeto, então é ignorado por não ser do tipo primitivo. É por isso que a conversão de tipos&lt;code&gt;number&lt;/code&gt;e&lt;code&gt;string&lt;/code&gt;podem funcionar da mesma forma — ambos acabam chamando&lt;code&gt;toString()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Operadores diferentes podem acionar a conversão numérica ou de string com a ajuda do parâmetro&lt;code&gt;preferredType&lt;/code&gt;. Mas existem duas exceções: o comparador de igualdade abstrato&lt;code&gt;==&lt;/code&gt;e a opção binária&lt;code&gt;+&lt;/code&gt;acionam modos de conversão padrão (&lt;code&gt;preferredType&lt;/code&gt;não é especificado, ou igual a&lt;code&gt;default&lt;/code&gt;). Nesse caso, a maior dos tipos internos(built-in) assumirão uma conversão numérica como default, exceto&lt;code&gt;Date&lt;/code&gt;que fará uma conversão de string.&lt;/p&gt;

&lt;p&gt;Segue abaixo um exemplo de como se comporta uma conversa de&lt;code&gt;Date&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// obtém a representação em string&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// 'Wed Jan 17 2018 16:15:42'&lt;/span&gt;

&lt;span class="c1"&gt;// obtém a representação numérica, número em milisegundos desde a época do Unix&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;   &lt;span class="c1"&gt;// 1516198542525&lt;/span&gt;

&lt;span class="c1"&gt;// comparara com uma representação de string&lt;/span&gt;
&lt;span class="c1"&gt;// é true, pois "d" foi convertido para a mesma string&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="c1"&gt;// compara com a representação numérica&lt;/span&gt;
&lt;span class="c1"&gt;// false, pois d não foi convertido para um número usando valueOf()&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// false&lt;/span&gt;

&lt;span class="c1"&gt;// O resulado é 'Wed Jan 17 2018 16:15:42Wed Jan 17 2018 16:15:42'&lt;/span&gt;
&lt;span class="c1"&gt;// '+' funcional igual ao '==', aciona o modo padrão de conversão&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// O resultado é 0, pois o operador '-' aciona explicitamente a conversão numérica, não a padrão&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você pode sobrescrever os métodos padrão&lt;code&gt;toString()&lt;/code&gt;e&lt;code&gt;valueOf()&lt;/code&gt;para conectar-se à lógica de conversão objeto para primitivo(object-to-primitive).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;101&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Prop: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nf"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;  &lt;span class="c1"&gt;// 'Prop: 101'&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;// '101'&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;         &lt;span class="c1"&gt;//  101&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;    &lt;span class="c1"&gt;//  true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe como&lt;code&gt;obj + ‘’&lt;/code&gt;retorna&lt;code&gt;'101'&lt;/code&gt;como uma string. O operador&lt;code&gt;+&lt;/code&gt;dispara um modo de conversão padrão, e como dito anteriormente,&lt;code&gt;Object&lt;/code&gt;assume a conversão numérico como padrão, usando portanto, o método&lt;code&gt;valueOf()&lt;/code&gt;ao invés do&lt;code&gt;toString()&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Método do ES6 - Symbol.toPrimitive
&lt;/h2&gt;

&lt;p&gt;No ES5 você pode conectar a lógica de conversão de objeto a primitivo(object-to-primitive) substituindo os métodos&lt;code&gt;toString&lt;/code&gt;e&lt;code&gt;valueOf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;No ES6 você pode ir mais longe, podendo substituir completamente a rotina interna&lt;code&gt;[[ToPrimitive]]&lt;/code&gt;implementando o método&lt;code&gt;[Symbol.toPrimtive]&lt;/code&gt;em um objeto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Disk&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;capacity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toPrimitive&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;hint&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Capacity: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;capacity&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; bytes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// convert to KiB&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;capacity&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// assume numeric conversion as a default&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;capacity&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 1MiB disk&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;disk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Disk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;// Capacity: 1048576 bytes&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;// '1024'&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;        &lt;span class="c1"&gt;// 1024&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;disk&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exemplos
&lt;/h2&gt;

&lt;p&gt;Sabendo a teoria, agora vamos aos exemplos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;             &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;6&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;                 &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;        &lt;span class="c1"&gt;// 'number153'&lt;/span&gt;
&lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;        &lt;span class="c1"&gt;// '18number'&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;               &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;          &lt;span class="c1"&gt;// 'fooNaN'&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;           &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;false&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;         &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;               &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;false&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;    &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;             &lt;span class="c1"&gt;// true &lt;/span&gt;
&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;            &lt;span class="c1"&gt;// 'null1'&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;       &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;             &lt;span class="c1"&gt;// '0[object Object]1'&lt;/span&gt;
&lt;span class="o"&gt;!+&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;+!&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;              &lt;span class="c1"&gt;// 'truefalse'&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="c1"&gt;// 'Thu Jan 01 1970 02:00:00(EET)0'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abaixo, você encontrará explicações para cada expressão.&lt;/p&gt;

&lt;p&gt;O operador binário&lt;code&gt;+&lt;/code&gt;aciona a conversão numérica gerando o resultado&lt;code&gt;true&lt;/code&gt;ou&lt;code&gt;false&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador aritmético&lt;code&gt;/&lt;/code&gt;aciona a conversão numérico para a string&lt;code&gt;'6'&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;6&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador&lt;code&gt;+&lt;/code&gt;possui uma associação de leitura a partir da esquerda para a direita (left-to-right associativity), portanto a expressão&lt;code&gt;"number" + 15&lt;/code&gt;é executada primeiro. Desde que o primeiro operando é uma string, o operador&lt;code&gt;+&lt;/code&gt;aciona a conversão para string do número 15. No segundo passo, a expressão&lt;code&gt;"number15" + 3&lt;/code&gt;é tratada da mesma forma.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; 
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number15&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; 
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number153&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A expressão&lt;code&gt;15 + 3&lt;/code&gt;é avaliada primeiro. Já que ambos operandos são numéricos, não é preciso fazer a coerção dos tipos. Mas na segunda expressão, quando&lt;code&gt;18 + 'number'&lt;/code&gt;é avalido, ao verificar que um dos operandos é uma string, ele aciona a conversão para string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;18number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador de comparação&lt;code&gt;&amp;gt;&lt;/code&gt;acionada a conversão numérica para&lt;code&gt;[1]&lt;/code&gt;e&lt;code&gt;null&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador unário&lt;code&gt;+&lt;/code&gt;tem maior precedência ao operador binário&lt;code&gt;+&lt;/code&gt;. Então a expressão&lt;code&gt;+'bar'&lt;/code&gt;é avaliada primeiro. O operador unário aciona a conversão numérica para a string&lt;code&gt;'bar'&lt;/code&gt;. Já que a string não apresenta um número válido, o resultado será&lt;code&gt;NaN&lt;/code&gt;. Na segunda etapa, a expressão&lt;code&gt;'foo' + NaN&lt;/code&gt;será avaliada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;foo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt; 
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fooNaN&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador&lt;code&gt;==&lt;/code&gt;aciona a conversão numérica, a string&lt;code&gt;true&lt;/code&gt;é convertida para&lt;code&gt;NaN&lt;/code&gt;, o booleano&lt;code&gt;true&lt;/code&gt;é convertido para 1.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;false&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;   
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador&lt;code&gt;==&lt;/code&gt;normalmente aciona a conversão numérica, mas não é o caso quando é colocado&lt;code&gt;null&lt;/code&gt;.&lt;code&gt;null&lt;/code&gt;é igual apenas a&lt;code&gt;null&lt;/code&gt;ou&lt;code&gt;undefined&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador&lt;code&gt;!!&lt;/code&gt;converter ambas strings&lt;code&gt;'true'&lt;/code&gt;e&lt;code&gt;'false'&lt;/code&gt;para o booleano&lt;code&gt;true&lt;/code&gt;, já que eles não são strings vazias. Então,&lt;code&gt;==&lt;/code&gt;apenas verifica a igualdade de dois booleanos&lt;code&gt;true&lt;/code&gt;sem qualquer coerção.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;false&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;  
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador&lt;code&gt;==&lt;/code&gt;aciona a conversão numérica para um array. O método do array&lt;code&gt;valueOf()&lt;/code&gt;retorna o próprio array, e é ignorado por não ser um primitivo. A função do array&lt;code&gt;toString()&lt;/code&gt;converte&lt;code&gt;['x']&lt;/code&gt;para a string&lt;code&gt;'x'&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;  
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt;  &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador&lt;code&gt;+&lt;/code&gt;aciona uma conversão numérica para&lt;code&gt;[]&lt;/code&gt;. A função do array&lt;code&gt;valueOf()&lt;/code&gt;é ignorado, pois retorna a si mesmo, cujo valor não é primitivo. A função do array&lt;code&gt;toString()&lt;/code&gt;retorna uma string vazia.&lt;/p&gt;

&lt;p&gt;Na segunda expressão&lt;code&gt;'' + null + 1&lt;/code&gt;é avaliada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt;  &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt;  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;null&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;null1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os operadores lógicos&lt;code&gt;||&lt;/code&gt;e&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;fazem coerção para booleano, mas retornando os operandos originais — não valores booleanos.&lt;code&gt;0&lt;/code&gt;é falso(falsy), enquanto&lt;code&gt;'0'&lt;/code&gt;é verdadeiro(truthy), pois não é uma string vazia. Um objeto vazio&lt;code&gt;{}&lt;/code&gt;também retorna verdadeiro(truthy).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;  
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;  &lt;span class="c1"&gt;// internamente&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;             &lt;span class="c1"&gt;// internamente&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Não é preciso fazer coerção pois ambos operandos são do mesmo tipo. Desde que&lt;code&gt;==&lt;/code&gt;verifica a identidade do objeto (object identity), e não sua igualdade (object equality), o resultado será&lt;code&gt;false&lt;/code&gt;, por conta dos 2 arrays serem de instâncias diferentes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt;  &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Todos os operandos são valores não primitivos, portanto,&lt;code&gt;+&lt;/code&gt;inicia a conversão numérica com o item mais a esquerda. A função&lt;code&gt;valueOf&lt;/code&gt;de ambos objetos e arrays retornarão a si mesmo, e serão ignorados. O método&lt;code&gt;toString()&lt;/code&gt;é usado como fallback. A pegadinha aqui é que&lt;code&gt;{}&lt;/code&gt;não é considerado um objeto literal, mas sim como um bloco de declaração de estado, então é ignorado. A avaliação começará com a próxima expressão&lt;code&gt;+ []&lt;/code&gt;, que será convertido para uma string vazia através do método&lt;code&gt;toString()&lt;/code&gt;, e então para&lt;code&gt;0&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[object Object]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0[object Object]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0[object Object]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0[object Object]1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse é mais fácil de explicar, pois o passo a passo de sua resolução se dará de acordo com a precedência do operador.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;!+&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;+!&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;  
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!+&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;truefalse&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador&lt;code&gt;-&lt;/code&gt;acionará a conversão numérica para&lt;code&gt;Date&lt;/code&gt;. A função&lt;code&gt;Date.valueOf()&lt;/code&gt;retornará o número de milissegundos desde a época do Unix.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O operador&lt;code&gt;+&lt;/code&gt;acionará a conversão padrão.&lt;code&gt;Date&lt;/code&gt;assumirá uma conversão para string, portanto o método&lt;code&gt;toString()&lt;/code&gt;será utilizado, ao invés do&lt;code&gt;valueOf()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Thu Jan 01 1970 02:00:00 GMT+0200 (EET)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="o"&gt;==&amp;gt;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Thu Jan 01 1970 02:00:00 GMT+0200 (EET)0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Rápidas explicações
&lt;/h2&gt;

&lt;h3&gt;
  
  
  O que é um operador unário e binário?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Unário: aquele que interage sobre um elemento. Ex: +, -, ++.&lt;/li&gt;
&lt;li&gt;Binário: aquele que interage sobre dois elementos. Ex: +, -, *, /, &amp;amp;, &amp;amp;&amp;amp;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;p&gt;Recomendo o excelente livro“&lt;a href="https://leanpub.com/understandinges6"&gt;Understanding ES6&lt;/a&gt;” escrito por&lt;a href="https://medium.com/u/77c787f473e5?source=post_page-----d6c9203c4e5----------------------"&gt;Nicholas C. Zakas&lt;/a&gt;. É uma grande fonte para aprender ES6, não é tão avançado, e não fica muito tempo em partes mais profundas.&lt;/p&gt;

&lt;p&gt;E aqui um ótimo livro de ES5 —&lt;a href="http://speakingjs.com/"&gt;SpeakingJS&lt;/a&gt;written por&lt;a href="https://medium.com/u/7fab51e62203?source=post_page-----d6c9203c4e5----------------------"&gt;Axel Rauschmayer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;(&lt;strong&gt;Russian&lt;/strong&gt;) Современный учебник Javascript —&lt;a href="https://learn.javascript.ru/"&gt;https://learn.javascript.ru/&lt;/a&gt;. Especially&lt;a href="https://learn.javascript.ru/object-conversion"&gt;these&lt;/a&gt;&lt;a href="https://learn.javascript.ru/types-conversion"&gt;two&lt;/a&gt;pages on type coercion.&lt;/p&gt;

&lt;p&gt;JavaScript Comparison Table —&lt;a href="https://dorey.github.io/JavaScript-Equality-Table/"&gt;https://dorey.github.io/JavaScript-Equality-Table/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;wtfjs — a little code blog about that language we love despite giving us so much to hate —&lt;a href="https://wtfjs.com/"&gt;https://wtfjs.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codeburst.io/javascript-quickie-what-is-type-coercion-74f19df6d16f"&gt;https://codeburst.io/javascript-quickie-what-is-type-coercion-74f19df6d16f&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codeburst.io/javascript-quickie-what-is-type-coercion-74f19df6d16f"&gt;&lt;/a&gt;&lt;a href="https://medium.com/codezillas/let-me-coerce-you-into-liking-javascripts-dynamic-typing-system-3cd22c19cb64"&gt;https://medium.com/codezillas/let-me-coerce-you-into-liking-javascripts-dynamic-typing-system-3cd22c19cb64&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/intrinsic/javascript-object-type-coercion-b2ec176c02c4"&gt;https://medium.com/intrinsic/javascript-object-type-coercion-b2ec176c02c4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hackernoon.com/understanding-js-coercion-ff5684475bfc"&gt;https://hackernoon.com/understanding-js-coercion-ff5684475bfc&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Um guia para entender JavaScript hoisting 🚩com variáveis usando let e const</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Thu, 15 Apr 2021 14:42:44 +0000</pubDate>
      <link>https://dev.to/allangrds/um-guia-para-entender-javascript-hoisting-com-variaveis-usando-let-e-const-p7</link>
      <guid>https://dev.to/allangrds/um-guia-para-entender-javascript-hoisting-com-variaveis-usando-let-e-const-p7</guid>
      <description>&lt;p&gt;Esse artigo é uma livre tradução do artigo&lt;a href="https://medium.freecodecamp.org/what-is-variable-hoisting-differentiating-between-var-let-and-const-in-es6-f1a70bb43d" rel="noopener noreferrer"&gt;A guide to JavaScript variable hoisting 🚩 with let and const&lt;/a&gt;, por&lt;a href="https://medium.freecodecamp.org/@bhuvanmalik" rel="noopener noreferrer"&gt;Bhuvan Malik&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Novos desenvolvedores de JavaScript geralmente têm dificuldade em entender o comportamento exclusivo do hoisting de*variáveis*​​/&lt;em&gt;funções&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Já que vamos falar sobre declarações de&lt;code&gt;var, let&lt;/code&gt;e&lt;code&gt;const&lt;/code&gt;mais tarde, é importante entender o içamento (hoisting) de variáveis ​​em vez do içamento (hoisting) de funções. Vamos mergulhar!&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é içamento de variável (variable hoisting)?
&lt;/h2&gt;

&lt;p&gt;A engine do Javascript trata todas as variáveis declaradas com&lt;code&gt;var&lt;/code&gt;como se fossem declaradas no topo do escopo de uma função (se colocadas dentro de uma), ou no topo do escopo global (se declaradas fora de uma função), independentemente de onde a declaração real ocorrer. Isso essencialmente é “&lt;em&gt;hoisting&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;Então, variáveis podem realmente estar disponíveis antes de sua declaração.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2Fimg%2F1_q7bpdmcgkh2sblc5ew2m8a.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2Fimg%2F1_q7bpdmcgkh2sblc5ew2m8a.gif" title="Hoisting" alt="Hoisting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos ver essa parada em ação…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Saída (Output): undefined&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Saída (Output): "square"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você está vindo de linguagens baseadas em C, você estava esperando que um erro fosse lançado ao chamar o primeiro&lt;code&gt;console.log&lt;/code&gt;, já que a variável&lt;code&gt;shape&lt;/code&gt;não foi definida naquele momento. Entretanto, o interpretador do Javascript vai além, e iça (hoists) todas as declarações de variáveis pro top, e a suas inicializações permanecem no mesmo local.&lt;/p&gt;

&lt;p&gt;É isso que acontece por baixo dos panos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//a declaraçã da variável é içada (hoisted)&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Saída (Output): undefined&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Saída (Output): "square"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abaixo está outro exemplo, dessa vez no escopo de uma função para deixar as coisas mais claras:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getShape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// shape existe aqui com o valor "undefined"&lt;/span&gt;
&lt;span class="c1"&gt;// Saída (Output): undefined&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// outro código qualquer&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// shape existe aqui com o valor "undefined"&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba que no exemplo acima a declaração de&lt;code&gt;shape&lt;/code&gt;é içada (hoisted) para o topo da função&lt;code&gt;getShape&lt;/code&gt;. Isso acontece pois os blocos&lt;code&gt;if/else&lt;/code&gt;não criam escopos locais como vemos em outras linguagens. O escopo local é essencialmente o escopo de um função em JavaScript. Portanto, “shape” é acessível em todos os lugares fora do bloco if e dentro da função com um valor “undefined”.&lt;/p&gt;

&lt;p&gt;Esse comportamento padrão do JavaScript tem suas vantagens e desvantagens. Não entender completamente isso pode levar a bugs sutis, mas perigosos, em nosso código.&lt;/p&gt;

&lt;h2&gt;
  
  
  Declarações no Nível do Bloco (Block-Level Declarations)
&lt;/h2&gt;

&lt;p&gt;O*&lt;em&gt;ES6&lt;/em&gt;*introduziu escopos no nível de bloco (block-level scoping) para prover aos desenvolvedores maior controle e flexibilidade sobre o ciclo de vida de uma variável.&lt;/p&gt;

&lt;p&gt;Declarações no Nível do Bloco (Block-Level Declarations) são feitas em blocks/escopos léxicos que são criadas dentro do block&lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Declaração com “let”
&lt;/h3&gt;

&lt;p&gt;Essa syntax é similar a&lt;code&gt;var&lt;/code&gt;, apenas troque&lt;code&gt;var&lt;/code&gt;por&lt;code&gt;let&lt;/code&gt;para declarar uma variável para que seu escopo fique apenas naquele bloco.&lt;/p&gt;

&lt;p&gt;Coloque a declaração do seu&lt;code&gt;let&lt;/code&gt;no topo do bloco para que ele esteja disponível para o bloco inteiro.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getShape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// shape não existe aqui&lt;/span&gt;
&lt;span class="c1"&gt;// console.log(shape); =&amp;gt; ReferenceError: shape is not defined&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// algum có&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// shape também não existe&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba como&lt;code&gt;shape&lt;/code&gt;existe apenas dentro do block do&lt;code&gt;if&lt;/code&gt;, e como um erro é lançado quando é feita a tentiva de acesso for dele, lançando um&lt;code&gt;undefined&lt;/code&gt;como vimos anteriormente quando usamos&lt;code&gt;var&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observação:&lt;/strong&gt;Se um identificador já foi definido dentro do escopo com&lt;code&gt;var&lt;/code&gt;, usando o mesmo identificador como&lt;code&gt;let&lt;/code&gt;dentro desse escopo lançará um erro. Além disso, nenhum erro será mostrado se uma declaração&lt;code&gt;let&lt;/code&gt;criar uma variável com o mesmo nome de uma variável em seu escopo externo. (Este caso é o mesmo ao usar&lt;code&gt;const&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rectangle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// SyntaxError: Identifier 'shape' has already been declared&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;e:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condicao&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// não lança um erro&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rectangle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// mais código&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Sem erro&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Declaração com “const”
&lt;/h3&gt;

&lt;p&gt;A syntax dessa declaração é similar a&lt;code&gt;let&lt;/code&gt;&amp;amp;&lt;code&gt;var&lt;/code&gt;, o ciclo de vida(lifecycle) é o mesmo que o do&lt;code&gt;let&lt;/code&gt;, mas você precisa seguir certas regras.&lt;/p&gt;

&lt;p&gt;Toda&lt;code&gt;const&lt;/code&gt;é tratada como*&lt;em&gt;constantes&lt;/em&gt;*, e, portanto, ela não pode ter seu valore reatribuído após ser definida. Devido a isto, toda&lt;code&gt;const&lt;/code&gt;deve ser inicializada no momento da declaração.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// válido &lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;triangle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// syntax error: missing initialization&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// TypeError: Assignment to constant variable&lt;/span&gt;

&lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Entretando&lt;/strong&gt;, propriedades de um objeto podem ser alteradas!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;triangle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;sides&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// FUNCIONA&lt;/span&gt;
&lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sides&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// SyntaxError: Invalid shorthand property initializer&lt;/span&gt;
&lt;span class="nx"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hexagon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;sides&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima podemos ver que as propriedades do objeto&lt;code&gt;shape&lt;/code&gt;puderem ser alteradas pois nós mudamos apenas o que ela contém, e não o que está vinculado, como em uma string, por exemplo.&lt;/p&gt;

&lt;p&gt;Podemos resumir dizendo que&lt;code&gt;const&lt;/code&gt;impede a modificação da ligação(binding) como um todo — não o valor ao qual ela está vinculada.&lt;/p&gt;

&lt;p&gt;Observação: Propriedades podem ser alteradas. Para uma real imutabilidade user Object.Freeze, Immutable.js ou Mori.&lt;/p&gt;

&lt;h2&gt;
  
  
  A zona temporal morta
&lt;/h2&gt;

&lt;p&gt;Agora sabemos que acessar uma variável com&lt;code&gt;let&lt;/code&gt;ou&lt;code&gt;const&lt;/code&gt;antes de ser declarada lançará um&lt;code&gt;ReferenceError&lt;/code&gt;. Esse período entre a entrada do escopo e a declaração de onde eles não podem ser acessados é chamado de Zona Temporal Morta (Temporal Dead Zone).&lt;/p&gt;

&lt;p&gt;Perceba que a “Zona Temporal Morta” não é formalmente mencionada nas especificações do ECMAScript, é apenas um termo popular entre os programadores.&lt;/p&gt;

&lt;p&gt;Eu pessoalmente recomendo que sempre use&lt;code&gt;const&lt;/code&gt;, pois gera menos bugs. Atualmente eu raramente encontro uma situação onde precise usar o&lt;code&gt;var&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Como regra geral, use&lt;code&gt;let&lt;/code&gt;somente para contadores de loop ou se você realmente precisará alterar o valor da variável depois. Pra qualquer outro caso, vá de&lt;code&gt;const&lt;/code&gt;. Pessoalmente eu abandonei loops para usar &lt;strong&gt;filter (), map () &amp;amp; reduce ()&lt;/strong&gt;. Você deveria também.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fica esperto e veja a 2a parte em “Function Hoisting &amp;amp; Questões importantes de hoisting em processos seletivos”.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.freecodecamp.org/function-hoisting-hoisting-interview-questions-b6f91dbc2be8" rel="noopener noreferrer"&gt;https://medium.freecodecamp.org/function-hoisting-hoisting-interview-questions-b6f91dbc2be8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clique&lt;a href="https://medium.com/@bhuvanmalik/es6-functions-9f61c72b1e86" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;para ver meus artigos sobre as úteis features do ES6 relacionadas a funções.&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>O que é Hoisting em Javascript?</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Thu, 15 Apr 2021 14:42:14 +0000</pubDate>
      <link>https://dev.to/allangrds/o-que-e-hoisting-em-javascript-5dpg</link>
      <guid>https://dev.to/allangrds/o-que-e-hoisting-em-javascript-5dpg</guid>
      <description>&lt;p&gt;Esse artigo é uma tradução livre de&lt;a href="https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-what-is-hoisting-in-javascript-a63c1b2267a1"&gt;What is Hoisting in Javascript?&lt;/a&gt;, por&lt;a href="https://medium.com/@sunilsandhu"&gt;Sunil Sandhu&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Uma das muitas peculiaridades do Javascript é algo conhecido como*&lt;em&gt;hoisting&lt;/em&gt;*.&lt;/p&gt;

&lt;p&gt;Se você começou a desenvolver recentemente com Javascript, é bem provável que você ainda não esteja escrevendo seu código perfeitamente. Então, por causa disso, é altamente provável que seu*&lt;em&gt;hoisting&lt;/em&gt;*não esteja perfeito também.😉&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é hoisting?
&lt;/h2&gt;

&lt;p&gt;Basicamente, quando o Javascript compila todo seu código, todas as declarações de variáveis usando&lt;code&gt;var&lt;/code&gt;são hoistiadas(abrasilerei)/levadas ao topo de suas funções/escopo local (se declaradas dentro de uma função), ou ao topo do escopo global (se declaradas fora de uma função) independentemente de onde a declaração foi feita. Isto é o que queremos dizer com “&lt;em&gt;hoisting&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;As declarações de funções também são hoistiadas, mas elas irão para a parte mais alta do escopo, por isso ficará acima de todas as declarações de variáveis.&lt;/p&gt;

&lt;p&gt;Chega de conversinha, vamos ver alguns exemplos básicos para demonstrar o impacto do hoisting.&lt;/p&gt;

&lt;p&gt;Se escrevermos o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;meuNome&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;meuNome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pop quiz! O que o comando&lt;code&gt;console.log&lt;/code&gt;mostrará?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;1.&lt;/em&gt;&lt;/strong&gt;&lt;code&gt;Uncaught ReferenceError: meuNome is not defined&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;2.&lt;/em&gt;&lt;/strong&gt;&lt;code&gt;Bob&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A terceira opção é realmente a resposta correta.&lt;/p&gt;

&lt;p&gt;Como falei anteriormente, as variáveis são movidas pro topo de seus escopos\&lt;br&gt;
quando seu Javascript compila em tempo de execução ( que — se excluirmos o NodeJS — de uma forma bem básica é quando sua página está carregando). Entretanto, uma coisa importante a notar é que a única coisa que é movida para o topo são as declarações de variáveis, não o valor real delas.&lt;/p&gt;

&lt;p&gt;Para clarear as ideias, se tivermos um pedaço de código, e na linha 10 tivermos um&lt;code&gt;var name = 'Sunil'&lt;/code&gt;, quando o Javascript for compilado,&lt;code&gt;var name&lt;/code&gt;será movido ao topo de seu escopo, enquanto&lt;code&gt;name = 'Sunil'&lt;/code&gt;permanecerá na linha 10 (ou possivelmente na linha 11 se&lt;code&gt;var name&lt;/code&gt;for levada para a linha 1).&lt;/p&gt;

&lt;p&gt;Com isso em mente, vamos olhar pro código que coloquei anteriormente, mas vamos ver como o Javascript irá devolver a saída em tempo de execução:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;meuNome&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;meuNome&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;meuNome&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;João&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É por isso que o&lt;code&gt;console.log&lt;/code&gt;devolverá&lt;strong&gt;undefined,&lt;/strong&gt;pois ele reconhece que a variável*&lt;em&gt;meuNome&lt;/em&gt;*existe, porém ela não teve um valor inserido até a terceira linha.&lt;/p&gt;

&lt;p&gt;Também mencionamos brevemente anteriormente que funções também são hoistiadas (levadas)para o topo (logo acima, onde as declarações de variáveis ​​são hoistiadas).&lt;/p&gt;

&lt;p&gt;Então se olharmos para o código abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hey&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Iae &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;hey&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;João&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;strong&gt;hey()&lt;/strong&gt; retornará &lt;strong&gt;undefined&lt;/strong&gt; mesmo assim, pois o interpretador do JavaScript compilará o código em tempo de execução para o seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hey&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Iae &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;hey&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;João&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Então, no momento em que a função é chamada ela sabe que uma variável chamada&lt;code&gt;name&lt;/code&gt;existe, mas a variável não possui um valor atribuído. Existem algumas variantes para isso que ocorrem ao usar expressões variáveis (variable expressions) ​​de &lt;strong&gt;IIFE&lt;/strong&gt;(&lt;a href="https://medium.com/javascript-in-plain-english/https-medium-com-javascript-in-plain-english-stop-feeling-iffy-about-using-an-iife-7b0292aba174"&gt;clique aqui se você quiser saber mais&lt;/a&gt;), mas tentar obter um controle mental de tudo isso de uma vez não é o ideal, então eu irei deixá-lo pesquisar o hoisting a respeito de &lt;strong&gt;function expressions&lt;/strong&gt; e &lt;strong&gt;IIFE’s.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tendo falado isso, tudo que mencionei anteriormente deve ajudá-lo a entender como o hoisting funciona.&lt;/p&gt;

&lt;p&gt;O conceito de hoisting é a razão pela qual você pode, às vezes, se deparar com o código de outras pessoas, no qual as variáveis são declaradas logo no topo e, em seguida, recebem valores posteriormente. Essas pessoas estão simplesmente tentando fazer com que seu código se assemelhe ao modo como o interpretador irá compilá-lo, a fim de ajudá-lo a minimizar possíveis erros.&lt;/p&gt;

&lt;p&gt;Se você gostou desse artigos, envie muitos claps e se inscreva em minha publicação &lt;a href="https://medium.com/javascript-in-plain-english"&gt;Javascript In Plain English.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Tecnologia, negócios, otimização prematura e dívida técnica</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Thu, 15 Apr 2021 14:24:28 +0000</pubDate>
      <link>https://dev.to/allangrds/tecnologia-negocios-otimizacao-prematura-e-divida-tecnica-30gn</link>
      <guid>https://dev.to/allangrds/tecnologia-negocios-otimizacao-prematura-e-divida-tecnica-30gn</guid>
      <description>&lt;p&gt;Foi em 2017, logo após sair de meu antigo trabalho que entrei em um projeto com um colega dessa mesma empresa. A ideia era criar uma startup(mais uma?) que fornecesse uma plataforma web do ramo de logística.&lt;/p&gt;

&lt;h2&gt;
  
  
  Planejando a aplicação
&lt;/h2&gt;

&lt;p&gt;Estava trabalhando como front há pouco tempo e mexia com PHP nas horas vagas. Queria fazer algo mais separadinho, mesmo que a API fosse um grande monolito.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxsesf1m5hzinp7phcok5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxsesf1m5hzinp7phcok5.png" alt="alt text" width="161" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Olhando para a imagem colocada acima, o que ela está dizendo para mim?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tempo: No projeto sou o único de tecnologia e meu colega na parte de negócio. Sou uma pessoa inexperiente, e a plataforma não terá pouco conteúdo, mesmo para um MVP. O resultado disso será eu tendo que manter 2(duas) aplicações. Se algo novo surgir, alteração nas 2(duas).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refleti e percebi que eu estava caindo no famoso caso de otimização prematura - Otimize hoje, para não precisar otimizar amanhã -. Eu estava desenvolvendo algo, por mais legal ou interessante que fosse, que poderia ser menor: um monólito com a parte de back e front. O tempo que eu gastaria no desenvolvimento de ambas as aplicações geraria um novo problema, que falarei mais pra frente.&lt;/p&gt;

&lt;p&gt;Como falei, a segunda forma que pensei para desenvolver a plataforma foi:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feui5hb19segqxy8hk1wn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feui5hb19segqxy8hk1wn.png" alt="alt text" width="161" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Monólito na sua forma mais pura. Sem API, sem front consumindo. Uma única aplicação que faz tudo.&lt;/p&gt;

&lt;p&gt;Com esse cara aqui eu ganho uma vantagem/desvantagem em relação ao modelo anterior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tempo: O recurso mais escasso que todos nós temos, e que neste modelo eu teria uma redução. Usando um framework como Laravel eu já faço uma consulta e mando os dados direto pra minha view renderizar. Sem precisar construir 2(duas) aplicações diferentes. O problema é que futuramente sustentar uma aplicação inteira em um único lugar ficaria inviável.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refletindo, de novo, esse caso já foi pra outra ponta, caí no caso dedívida técnica- Pense nela como um empréstimo. Você conseguirá o que precisa, mas precisará pagar juros depois -, eu abdiquei de uma qualidade, gerando uma dívida tecnológica, para conseguir desenvolver rápido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Esquerda ou direita?
&lt;/h2&gt;

&lt;p&gt;No primeiro caso percebi que estava construindo uma aplicação que não era o ideal, mas dividia a lógica da visualização da manipulação de dados. No segundo caso eu ganhei tempo, deixando tudo junto, no grande monolito emLaravel, mas gerando um problema de manutenção no futuro.&lt;/p&gt;

&lt;p&gt;Se você percebe, ambas acabam esbarrando no problema de tempo. E o que essas duas abordagens têm em comum?&lt;/p&gt;

&lt;h2&gt;
  
  
  Time to market!
&lt;/h2&gt;

&lt;p&gt;Time to market é o tempo para colocar um produto no mercado. Nesse caso o tempo é meu pior inimigo, pois como querotestar o MVP, meu lindo negócio ainda não nasceu, e tenho que conseguir validá-lo o mais rápido possível.&lt;/p&gt;

&lt;p&gt;Se eu escolher minha primeira abordagem(otimização prematura), terei uma curva para entregar o MVP maior, mas no futuro isso se estabiliza. Indo para o outro lado(dívida técnica), eu conseguirei lançar o MVP muito mais rápido, mas isso terá um custo que ficará cada vez maior conforme o tempo passar.&lt;/p&gt;

&lt;p&gt;Então tá aí a resposta, né?&lt;/p&gt;

&lt;p&gt;Abrace a dívida técnica para crescer, mas saiba deixá-la quando tiver crescido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minha talk
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.youtube.com/watch?v=RCNoTqd57P0"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HoABb9ij--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/http://img.youtube.com/vi/RCNoTqd57P0/0.jpg" alt="" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Coisas que você pode fazer para melhorar a qualidade do seu código</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Thu, 15 Apr 2021 14:22:11 +0000</pubDate>
      <link>https://dev.to/allangrds/coisas-que-voce-pode-fazer-para-melhorar-a-qualidade-do-seu-codigo-41gp</link>
      <guid>https://dev.to/allangrds/coisas-que-voce-pode-fazer-para-melhorar-a-qualidade-do-seu-codigo-41gp</guid>
      <description>&lt;p&gt;Como diminuir os WTFs por minuto.&lt;br&gt;
Esse post é uma tradução livre do artigo &lt;a href="https://medium.com/better-programming/things-that-you-can-do-to-improve-code-quality-c746c30e7521"&gt;Things That You Can Do to Improve Code Quality&lt;/a&gt;, escrito por &lt;a href="https://medium.com/@daaaan?source=post_page-----c746c30e7521----------------------"&gt;Daan&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Um código mal escrito pode ser um baita desastre. Quando a bagunça nele aumenta, o tempo para mexer em algo também irá :/. No pior caso, o código ninguém consegue mexer no código, e aos poucos o projeto vai morrendo.&lt;/p&gt;

&lt;p&gt;Para prevenir esse tipo de caso, você vai precisar de um código de qualidade. Você &lt;strong&gt;deve&lt;/strong&gt; investir seu tempo para desenvolvê-lo. E pense que em longo prazo ele vai se pagar, tranquilamente.&lt;/p&gt;

&lt;p&gt;Qualidade não tem dono, é tarefa de todo mundo. Não interessa se você é gerente, um tester ou desenvolvedor. Entregar um código de alta qualidade e funcionando deve ser a meta em todo o processo de desenvolvimento.&lt;/p&gt;

&lt;p&gt;Vou mostrar uma lista de &lt;strong&gt;6 coisas que podem ser feitas para melhorar a qualidade do código.&lt;/strong&gt;Alguns desses pontos você consegue fazer sozinho, e outras o time precisará se empenhar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gtxuwysjrabdb6xxsp5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9gtxuwysjrabdb6xxsp5.png" alt="alt text" width="525" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como mensurar um bom código: WTFs por minuto. Fonte: &lt;a href="https://hackernoon.com/the-book-every-programmer-should-read-33b5ef2e532a"&gt;https://hackernoon.com/the-book-every-programmer-should-read-33b5ef2e532a&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  1. O Princípio dos 4 olhos(Four-Eyes Principle)
&lt;/h3&gt;

&lt;p&gt;O princípio dos 4 olhos é algo fácil de ser entendido e executado. Ele precisa de duas pessoas, a que fez o código, e outra que possa revisá-lo. Um dos métodos atuais mais conhecidos para fazer isso é o pull request.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Pull requests permite que você informe aos outros as mudanças que você fez na sua branch em um repositório do Github. Assim que ele é aberto, você pode discutir e revisar algumas mudanças de código com seus colegas antes que suas mudanças sejam mergeadas na branch base.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;—&lt;a href="https://help.github.com/en/articles/about-pull-requests"&gt;Github.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Durante o review de código, algumas coisas devem ser levadas em conta. Uma delas é verificar se parte do código quebra/infringe alguma convenção de código estipulada pelo time. Isso pode ser automatizado através do uso de um linter, mas algumas vezes essa verificação ainda é feita manualmente.&lt;/p&gt;

&lt;p&gt;Outras coisas que podem ser feitas, mas não de forma automática, e analisar a manutenabilidade do código e como é feito o tratamento de erros(error handling). Por último, mas não menos importante, o código deve ser verificado quanto à integridade. Esse trecho de código contém o escopo da funcionalidade solicitada?&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Integração Contínua(Continuous Integration)
&lt;/h3&gt;

&lt;p&gt;“Mas funciona no servidor de desenvolvimento”, ou ainda pior: “Na minha máquina funciona”.&lt;/p&gt;

&lt;p&gt;Problemas e discussões dessa natureza são o que você deseja que não aconteçam. É exatamente aí que a integração contínua(CI) pode desempenhar um papel importante.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Integração Contínua é uma prática de desenvolvimento de software onde os membros do time juntam seus trabalhos de forma frequente, normalmente cada pessoa faz isso diariamente — chegando a múltiplas integrações por dia. Cada integração é verificada por um build automático(incluindo os testes) para detectar erros de integração o mais rápido possível.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;— Martin Fowler&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A sacada da integração contínua é dar aos desenvolvedores um feedback rápido que informe o que ele colocou com o que já existe.&lt;/p&gt;

&lt;p&gt;A integração contínua funciona quando você segue esses 2 princípios básicos:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mantenha o build rápido. Não existe nada mais desanimador que um build que demora 1h.&lt;/li&gt;
&lt;li&gt;Corrija os builds quebrados o mais rápido possível. Toda a ideia de CI é que você está sempre desenvolvendo algo numa base de código estável.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;O CI melhora a qualidade do código pois fornece um feedback rápido aos desenvolvedores. Se um teste quebra, o build vai falhar, e o desenvolvedor será notificado. Além disso, é bom que seja adicionado um linter ao script the build, para sempre verificar as convenções de código estipuladas. Isso também aumenta a qualidade do código.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Convenções de Codificação(Coding Conventions)
&lt;/h3&gt;

&lt;p&gt;É importante existir uma lista das convenções de código estipuladas. Mantes antes de você começar a fazê-la, todos no time precisam estar alinhados. Isso vai demandar tempo, e precisará ser conversado com pessoa a pessoa, com muita discussão sobre quais convenções escolher.&lt;/p&gt;

&lt;p&gt;Faça uma lista das convenções especificando como as variáveis devem ser declaradas, e alguns convenções para nomeclatura, e etc. O número de regras que você pode colocar nessa lista é infinita, e elas podem variar. Apenas tenha as regras que fazem sentido pro seu time. Sinta-se livre para adicionar novas regras se o time gostar.&lt;/p&gt;

&lt;p&gt;Depois de ter essa lista, é garantir que ela será cumprida. Como falei anteriormente, o melhor modo de verificar que essas convenções estão sendo seguidas, é através de um linter uma pipeline de CI, já que não é preciso nenhuma ação manual — hoje já é possível você ter extensões em seu editor de texto que verifiquem o código em tempo real e te dê avisos na interface. Sempre se certifique de usar o lint regularmente, pra deixar os commits certinhos. Isso vai aumentar a legibilidade e manutenibilidade da base de código, já que o código estará uniforme.&lt;/p&gt;

&lt;p&gt;Um código de alta qualidade pode acelerar o desenvolvimento de software a longo prazo, pois pode ser reutilizado e os desenvolvedores não precisam gastar muito tempo corrigindo bugs antigos e fazendo melhorias nele. Sem contar que também facilita a entrada de novas pessoas no projeto.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Teste, Teste, Teste
&lt;/h3&gt;

&lt;p&gt;Quanto menos erros o código tiver, maior será sua qualidade. O teste completo filtra bugs críticos, garantindo que o código funcione da maneira esperada.&lt;/p&gt;

&lt;p&gt;Ter uma estratégia de teste é essencial quando o assunto é ter um código de qualidade. No mínimo, seu código deve ter testes de unidade. Se quiser fazer outros, como testes de integração, regressão, será ainda melhor.&lt;/p&gt;

&lt;p&gt;De acordo com a pirâmide de testes, a maior quantidade de testes que um software deveria ter, são os de unidade. A razão para isso é que são os mais baratos e mais rápidos. Existe uma porrada de ferramentas disponíveis para te ajudar na criação de testes de unidade e também para relatórios de cobertura de código(code coverage).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7g6pxoubtr1uf3vy7yf1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7g6pxoubtr1uf3vy7yf1.png" alt="alt text" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://blog.octo.com/en/the-test-pyramid-in-practice-5-5/"&gt;https://blog.octo.com/en/the-test-pyramid-in-practice-5-5/&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Executar a bateria de testes e criar um relatório da cobertura de testes é algo que pode ser feito de forma automática através do CI. É possível você fazer o build falhar caso a cobertura de código seja inferior ao percentual configurado.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Analise Bugs
&lt;/h3&gt;

&lt;p&gt;Ter bugs é inevitável. O modo como eles são tratados é muito importante. Se você deseja evoluir como desenvolvedor, esse é um ponto chave, para que você aprenda com seus erros. É por isso que você deve analisar os bugs.&lt;/p&gt;

&lt;p&gt;Quando um bug ocorre, entenda seu impacto. É um bug de alta ou baixa prioridade? Se for um bug de alta prioridade, corre pra resolver.&lt;/p&gt;

&lt;p&gt;Quando a análise do bug for feita, é importante se fazer algumas perguntas. O que aconteceu de errado? Pq não testamos isso(da forma certa)? Onde mais isso acontece? E mais importante: Como podemos fazer com que isso não ocorra novamente:&lt;/p&gt;

&lt;p&gt;Claro, ferramentas são importantes para te ajudar a rastrear esses bugs. Existem muitas ferramentas no mercado. Pegue uma que se encaixe em sua necessidade.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O único e real erro é aquele com o qual não aprendemos nada&lt;/p&gt;

&lt;p&gt;&lt;em&gt;— Henry Ford&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  6. Comece a mensurar(Measuring)
&lt;/h3&gt;

&lt;p&gt;Quando se trata de mensurar, existem várias métricas que você pode usar para quantificar a qualidade do seu código.&lt;/p&gt;

&lt;h3&gt;
  
  
  Métrica de defeito(Defect metric)
&lt;/h3&gt;

&lt;p&gt;O número de defeitos e a severidade deles é uma métrica importante de qualidade. Se você deseja manter um rastro desses defeitos, você pode usar um bug burndown chart, por exemplo. Ele é funciona como um burndown chart do desenvolvimento ágil. A única diferença é que nesse você vai contar a quantidade de bugs que não foram consertados, ao invés dos pontos das histórias.&lt;/p&gt;

&lt;h3&gt;
  
  
  Métrica de complexidade(Complexity metrics)
&lt;/h3&gt;

&lt;p&gt;A complexidade é frequentemente medida com a métrica de complexidade ciclomática. É uma medida quantitativa do número de caminhos linearmente independentes através do código fonte de um programa.&lt;/p&gt;

&lt;p&gt;Existe uma correlação entre o número de complexidade ciclomática e a frequência de defeitos:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Vários estudos investigaram a correlação entre o número de complexidade ciclomática e a frequência de defeitos que ocorrem em uma função ou método. Alguns estudos encontram uma correlação positiva entre a complexidade e os defeitos ciclomáticos: funções e métodos que têm a maior complexidade tendem a conter também o maior número de defeitos. No entanto, a correlação entre complexidade ciclomática e tamanho do programa (normalmente medida em linhas de código) foi demonstrada muitas vezes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;—&lt;a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity"&gt;Wikipedia&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ter um código menos complexo, deveria, em teoria, gerar menos bugs.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Processos em containers não devem ser executados como root</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Thu, 15 Apr 2021 14:18:51 +0000</pubDate>
      <link>https://dev.to/allangrds/processos-em-containers-nao-devem-ser-executados-como-root-hdp</link>
      <guid>https://dev.to/allangrds/processos-em-containers-nao-devem-ser-executados-como-root-hdp</guid>
      <description>&lt;p&gt;Esse artigo é uma tradução livre de&lt;a href="https://medium.com/@mccode/processes-in-containers-should-not-run-as-root-2feae3f0df3b"&gt;Processes In Containers Should Not Run As Root&lt;/a&gt;por&lt;a href="https://medium.com/@mccode?source=post_header_lockup"&gt;Marc Campbell&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  tldr;
&lt;/h2&gt;

&lt;p&gt;Um processo dentro de um container não deve rodar com privilégios de root, assuma isso como verdade.&lt;/p&gt;

&lt;p&gt;Ao invés disse, crie um usuário em seu&lt;code&gt;Dockerfile&lt;/code&gt;com um conhecido&lt;code&gt;UID&lt;/code&gt;e&lt;code&gt;GID&lt;/code&gt;, e execute seu processo usando esse usuário. Imagens construídas sobre esse padrão são mais fáceis de serem executadas de forma segura por limitar o acesso a determinados recursos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Sistemas bem arquitetados aderem ao&lt;a href="https://en.wikipedia.org/wiki/Principle_of_least_privilege"&gt;princípio do menor privilégio&lt;/a&gt;. Esse princípio diz que um aplicativo deve ter acesso apenas aos recursos necessários para executar a função necessária. Isso é muito importante quando desejamos fazer um sistema seguro. Seja malicioso ou por causa de erros, um processo pode ter consequências inesperadas em tempo de execução. Um dos melhores modos de se proteger contra qualquer acesso inesperado é conceder o mínimo privilégio para que um processo seja executado.&lt;/p&gt;

&lt;p&gt;A maior dos processos containerizados são serviços de aplicações, sendo assim, elas não precisa de acesso como&lt;code&gt;root&lt;/code&gt;. Enquanto o&lt;a href="https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface"&gt;Docker precisa ser executado como root&lt;/a&gt;, os containers em si, não. Imagens Docker bem escritas, seguras e reutilizáveis ​​não devem ser executadas como root e devem fornecer um método previsível e fácil para limitar o acesso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por que isso é importante?
&lt;/h2&gt;

&lt;p&gt;Lembre-se que um processo em execução em um container não é diferente de outro processo em execução no Linux, exceto que ele tem um pequeno pedaço de metadata informando que ele está sendo executado em um container.&lt;/p&gt;

&lt;p&gt;Os containers são tão seguros quanto sua máquina host, portanto, qualquer coisa executada em um container deve ser tratada com a mesma consideração que qualquer coisa executada no próprio host.&lt;/p&gt;

&lt;p&gt;Assim como você não faria (ou não deveria) executar qualquer coisa como root em seu servidor, você não deveria executar nada como root em um container em seu servidor. Executar binários que foram criados em outro lugar requer confiança, e o mesmo é verdadeiro para binários em containers.&lt;/p&gt;

&lt;p&gt;Se um processo dentro de um container for executada como root por default, é possível mudar o&lt;code&gt;uid&lt;/code&gt;e&lt;code&gt;gid&lt;/code&gt;quando o container for iniciado. Sendo o criador da imagem, você deve usar como padrão um usuário diferente e facilitar a limitação de acesso para ele. Criando um usuário em seu&lt;code&gt;Dockerfile&lt;/code&gt;, você está tornando não apenas ele seguro por padrão, mas também mais fácil de continuar seguro.&lt;/p&gt;

&lt;p&gt;O exemplo abaixo mostrará o risco de executar um container como&lt;code&gt;root&lt;/code&gt;. Vamos criar um arquivo no diretório&lt;code&gt;/root&lt;/code&gt;, impedindo qualquer um diferente do&lt;code&gt;root&lt;/code&gt;vê-lo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;marc@srv:~$ sudo -s
root@srv:~# cd /root
root@srv:~# echo "top secret stuff" &amp;gt;&amp;gt; ./secrets.txt 
root@srv:~# chmod 0600 secrets.txt
root@srv:/root# ls -l
total 4
-rw------- 1 root root 17 Sep 26 20:29 secrets.txt
root@srv:/root# exit
exit
marc@srv:~$ cat /root/secrets.txt
cat: /root/secrets.txt: Permission denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora eu tenho um arquivo&lt;code&gt;/root/secrets.txt&lt;/code&gt;que só o&lt;code&gt;root&lt;/code&gt;consegue ver. Estou logado como um usuário normal(não root). Vamos criar uma imagem Docker a partir desse Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; debian:stretch&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["cat", "/tmp/secrets.txt"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E finalmente, vamos executar esse&lt;code&gt;Dockerfile&lt;/code&gt;, montando um volume a partir do&lt;code&gt;/root/secrets.txt&lt;/code&gt;que não possa ler o arquivo&lt;code&gt;/tmp/secrets.txt&lt;/code&gt;dentro do container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;marc@srv:~$ docker run -v /root/secrets.txt:/tmp/secrets.txt &amp;lt;img&amp;gt;
top secret stuff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mesmo sendo&lt;code&gt;marc&lt;/code&gt;, o container está rodando como&lt;code&gt;root&lt;/code&gt;e, portanto, tem acesso a tudo que o&lt;code&gt;root&lt;/code&gt;tem acesso neste servidor. Isso não é o ideal; A execução de containers dessa maneira significa que todos os containers que você acessa do Docker Hub podem ter acesso total a tudo em seu servidor (dependendo de como você o executa).&lt;/p&gt;

&lt;h2&gt;
  
  
  Recomendação
&lt;/h2&gt;

&lt;p&gt;A recomendação é criar um usuário com um&lt;code&gt;uid&lt;/code&gt;conhecido no&lt;code&gt;Dockerfile&lt;/code&gt;e rodar a aplicação usando esse usuário. O começo do&lt;code&gt;Dockerfile&lt;/code&gt;deve seguir o seguinte padrão:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; &amp;lt;base image&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;groupadd &lt;span class="nt"&gt;-g&lt;/span&gt; 999 appuser &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    useradd &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; 999 &lt;span class="nt"&gt;-g&lt;/span&gt; appuser appuser
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; appuser&lt;/span&gt;
... &amp;lt;rest of Dockerfile&amp;gt; ...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usando esse padrão é fácil executar um container no contexto do usuário/grupo com o mínimo de privilégios necessários.&lt;/p&gt;

&lt;p&gt;Por exemplo, adicionarei isso ao meu&lt;code&gt;Dockerfile&lt;/code&gt;de cima, e o executarei novamente. Meu arquivo ficou assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; debian:stretch&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;groupadd &lt;span class="nt"&gt;-g&lt;/span&gt; 999 appuser &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    useradd &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; 999 &lt;span class="nt"&gt;-g&lt;/span&gt; appuser appuser
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; appuser&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["cat", "/tmp/secrets.txt"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executando esse container com o mesmo comando de antes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;marc@srv:~$ docker run -v /root/secrets.txt:/tmp/secrets.txt &amp;lt;img&amp;gt;
cat: /tmp/secrets.txt: Permission denied
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, o comportamento padrão do container é que ele não terá privilégios de&lt;code&gt;root&lt;/code&gt;no host.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reusando outras imagens
&lt;/h2&gt;

&lt;p&gt;Imagens Docker são incríveis por serem reutilizáveis, mas quando o&lt;code&gt;FROM&lt;/code&gt;de uma imagem é executado através de um usuário normal, seu container herdará esse usuário. Se você precisar criar sua própria imagem ou executar operações como&lt;code&gt;root&lt;/code&gt;tenha certeza que&lt;code&gt;USER root&lt;/code&gt;esteja próximo do topo de seu&lt;code&gt;Dockerfile&lt;/code&gt;. Então&lt;code&gt;FROM appuser&lt;/code&gt;para torná-lo utilizável.&lt;/p&gt;

&lt;h2&gt;
  
  
  Executando outros containers como usuários normais (non-root)
&lt;/h2&gt;

&lt;p&gt;Imagens Docker são feitas para serem portáteis, e é normal obter outras imagens do Docker Hub. Algumas delas (imagens oficiais) seguirão as melhores práticas e serão executadas como usuários normais (non-root), mas muitas imagens não fazem isso. Muitas simplesmente executam as coisas como&lt;code&gt;root&lt;/code&gt;e deixam pra você descobrir como executar as coisas com segurança. Existem opções que permitirão você rodar uma imagem de forma segura que não foi criada por você.&lt;/p&gt;

&lt;h3&gt;
  
  
  Criando outra imagem
&lt;/h3&gt;

&lt;p&gt;Primeiro, uma opção é criar outra imagem usando a imagem original com a camada&lt;code&gt;FROM&lt;/code&gt;. Então você poderá criar um usuário, e copiar o&lt;code&gt;ENTRYPOINT&lt;/code&gt;origin e diretrizes do&lt;code&gt;CMD&lt;/code&gt;para sua própria imagem. Isso resultará em uma nova imgem que seguirá as boas práticas citadas aqui, garantindo que sua execução ocorra de forma segura. O que pode incomodar nesse ponto é que você precisará rebuildar sua imagem quando a imagem base for atualizada. Você terá que configurar um processo para fazer esse rebuild quando a imagem base for rebuildada.&lt;/p&gt;

&lt;h3&gt;
  
  
  Especificando um uid quando iniciando um container
&lt;/h3&gt;

&lt;p&gt;Finalmente você pode criar um usuário no host e passar o&lt;code&gt;uid&lt;/code&gt;pro Docker quando o container for iniciado. Por exemplo, revisitando o exemplo do&lt;code&gt;Dockerfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; debian:stretch&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["cat", "/tmp/secrets.txt"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Eu consigo executar esse container com ou sem o parâmetro user_id e ver os diferentes resultados(o user_id 1001 representa minha conta atual nesse servidor):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run --user 1001 -v /root/secrets.txt:/tmp/secrets.txt &amp;lt;img&amp;gt;
cat: /tmp/secrets.txt: Permission denied

$ docker run -v /root/secrets.txt:/tmp/secrets.txt &amp;lt;img&amp;gt;
top secret stuff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso funciona e é a mesma coisa que criar um usuário no&lt;code&gt;Dockerfile&lt;/code&gt;, mas requer que o usuário opte por executar o container com segurança. Especificar um usuário normal (non-root) no&lt;code&gt;Dockerfile&lt;/code&gt;fará com que o container seja executado com segurança por padrão.&lt;/p&gt;

&lt;h2&gt;
  
  
  Para leitura futura
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://medium.com/@mccode/understanding-how-uid-and-gid-work-in-docker-containers-c37a01d01cf"&gt;Understanding how uid and gid work in Docker containers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/engine/reference/commandline/run/"&gt;Official reference to the Docker Run command (Docker)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/engine/security/security/"&gt;Docker Security&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;— -&lt;/p&gt;

&lt;p&gt;Se você está usando Docker para lançar uma aplicação SaaS, você deveria verificar&lt;a href="http://www.replicated.com/"&gt;www.replicated.com&lt;/a&gt;para poder lançar uma versão corporativa e instalável do seu produto.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Uma lista comovente de links para estudar tecnologia</title>
      <dc:creator>Allan Ramos</dc:creator>
      <pubDate>Wed, 14 Apr 2021 20:50:13 +0000</pubDate>
      <link>https://dev.to/allangrds/uma-lista-comovente-de-links-para-estudar-tecnologia-5aia</link>
      <guid>https://dev.to/allangrds/uma-lista-comovente-de-links-para-estudar-tecnologia-5aia</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Você teria links pra quem está começando com programação?— disse alguém.&lt;/p&gt;

&lt;p&gt;Você teria links para pessoas que desejam ser devs? — disse outra pessoa.&lt;/p&gt;

&lt;p&gt;Gente, o que vocês acompanham de blogs?— disse eu a meus colegas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vai e vem, e vou montando uma mega lista. Aproveitando isso, achei melhor colocar tudo isso em uma postagem, já que você, assim como eu e muitos, podem precisar das referências aqui presentes.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Observação&lt;/strong&gt;: Não coloquei e não colocarei meetups por ser algo regional.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Livros
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Em português
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://leanpub.com/dockerparadesenvolvedores"&gt;Docker para desenvolvedores&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.altabooks.com.br/o-codificador-limpo.html"&gt;O codificador limpo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.altabooks.com.br/domain-driven-design-atacando-as-complexidades-no-coracao-do-software-3a-edicao.html"&gt;Domain Driven Design: Atacando as complexidades no coração do software&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.altabooks.com.br/implementando-domain-driven-design.html"&gt;Implementando Domain Drive Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com.br/Trabalho-Eficaz-com-C%C3%B3digo-Legado/dp/8582600321"&gt;Trabalho Eficaz com Código Legado&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com.br/Algoritmos-Teoria-Pr%C3%A1tica-Thomas-Cormen/dp/8535236996"&gt;Algoritmos: Teoria e Prática&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Em inglês
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com.br/Code-Complete-Steve-McConnell/dp/0735619670"&gt;Code Complete&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com.br/Refactoring-Improving-Design-Existing-Code/dp/0134757599/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1544733988&amp;amp;sr=1-1&amp;amp;keywords=Refactoring+martin"&gt;Refactoring: Improving the Design of Existing Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Canais
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Brasileiros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCSfwM5u0Kce6Cce8_S72olg/featured"&gt;Rocketseat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCtIygB7LtILSFWR0kxtZC-A"&gt;DEVNAESTRADA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCJnKVGmXRXrH49Tvrx5X0Sw"&gt;Linux Tips&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCnLdHOuue5i1O7TsH6oh07w"&gt;BrazilJs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCaXHZLldk54oEwDDAxY_i4A"&gt;Code Experts Learning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCU5JicSrEM5A63jkJ2QvGYw/videos"&gt;Filipe Deschamps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCNhSCufrcOMeFvzEM7tt9Lw"&gt;Pagar.me Talks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCVheRLgrk7bOAByaQ0IVolg"&gt;CollabCode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCFuIUoyHB12qpYa8Jpxoxow"&gt;Código Fonte TV&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/user/CursoDeProgramacao/videos"&gt;Harlley Oliveira&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCWrqsnPLl6aRX0ECUmPaZEw/videos"&gt;O Universo da Programação&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCkqOofjb7nl6V8vXrIbGtiQ"&gt;Rodrigo Branas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?list=UUNTX_S7zq9h_MKhPljMIoYw&amp;amp;v=LbT52rHHk1c"&gt;Imasters&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Internacionais
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCO1cgjhGzsSYb1rsB4bFe4Q"&gt;Fun Fun Function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCtxCXg-UvSnTKPOzLH4wJaQ/featured"&gt;Coding Tech&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCyIe-61Y8C4_o-zZCtO4ETQ"&gt;DevTips&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCjX0FtIZBBVD3YoCcxnDC4g"&gt;dcode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCP_lo1MFyx5IXDeD9s_6nUw"&gt;Facebook Developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCs_tLP3AiwYKwdUHpltJPuA"&gt;GOTO Conference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCkQX1tChV7Z7l1LFF4L9j_g"&gt;InfoQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCzoVCacndDCfGDf41P-z0iA"&gt;JSConf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCVTlvUkGslCV_h-nSAId8Sw"&gt;LearnCode Academy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCm9iiIfgmVODUJxINecHQkA"&gt;ng-conf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UC3BGlwmI-Vk6PWyMt15dKGw"&gt;O'Reilly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCaYhcUwRBNscFNUKTjgPFiA"&gt;Rust&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCl0hPcsUmeld49qmWWSQKOg/videos"&gt;Source Coded&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UC_QIfHvN9auy2CoOdSfMWDw/videos"&gt;Strange Loop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCTdw38Cw6jcm0atBPA39a0Q/videos"&gt;NDC Conference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCZ_EWaQZCZuGGfnuqUoHujw/videos"&gt;Hello Rust&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCQPYJluYC_sn_Qz_XE-YbTQ/videos"&gt;node.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCEtohQeDqMSebi2yvLMUItg/videos"&gt;Lambda Conf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UC9-y-6csu5WGm29I7JiwpnA"&gt;Computerphile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCEBb1b_L6zDS3xTUrIALZOw"&gt;MIT OpenCourseWare&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/channel/UCUR1pFG_3XoZn3JNKjulqZg"&gt;Thoughtbot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Podcasts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Brasileiros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://soundcloud.com/testcastbrasil"&gt;TestCast Brasil&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://labs.bluesoft.com.br/category/podcast/"&gt;Bluesoft Labs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hipsters.tech/category/podcast/"&gt;Hipsters Ponto Tech&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devnaestrada.com.br/"&gt;DEVNAESTRADA&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://tecnologicamentearretado.com.br/"&gt;Tecnologicamente Arretado&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://player.fm/series/26914"&gt;Grok Podcast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://quebradev.com.br/"&gt;QuebraDev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://podtail.com/en/podcast/lendocast/"&gt;LendoCast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.10deploys.com/"&gt;10 deploys&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.lambda3.com.br/tag/podcast/"&gt;Lambda3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mundopodcast.com.br/podprogramar/"&gt;PodProgramar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pizzadedados.com/"&gt;Pizza de Dados&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://databasecast.com.br/wp/"&gt;DatabaseCast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soundcloud.com/umblercast"&gt;UmblerCast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.taller.net.br/tag/podcast/"&gt;Taller&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zofe.com.br/"&gt;Zone of Front-Enders&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://areadetransferencia.com.br/"&gt;Área de Transferência&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elemencast.github.io/#/episodios/"&gt;Elemencast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.segurancalegal.com/"&gt;Segurança Legal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sudocast.com.br/"&gt;SudoCast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soundcloud.com/castaliopodcast"&gt;Castálio Podcast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soundcloud.com/castaliopodcast"&gt;Hack 'n' Cast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://seginfo.com.br/seginfocast/"&gt;SegInfocast&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Internacionais
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.arresteddevops.com/"&gt;Arrested DevOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://allthingsdevops.bigbinary.com/"&gt;All Thing DevOps Podcast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://talkpython.fm/episodes/all"&gt;Talk Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devchat.tv/js-jabber/"&gt;Javascript Jabber&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hanselminutes.com/"&gt;THE HANSELMINUTES PODCAST&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://changelog.com/podcasts"&gt;All Changelog Podcasts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://designdetails.fm/"&gt;Design Details&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spec.fm/podcasts/developer-tea"&gt;Developer Tea&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spec.fm/podcasts/toolsday"&gt;Toolsday&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spec.fm/podcasts/reactpodcast"&gt;React Podcast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spec.fm/podcasts/immutable"&gt;Immutable&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://softwareengineeringdaily.com/"&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://leanstartup.co/podcasts/"&gt;Lean Startup Podcast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.se-radio.net/"&gt;Software Engineering Radio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://podcast.hackernoon.com/"&gt;Hackernoon Podcast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.legacycode.rocks/podcast-1"&gt;Legacy Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.producthunt.com/radio"&gt;Product Hunter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://testandcode.com/"&gt;Test &amp;amp; Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.collaborationsuperpowers.com/podcasts/"&gt;Collaboration Superpowers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ryanripley.com/agile-for-humans/"&gt;Agile for Humans&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.fullstackradio.com/"&gt;FullStack Radio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codenewbie.org/basecs"&gt;CodeNewbie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://apisyouwonthate.com/podcast/"&gt;API Busters&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.fiveminutegeekshow.com/"&gt;The Five-Minute Geek Show&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://soundcloud.com/serverlesspodcast"&gt;Serverless Podcast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.codingblocks.net/"&gt;Conding Blocks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://thisdeveloperslife.com/"&gt;The Developers Life&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://syntax.fm/"&gt;Syntax.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://thewebahead.net/episodes"&gt;The Web Ahead&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://5by5.tv/bigwebshow"&gt;5by5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://changelog.com/jsparty"&gt;JS Party&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Blogs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Brasileiros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.proof.com.br/blog/"&gt;PROOF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://churrops.io/"&gt;ChurrOps on DevOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href=""&gt;TI Mandic&lt;/a&gt;&lt;a href="https://blog.mandic.com.br/"&gt;https://blog.mandic.com.br/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.maujor.com/blog/"&gt;Maujor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://odesenvolvedor.com.br/"&gt;O Desenvolvedor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nandovieira.com.br/"&gt;Nando Vieira&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://seginfo.com.br/"&gt;SegInfo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.akitaonrails.com/"&gt;Akita On Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/trainingcenter"&gt;Training Center&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/tableless"&gt;Tableless&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.codecasts.com.br/?gi=274cd494cf01"&gt;Codecasts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/pagarme"&gt;Pagar.me&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Internacionais
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.atlassian.com/blog"&gt;Atlassian&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devopscube.com/"&gt;DevOps Cube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.docker.com/blog/"&gt;Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.upguard.com/blog"&gt;UpGuard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devops.com/category/blogs/"&gt;DevOps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://davidwalsh.name/"&gt;David Walsh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://scotch.io/"&gt;Scoth.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thenewstack.io/"&gt;The New Stack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/"&gt;Dev.to&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.logrocket.com/"&gt;LogRocket&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/"&gt;freeCodeCamp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hackernoon.com/"&gt;hackernoon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Dicas extras
&lt;/h2&gt;

&lt;p&gt;Para gerenciar esse mar de blogs utilizo o Feedly, uma platataforma onde você assina o feed desses sites, e categorizar cada assinatura, deixando tudo organizado para acompanhar diversos artigos relacionados de uma vez.&lt;/p&gt;

&lt;p&gt;E para podcasts, no meu celular utilizo o Podcast Addict.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
