<?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: Guilherme Siquinelli</title>
    <description>The latest articles on DEV Community by Guilherme Siquinelli (@guiseek).</description>
    <link>https://dev.to/guiseek</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%2F531838%2Fe540fb1d-71bf-47e7-ace4-7d37ce952208.png</url>
      <title>DEV Community: Guilherme Siquinelli</title>
      <link>https://dev.to/guiseek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/guiseek"/>
    <language>en</language>
    <item>
      <title>Angular Typed Forms, a melhor forma de tipar seus formulários</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Tue, 06 Aug 2024 06:17:58 +0000</pubDate>
      <link>https://dev.to/guiseek/angular-typed-forms-a-melhor-forma-de-tipar-seus-formularios-hpg</link>
      <guid>https://dev.to/guiseek/angular-typed-forms-a-melhor-forma-de-tipar-seus-formularios-hpg</guid>
      <description>&lt;p&gt;Fora abstrações, existem 3 classes para trabalhar com formulários no Angular.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;FormControl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FormGroup&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FormArray&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Geralmente nossos formulários representam alguma entidade ou modelo da nossa aplicação, principalmente quando falamos de CRUDs, como você pode ver no vídeo.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/L-odCf4MfJc?start=143"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Porém, o vídeo mostra um exemplo de formulário onde os tipos são inferidos pelo formulário já estarem preenchidos, mas como sabemos, a vida real não é assim que acontece, quem preenche o formulário são os usuários ou o banco de dados. Não acaba aqui, para adicionar a tipagem no formulário não basta apenas colocar nossa classe ou interface como generics, pois o &lt;code&gt;FormGroup&lt;/code&gt; não aceita.&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%2Fe8904m9y2h1wqr5a4m1h.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%2Fe8904m9y2h1wqr5a4m1h.png" alt="Image description" width="800" height="730"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fora que ainda sim, os tipos que importam de verdade, os relacionados a nossas interfaces, ficaram como &lt;code&gt;any&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  🤷‍♂️
&lt;/h1&gt;

&lt;p&gt;Nós não queremos saber se é um &lt;code&gt;FormGroup&lt;/code&gt; ou um &lt;code&gt;FormControl&lt;/code&gt;, o que queremos saber é:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Isso é uma string ou um número?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para que funcione a interface do mundo real, seria algo assim:&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%2Fisa9zfpdt8bfp62cdtko.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%2Fisa9zfpdt8bfp62cdtko.png" alt="Image description" width="800" height="884"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ou seja, precisamos criar uma segunda interface se adequando.&lt;/p&gt;

&lt;h2&gt;
  
  
  Praticamente inviável na minha humilde opinião. 🤨
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ___________________________________
 /                                   \
(  mas como isso pode ser resolvido?  )
 \___________________________________/
         \   ^__^
          \  (oo)\_______
             (__)\       )\/\
                 ||----w |
                 ||     ||
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como não encontrei nada parecido na documentação, tive de escrever eu mesmo um tipo que contorne esta dificuldade, que permite setar a interface no &lt;code&gt;FormGroup&lt;/code&gt; &lt;code&gt;root&lt;/code&gt; e tudo resolvido, e apesar deu ter usado recursividade, ficou mais simples do que imaginei que pudesse ficar.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;FormArray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormControl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormGroup&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;@angular/forms&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;DetectType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;U&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;FormArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DetectType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;U&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;FormGroup&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TypedForm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormControl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;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;TypedForm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;DetectType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  E veja, funciona mesmo! 🙂
&lt;/h2&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%2Fei44iu33e5nix6gcv0tj.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%2Fei44iu33e5nix6gcv0tj.png" alt="Image description" width="800" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bom, já vimos que funciona bem com o exemplo de tipo mostrado na documentação, agora vamos adentrar um pouco mais a vida real...&lt;/p&gt;

&lt;p&gt;É uma prática comum que objetos como endereço e opções estejam segmentados em outros tipos separados, pois podem ser reutilizados em outras partes da aplicação, desta forma:&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;street&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FoodOption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;food&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CoolParty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Address&lt;/span&gt;
  &lt;span class="na"&gt;forma1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
  &lt;span class="na"&gt;foodOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FoodOption&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;E bom, se o tipo pode ser reaproveitado em outros lugares da aplicação, o formulário também, certo? Minha recomendação é que estes formulários sejam quebrados em partes e usados em conjunto.&lt;/p&gt;

&lt;h2&gt;
  
  
  É desta forma que costumo fazer:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AddressForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;FormGroup&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TypedForm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;number&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;FormControl&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;street&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;FormControl&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FoodOptionForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;FormGroup&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TypedForm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FoodOption&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;food&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;FormControl&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;price&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;FormControl&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PartyForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;FormGroup&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TypedForm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CoolParty&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;address&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;AddressForm&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;forma1&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;FormControl&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;foodOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;FormArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FoodOptionForm&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;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;addOption&lt;/span&gt;&lt;span class="p"&gt;()&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;controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foodOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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;FoodOptionForm&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;removeOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&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;controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foodOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&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;Isso mesmo, orientação a objetos funciona muito bem pra isso!&lt;/p&gt;

&lt;p&gt;E repare outro benefício, na classe &lt;code&gt;PartyForm&lt;/code&gt;, criei os métodos &lt;code&gt;addOption&lt;/code&gt; e &lt;code&gt;removeOption&lt;/code&gt;, que adiciona uma nova opção ou remove do array &lt;code&gt;foodOptions&lt;/code&gt;, isso será útil na implementação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dá pra melhorar ainda?
&lt;/h2&gt;

&lt;p&gt;Dá sim, vamos facilitar o momento de alteração dos dados, permitindo preencher os dados já no momento da criação da instância.&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AddressForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;FormGroup&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TypedForm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Address&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&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;address&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Address&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;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;number&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;FormControl&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;street&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;FormControl&lt;/span&gt;&lt;span class="p"&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;address&lt;/span&gt;&lt;span class="p"&gt;)&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="nf"&gt;patchValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;address&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FoodOptionForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;FormGroup&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TypedForm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FoodOption&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&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;option&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FoodOption&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;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;food&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;FormControl&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;price&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;FormControl&lt;/span&gt;&lt;span class="p"&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;option&lt;/span&gt;&lt;span class="p"&gt;)&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="nf"&gt;patchValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;option&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PartyForm&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;FormGroup&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TypedForm&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CoolParty&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&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;party&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CoolParty&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;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;address&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;AddressForm&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;forma1&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;FormControl&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;foodOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;FormArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FoodOptionForm&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;})&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;party&lt;/span&gt;&lt;span class="p"&gt;)&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="nf"&gt;patchValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;party&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="nf"&gt;addOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FoodOption&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;{&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;controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foodOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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;FoodOptionForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;option&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;removeOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&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;controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;foodOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&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;Recomendo esta forma de trabalhar com formulário, fica bem prático!&lt;/p&gt;

&lt;p&gt;Espero que essa dica seja útil a você leitor.&lt;/p&gt;

&lt;p&gt;Um abraço&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>entities</category>
    </item>
    <item>
      <title>Numerical formatting from 0 to 99 with autocomplete sorted correctly. TypeScript series: Template literal types</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Sun, 27 Aug 2023 22:12:09 +0000</pubDate>
      <link>https://dev.to/guiseek/numerical-formatting-from-0-to-99-with-autocomplete-sorted-correctlytypescript-series-template-literal-types-p56</link>
      <guid>https://dev.to/guiseek/numerical-formatting-from-0-to-99-with-autocomplete-sorted-correctlytypescript-series-template-literal-types-p56</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;N&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;|&lt;/span&gt; &lt;span class="mi"&gt;2&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="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;5&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;|&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`0&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;N&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;N&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;0`&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;N&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;N&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>API da Web para Ativação de interação do usuário com a página</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Sat, 15 Jul 2023 01:41:39 +0000</pubDate>
      <link>https://dev.to/guiseek/api-da-web-para-ativacao-de-interacao-do-usuario-com-a-pagina-2872</link>
      <guid>https://dev.to/guiseek/api-da-web-para-ativacao-de-interacao-do-usuario-com-a-pagina-2872</guid>
      <description>&lt;p&gt;Por padrão, o navegador não permite a execução de alguns tipos de conteúdos ou ações sem que antes o usuário tenha ativado algum tipo interação com a página.&lt;/p&gt;

&lt;p&gt;Sendo mais específico, algum tipo de interação precisa ser alguma das que listarei abaixo e com alguns requisitos, como:&lt;/p&gt;

&lt;h2&gt;
  
  
  Eventos de ativação aceitos como interação
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;keydown&lt;/code&gt; (exceto para a tecla Esc ou nenhuma tecla que sirva de atalho para o agente do usuário)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mousedown&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pointerdown&lt;/code&gt; (apenas se a propriedade &lt;code&gt;pointerType&lt;/code&gt; for &lt;code&gt;"mouse"&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pointerup&lt;/code&gt; (apenas se &lt;code&gt;pointerType&lt;/code&gt; não for &lt;code&gt;"mouse"&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;touchend&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quando algum destes eventos é acionado, o agente do usuário diferencia entre dois tipos de estados de ativação possíveis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ativação &lt;strong&gt;permanente&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Ativação &lt;strong&gt;transitória&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ativação transitória
&lt;/h3&gt;

&lt;p&gt;Trata-se de um estado em que a janela indica que um usuário pressionou recentemente um botão, moveu o mouse, usou um menu ou realizou alguma outra interação. Ela expira após um tempo limite (se não for renovada por outra interação) e também pode ser consumida por algumas APIs, como a &lt;code&gt;Window.open()&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Aqui está uma lista de APIs da Web que requerem ativação transitória:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Window.open()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Window.showOpenFilePicker()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Window.showSaveFilePicker()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Window.showDirectoryPicker()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Window.getScreenDetails()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Window.queryLocalFonts()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Clipboard.read()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Clipboard.readText()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Clipboard.writeText()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Document.requestStorageAccess()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Element.requestFullScreen()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Element.requestPointerLock()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GPUAdapter.requestAdapterInfo()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HID.requesstDevice()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HTMLInputElement.showPicker()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HTMLVideoElement.requestPictureInPicture()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IdleDetector.requestPermission()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MediaDevices.selectAudioOutput()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MediaStreamTrack.sendCaptureAction()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MediaDevices.getViewportMedia()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MediaDevices.getDisplayMedia()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Navigator.share()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PaymentRequest.show()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PresentationRequest.start()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RemotePlayback.prompt()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;USB.requestDevice()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Keyboard.lock()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;XRSystem.requestSession()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ativação permanente
&lt;/h3&gt;

&lt;p&gt;Este estado indica que um usuário pressionou algum botão, moveu um mouse, usou um menu ou realizou algum outro tipo de interação. Ao contrário da transitória, este estado não é redefinido depois de ter sido definido inicialmente.&lt;/p&gt;

&lt;h4&gt;
  
  
  Lista de APIs da Web que requerem ativação permanente:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Navigator.vibrate()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;VirtualKeyboard.show()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;autoplay&lt;/code&gt; em mídias (especialmente para &lt;code&gt;AudioContext&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  API da Web &lt;code&gt;UserActivation&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Para determinar programaticamente se uma página tem ativação permanente ou transitória do usuário, a API &lt;em&gt;UserActivation&lt;/em&gt; fornece duas propriedades que estão disponíveis para consumo usando &lt;code&gt;navigator.userActivation&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;UserActivation.hasBeenActive&lt;/code&gt; (indica se a página tem ativação &lt;strong&gt;permanente&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UserActivation.isActive&lt;/code&gt; (indica se a página tem ativação &lt;strong&gt;transitória&lt;/strong&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Desta forma podemos usar as APIs da Web listadas acima apenas quando uma das respectivas propriedades acima requeridas for verdadeira.&lt;/p&gt;

&lt;p&gt;Usando algum dos eventos de interação apresentados no início do artigo, podemos verificar alguma das duas propriedades acima como validação e só então, caso haja interação, o uso da API desejada pode ser utilizada sem nenhum problema.&lt;/p&gt;

&lt;p&gt;Assim temos um software mais estável e o mais importante, que respeita seu usuário!&lt;/p&gt;

&lt;p&gt;Obrigado a você que leu até aqui e aproveite para deixar um comentário dizendo o que achou do conteúdo.&lt;/p&gt;

&lt;p&gt;Abraços!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Injeção de dependências para uma Arquitetura limpa</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Wed, 24 May 2023 02:27:05 +0000</pubDate>
      <link>https://dev.to/guiseek/injecao-de-dependencias-para-uma-arquitetura-limpa-5ein</link>
      <guid>https://dev.to/guiseek/injecao-de-dependencias-para-uma-arquitetura-limpa-5ein</guid>
      <description>&lt;p&gt;Parafraseando &lt;a href="http://cleancoder.com"&gt;Robert C. Martin&lt;/a&gt; em seu livro &lt;a href="https://www.amazon.com.br/Arquitetura-Limpa-artes%C3%A3o-estrutura-software-ebook/dp/B085PP6Y8P"&gt;Arquitetura limpa&lt;/a&gt;, mais precisamente no capítulo 5, quando fala sobre &lt;strong&gt;inversão de dependência&lt;/strong&gt; (pag 44). O paradigma OO geralmente proporciona maior facilidade para a aplicação da inversão de dependências, este é um dos princípios SOLID e permite direcionar as dependências do código. Assim não precisamos alinhá-las junto ao fluxo da aplicação de forma acoplada e por consequência dificultando mudanças no projeto.&lt;/p&gt;

&lt;p&gt;A possibilidade de escolher responsáveis para determinadas tarefas e trocá-los a qualquer momento nos dá poder! E o que fazemos com ele? Por exemplo, você pode reorganizar as dependências do código para que regras de negócio não dependam de componentes front-end ou da técnica adotada e usada até este momento do projeto para acesso a dados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T2CWGM3A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u851jy3snzsi2ogy8nkl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T2CWGM3A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u851jy3snzsi2ogy8nkl.png" alt="Gráfico de dependências" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note o domínio (regras de negócio) no canto inferior esquerdo, isolado. Enquanto a camada data-access (acesso a dados) faz o intermédio entre ela e as camadas feature e a aplicação, que é onde estão nossos componentes front-end.&lt;/p&gt;

&lt;p&gt;Pode não ser intuitivo aos primeiros olhares, mas isso faz com que essas camadas se tornem plug-ins para as regras de negócio, que é onde há menos mudanças e maior valor no software.&lt;/p&gt;

&lt;p&gt;Além disso, as regras de negócio, a UI e o acesso a dados podem ser transpilados em pacotes separados e independentes, unidades publicáveis com as mesmas dependências. Contudo, o pacote de regras de negócio não dependerá dos pacotes que contém a UI e o acesso a dados.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nHkzbxP7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fanqp8ua3w27lmn0aoua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nHkzbxP7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fanqp8ua3w27lmn0aoua.png" alt="Gráfico de tarefas executoras" width="800" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Significa que as regras de negócio podem ser implantadas independentemente da UI e da camada de acesso a dados. Que por sua vez, permite que haja deploy em momentos diferentes, independentes, permitindo que times diferentes trabalhem em seus respectivos pacotes sem impactos entre eles. Pois mudanças em componentes da UI ou do acesso a dados, por exemplo, não devem ter nenhum efeito negativo sobre as regras de negócio. &lt;/p&gt;

&lt;p&gt;Veja este repositório: &lt;a href="https://github.com/guiseek/getlab"&gt;getlab&lt;/a&gt;, ele está dividido em pacotes como camadas e suas respectivas responsabilidades, como abordado até agora. A branch main, a camada de acesso a dados, está usando Storage do navegador como base de dados.&lt;/p&gt;

&lt;p&gt;Para fazer a substituição de Storage para acesso a uma API REST com persistência em uma base NoSQL, foi necessário implementar as classes responsáveis por isso, ou seja, classes concretas para &lt;a href="https://github.com/guiseek/getlab/blob/mongodb/libs/data-access/src/lib/infrastructure/team-http.repository.ts"&gt; TeamRepository&lt;/a&gt; e &lt;a href="https://github.com/guiseek/getlab/blob/mongodb/libs/data-access/src/lib/infrastructure/schedule-http.repository.impl.ts"&gt;ScheduleRepository&lt;/a&gt;, depois substituí-las nos registros de dependências. Como está na branch mongodb.&lt;/p&gt;

&lt;p&gt;Se antes estávamos usando desta forma&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="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TeamRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TeamStorageRepositoryImpl&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;Podemos apenas alterar quem será usado a partir de agora&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="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TeamRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TeamHttpRepositoryImpl&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="https://github.com/guiseek/getlab/blob/afccbeebfd9003f9bcad13f428f9e66505fcefa7/libs/data-access/src/lib/providers.ts#L44"&gt;Veja o código&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora sempre que pedirmos TeamRepository, teremos uma instância de TeamHttpRepositoryImpl&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;teamRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;TeamRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// TeamHttpRepositoryImpl&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sem que nenhuma alteração em regras de negócios ou componentes da UI fossem necessárias.&lt;/p&gt;

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

&lt;p&gt;Vimos que devemos dividir as responsabilidades do código em camadas, vimos também que uma responsabilidade não deve interferir em outras e que principalmente devemos proteger a camada onde estão nossas regras de negócios. Com isso é possível ter times trabalhando de forma isolada e independentes. Mas como isso pode ser feito?&lt;/p&gt;

&lt;h3&gt;
  
  
  Vejo duas soluções / oportunidades
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Apresentar o design pattern &lt;strong&gt;Dependency Injection&lt;/strong&gt; (Injeção de Dependências);&lt;/li&gt;
&lt;li&gt;Falar sobre divisão de camadas utilizando arquitetura em monorepos;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Digo isso pois em uma aplicação Front-end comum, não basta dividir o código em camadas de diretórios para que seja possível executar build como pacotes independentes e é neste ponto que entra a arquitetura de monorepos, no entanto, é um tema que gera assunto para um outro artigo inteiro, então escreverei o próximo aprofundando estes dois assuntos, combinado?&lt;/p&gt;

&lt;p&gt;Abraços&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>frontend</category>
      <category>architecture</category>
    </item>
    <item>
      <title>SOLID explicado com TypeScript</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Sun, 21 May 2023 23:16:30 +0000</pubDate>
      <link>https://dev.to/guiseek/solid-27jn</link>
      <guid>https://dev.to/guiseek/solid-27jn</guid>
      <description>&lt;p&gt;Alguns princípios foram criados para ajudar pessoas desenvolvedoras a criar sistemas que sejam fáceis de entender, manter e evoluir ao longo do tempo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Princípios
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Single Responsibility Principle&lt;/strong&gt; (&lt;em&gt;Princípio da Responsabilidade Única&lt;/em&gt;):&lt;br&gt;
Diz que uma classe deve ter apenas uma única responsabilidade e assim, um único motivo para mudar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Open-Closed Principle&lt;/strong&gt; (&lt;em&gt;Princípio do Aberto-Fechado&lt;/em&gt;):&lt;br&gt;
Diz que uma classe deve estar aberta para novos cenários, mas fechada para modificação.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Liskov Substitution Principle&lt;/strong&gt; (&lt;em&gt;Princípio da Substituição de Liskov&lt;/em&gt;):&lt;br&gt;
Diz que os objetos de uma classe derivada devem ser substituíveis por objetos de sua classe base sem alterar o comportamento do software.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Interface Segregation Principle&lt;/strong&gt; (&lt;em&gt;Princípio da Segregação de Interface&lt;/em&gt;):&lt;br&gt;
Diz que interfaces devem ser separadas para que classes possam depender apenas dos métodos que utilizam.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dependency Inversion Principle&lt;/strong&gt; (&lt;em&gt;Princípio da Inversão de Dependência&lt;/em&gt;):&lt;br&gt;
Diz que módulos de alto nível não devem depender de módulos de baixo nível. Ambos devem depender de abstrações.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ao seguir esses princípios, conseguimos criar sistemas mais flexíveis, robustos e fáceis de manter, alterar e evoluir ao longo do tempo.&lt;/p&gt;

&lt;p&gt;Vamos mergulhar um pouco mais fundo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single Responsibility Principle
&lt;/h3&gt;

&lt;p&gt;Ter uma responsabilidade única significa que uma classe deve ter apenas um motivo para mudar. Se uma classe tiver mais de uma responsabilidade, mudanças em uma responsabilidade podem afetar outras responsabilidades, o que pode levar a um código mais complexo e difícil de manter.&lt;/p&gt;

&lt;p&gt;Darei um exemplo mais claro sobre o que podem ser consideradas responsabilidades diferentes.&lt;/p&gt;

&lt;p&gt;Suponha que tenhamos uma classe chamada &lt;strong&gt;&lt;code&gt;User&lt;/code&gt;&lt;/strong&gt; que é responsável tanto pela autenticação do usuário quanto pelo envio de notificações por e-mail.&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="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&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="nx"&gt;password&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;void&lt;/span&gt;
  &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;sendCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&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="nx"&gt;code&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;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ela possui responsabilidades diferentes e não segue o princípio &lt;strong&gt;SRP&lt;/strong&gt;. Podemos dividir as responsabilidades em duas classes diferentes.&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="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Auth&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&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="nx"&gt;password&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;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&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="nx"&gt;message&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;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assim, caso haja uma mudança em uma das responsabilidades, a outra não será afetada, o código estará mais organizado, fácil de entender, testar e manter. O que facilita sua reutilização, pois as classes que têm apenas uma responsabilidade podem ser usadas em diferentes partes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open-Closed Principle
&lt;/h3&gt;

&lt;p&gt;Uma classe deve permitir ser estendida para atender a novos requisitos, sem necessidade de alteração, ou seja, deve permitir adicionar novas funcionalidades usando herança, sem afetar o comportamento existente. Por exemplo, temos uma classe abstrata contendo alguns métodos básicos para comunicação com alguma fonte de dados.&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="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Repository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&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;abstract&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt; &lt;span class="k"&gt;void&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;Então criamos uma abstração específica com um método contextual, sem alterar &lt;code&gt;Repository&lt;/code&gt;.&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="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Repository&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&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;abstract&lt;/span&gt; &lt;span class="nf"&gt;findOneByEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para seguir o &lt;strong&gt;OCP&lt;/strong&gt;, a classe deve depender de abstrações em vez de implementações concretas. Isso significa que a classe deve depender de interfaces ou classes abstratas em vez de depender diretamente de classes concretas. As extensões podem ser adicionadas por meio da criação de novas implementações de interfaces ou classes abstratas, sem afetar o existente.&lt;/p&gt;

&lt;h3&gt;
  
  
  Liskov Substitution Principle
&lt;/h3&gt;

&lt;p&gt;Uma classe derivada deve ser capaz de substituir sua classe base sem introduzir erros ou comportamentos inesperados.  Classes derivadas devem manter a mesma semântica que suas classes base, ou seja, implementações devem cumprir os mesmos contratos definidos em suas abstrações. Caso uma subclasse não possa cumprir essas condições, ela não deve ser considerada apta de implementação da classe base.&lt;/p&gt;

&lt;p&gt;Por exemplo, criamos um caso de uso para autenticação.&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SignInUseCase&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="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;repository&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AuthRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserCredential&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;repository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;credential&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;Em seguida, criamos uma abstração que será o contrato para garantir que a classe concreta de &lt;code&gt;AuthRepository&lt;/code&gt; cumpra o acordo de implementação para o método &lt;code&gt;signIn&lt;/code&gt;.&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="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="nf"&gt;signIn&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="nx"&gt;UserCredential&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AuthResponse&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;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora podemos criar implementações diferentes para &lt;code&gt;AuthRepository&lt;/code&gt; que cumpram o contrato, recebendo &lt;code&gt;UserCredential&lt;/code&gt; e retornando &lt;code&gt;Observable&amp;lt;AuthResponse&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Como uma implementação que envia uma &lt;a href="https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Methods" rel="noopener noreferrer"&gt;requisição &lt;em&gt;HTTP&lt;/em&gt;&lt;/a&gt;.&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthHttpRepositoryImpl&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;AuthRepository&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="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;signIn&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="nx"&gt;UserCredential&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;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AuthResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/auth&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E outra como &lt;em&gt;&lt;a href="https://www.notion.so/C-digo-respons-vel-2ad92eebdb444596890e3003bf9f4fcb" rel="noopener noreferrer"&gt;stub&lt;/a&gt;,&lt;/em&gt; usada apenas durante a execução de testes automatizados.&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthStubRepositoryImpl&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;AuthRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;signIn&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="nx"&gt;UserCredential&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;of&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2Vybm...&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Então se uma classe &lt;strong&gt;A&lt;/strong&gt; depende da classe base &lt;strong&gt;B&lt;/strong&gt;, então uma classe derivada &lt;strong&gt;C&lt;/strong&gt; de &lt;strong&gt;B&lt;/strong&gt; deve ser capaz de ser usada como &lt;strong&gt;B&lt;/strong&gt;, sem afetar o software.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A&lt;/strong&gt;: &lt;code&gt;SignInUseCase&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;B&lt;/strong&gt;: &lt;code&gt;AuthRepository&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C&lt;/strong&gt;: &lt;code&gt;AuthHttpRepositoryImpl&lt;/code&gt; e &lt;code&gt;AuthStubRepositoryImpl&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Assim o código se torna mais flexível e escalável, pois novas classes derivadas podem ser adicionadas sem efeitos colaterais indesejados, além de ajudar na prevenção de bugs, pois classes derivadas devem ser testadas com relação aos contratos definidos nas classes base.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interface Segregation Principle
&lt;/h3&gt;

&lt;p&gt;Uma classe deve ter interfaces específicas para as suas funcionalidades, em vez de depender de uma única interface que contenha todas as funcionalidades possíveis.&lt;/p&gt;

&lt;p&gt;Por exemplo, se uma classe precisa apenas de um método de leitura de dados, ela deve implementar uma interface que contenha apenas esse método, em vez de depender de uma interface que contenha também métodos de escrita e exclusão de dados.&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="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;FindOneBy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&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;abstract&lt;/span&gt; &lt;span class="nx"&gt;findOneBy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;K&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&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;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O código se torna mais coeso e menos acoplado, pois dependem apenas de interfaces que precisam, pois temos interfaces mais granulares e específicas, o que facilita a manutenção e reutilização de código. O &lt;strong&gt;ISP&lt;/strong&gt; incentiva a modularidade para que interfaces possam ser adicionadas para atender a novas funcionalidades, sem afetar classes existentes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependency Inversion Principle
&lt;/h3&gt;

&lt;p&gt;Uma classe de alto nível deve depender de uma interface ou classe abstrata ao invés de depender de uma classe concreta de baixo nível.&lt;/p&gt;

&lt;p&gt;Um bom exemplo é a implementação que apresentei no Princípio da Substituição de Liskov em que a classe &lt;code&gt;SignInUseCase&lt;/code&gt; depende de &lt;code&gt;AuthRepository&lt;/code&gt;, que é uma classe abstrata. A substituição entre &lt;code&gt;AuthHttpRepositoryImpl&lt;/code&gt; e &lt;code&gt;AuthStubRepositoryImpl&lt;/code&gt; quando conveniente, é possível utilizando a técnica de injeção de dependências.&lt;/p&gt;

&lt;p&gt;Então, em vez de uma classe de alto nível depender diretamente de uma classe de acesso a dados específica, ela deve depender de uma abstração genérica que represente as funcionalidades que ela precisa.&lt;/p&gt;

&lt;p&gt;Alguns frameworks trabalham desta forma por padrão, como é o caso do &lt;a href="https://angular.io/guide/dependency-injection-in-action" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;, quando este não é o padrão do framework que utilizamos podemos usar alguma biblioteca, como a &lt;a href="https://github.com/inversify/InversifyJS" rel="noopener noreferrer"&gt;Inversify&lt;/a&gt; ou &lt;a href="https://github.com/microsoft/tsyringe" rel="noopener noreferrer"&gt;tsyringe&lt;/a&gt; da Microsoft.&lt;/p&gt;

&lt;p&gt;Assim o código se torna mais flexível e reutilizável, pois os módulos de alto nível são desacoplados dos módulos de baixo nível. Permitindo que diferentes implementações de baixo nível possam ser usadas com a mesma classe de alto nível, sem afetar o código a classe.&lt;/p&gt;

&lt;p&gt;Este princípio recomenda um design orientado a interfaces, que é uma abordagem mais modular e escalável para o desenvolvimento de software. Permitindo que equipes diferentes trabalhem sem que uma dependa diretamente do código da outra.&lt;/p&gt;

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

&lt;p&gt;Espero que este conteúdo tenha agregado positivamente com seu conhecimento,&lt;/p&gt;

&lt;p&gt;Um abraço.&lt;/p&gt;

&lt;p&gt;[]s&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Criando um pacote NPM</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Sun, 26 Mar 2023 00:29:50 +0000</pubDate>
      <link>https://dev.to/guiseek/criando-um-pacote-npm-5an7</link>
      <guid>https://dev.to/guiseek/criando-um-pacote-npm-5an7</guid>
      <description>&lt;p&gt;Você pode adicionar um arquivo &lt;code&gt;package.json&lt;/code&gt; ao seu pacote para facilitar o gerenciamento e a instalação por outras pessoas. Os pacotes publicados no registro devem conter um arquivo &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Um arquivo &lt;code&gt;package.json&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lista os pacotes dos quais seu projeto depende&lt;/li&gt;
&lt;li&gt;especifica versões de um pacote que seu projeto pode usar usando &lt;a href="https://docs.npmjs.com/about-semantic-versioning"&gt;regras de versão semântica&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;torna sua compilação reproduzível e, portanto, mais fácil de compartilhar com outros desenvolvedores&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Observação&lt;/strong&gt;&lt;br&gt;
Para facilitar a localização do pacote no site do npm, recomendamos incluir uma &lt;code&gt;descrição&lt;/code&gt; personalizada no arquivo &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://docs.npmjs.com/creating-a-package-json-file#packagejson-fields"&gt;&lt;/a&gt;Campos &lt;code&gt;package.json&lt;/code&gt; 
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://docs.npmjs.com/creating-a-package-json-file#required-name-and-version-fields"&gt;&lt;/a&gt;Os campos &lt;code&gt;name&lt;/code&gt; e &lt;code&gt;version&lt;/code&gt; são obrigatórios
&lt;/h3&gt;

&lt;p&gt;Um arquivo &lt;code&gt;package.json&lt;/code&gt; deve conter os campos &lt;code&gt;"name"&lt;/code&gt; e &lt;code&gt;"version"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O campo &lt;code&gt;"name"&lt;/code&gt; contém o nome do seu pacote e deve estar em letras minúsculas e uma palavra, e pode conter hífens e sublinhados.&lt;/p&gt;

&lt;p&gt;O campo &lt;code&gt;"version"&lt;/code&gt; deve estar no formato &lt;code&gt;x.x.x&lt;/code&gt; e seguir o &lt;a href="https://docs.npmjs.com/about-semantic-versioning"&gt;diretrizes de versão semântica&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://docs.npmjs.com/creating-a-package-json-file#author-field"&gt;&lt;/a&gt;Campo Author
&lt;/h3&gt;

&lt;p&gt;Se você quiser incluir as informações do autor do pacote no campo &lt;code&gt;"author"&lt;/code&gt;, use o seguinte formato (e-mail e site são opcionais):&lt;/p&gt;

&lt;p&gt;Seu nome &lt;a href="mailto:email@example.com"&gt;email@example.com&lt;/a&gt; (&lt;a href="http://example.com"&gt;http://example.com&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://docs.npmjs.com/creating-a-package-json-file#example"&gt;&lt;/a&gt;Examplo
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"meu-maravilhoso-pacote"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Guilherme Siquinelli &amp;lt;email@guiseek.dev&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;a href="https://docs.npmjs.com/creating-a-package-json-file#creating-a-new-packagejson-file"&gt;&lt;/a&gt;Criando um novo arquivo &lt;code&gt;package.json&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Você pode criar um arquivo &lt;code&gt;package.json&lt;/code&gt; executando um questionário CLI ou criando um arquivo &lt;code&gt;package.json&lt;/code&gt; padrão.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://docs.npmjs.com/creating-a-package-json-file#running-a-cli-questionnaire"&gt;&lt;/a&gt;Executando um questionário CLI
&lt;/h3&gt;

&lt;p&gt;Para criar um arquivo &lt;code&gt;package.json&lt;/code&gt; com os valores que você fornecer, use o comando &lt;code&gt;npm init&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;No terminal, navegue até o diretório raiz do seu pacote.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /caminho/para/pacote
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execute o seguinte comando:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Responda às perguntas do questionário da linha de comando.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  &lt;a href="https://docs.npmjs.com/creating-a-package-json-file#customizing-the-packagejson-questionnaire"&gt;&lt;/a&gt;Personalizando o questionário &lt;code&gt;package.json&lt;/code&gt; 
&lt;/h4&gt;

&lt;p&gt;Se você espera criar muitos arquivos &lt;code&gt;package.json&lt;/code&gt; , pode personalizar as perguntas feitas e os campos criados durante o processo &lt;code&gt;init&lt;/code&gt; para que todos os arquivos &lt;code&gt;package.json&lt;/code&gt; contenham um conjunto padrão de informações.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Em seu diretório pessoal (home), crie um arquivo chamado &lt;code&gt;.npm-init.js&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Para adicionar perguntas personalizadas, usando um editor de texto, adicione perguntas com a função &lt;code&gt;prompt&lt;/code&gt;:&lt;br&gt;
&lt;/p&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="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;qual é o seu sabor de sorvete preferido, amigo?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Gosto de todos&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;/li&gt;
&lt;li&gt;
&lt;p&gt;Para adicionar campos personalizados, usando um editor de texto, adicione os campos desejados ao arquivo &lt;code&gt;.npm-init.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;customField&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Example custom field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;otherCustomField&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 example field is really cool&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;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Para saber mais sobre como criar personalizações &lt;code&gt;npm init&lt;/code&gt; avançadas, consulte o &lt;a href="https://github.com/npm/init-package-json"&gt;init-package-json GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://docs.npmjs.com/creating-a-package-json-file#creating-a-default-packagejson-file"&gt;&lt;/a&gt;Criando um arquivo &lt;code&gt;package.json&lt;/code&gt; padrão
&lt;/h3&gt;

&lt;p&gt;Para criar um &lt;code&gt;package.json&lt;/code&gt; padrão usando informações extraídas do diretório atual, use o comando &lt;code&gt;npm init&lt;/code&gt; com a sinalização &lt;code&gt;--yes&lt;/code&gt; ou &lt;code&gt;-y&lt;/code&gt;. Para obter uma lista de valores padrão, consulte "&lt;a href="https://docs.npmjs.com/creating-a-package-json-file#default-values-extracted-from-the-current-directory"&gt;Valores padrões extraídos do diretório atual&lt;/a&gt;".&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Na linha de comando, navegue até o diretório raiz do seu pacote.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /caminho/para/pacote
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execute o seguinte comando:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Resultado:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"seu-maravilhoso-pacote"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"repository"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/seu-usuario/seu-maravilhoso-pacote.git"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ISC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"bugs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/seu-usuario/seu-maravilhoso-pacote/issues"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"homepage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/seu-usuario/seu-maravilhoso-pacote"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;a href="https://docs.npmjs.com/creating-a-package-json-file#default-values-extracted-from-the-current-directory"&gt;&lt;/a&gt;Valores padrão extraídos do diretório atual
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt;: o nome do diretório atual&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;version&lt;/code&gt;: sempre &lt;code&gt;1.0.0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;description&lt;/code&gt;: informações do README ou uma string vazia &lt;code&gt;""&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;scripts&lt;/code&gt;: por padrão, cria um script &lt;code&gt;test&lt;/code&gt; vazio&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;keywords&lt;/code&gt;: vazio&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;author&lt;/code&gt;: vazio&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;license&lt;/code&gt;: &lt;a href="https://opensource.org/licenses/ISC"&gt;&lt;code&gt;ISC&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bugs&lt;/code&gt;: informações do diretório atual, se presente&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;homepage&lt;/code&gt;: informações do diretório atual, se presente&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://docs.npmjs.com/creating-a-package-json-file#setting-config-options-for-the-init-command"&gt;&lt;/a&gt;Definir opções de configuração para o comando init
&lt;/h3&gt;

&lt;p&gt;Você pode definir opções de configuração padrão para o comando init. Por exemplo, para definir o e-mail padrão do autor, o nome do autor e a licença, na linha de comando, execute os seguintes comandos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;set &lt;/span&gt;init-author-email &lt;span class="s2"&gt;"example-user@example.com"&lt;/span&gt;
npm &lt;span class="nb"&gt;set &lt;/span&gt;init-author-name &lt;span class="s2"&gt;"example_user"&lt;/span&gt;
npm &lt;span class="nb"&gt;set &lt;/span&gt;init-license &lt;span class="s2"&gt;"MIT"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Como iniciar um projeto TypeScript</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Sat, 25 Mar 2023 04:45:35 +0000</pubDate>
      <link>https://dev.to/guiseek/como-iniciar-um-projeto-typescript-381m</link>
      <guid>https://dev.to/guiseek/como-iniciar-um-projeto-typescript-381m</guid>
      <description>&lt;p&gt;Os requisitos básicos para que possamos utilizar TypeScript em um projeto são&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Instalar NodeJS&lt;/li&gt;
&lt;li&gt;Criar um diretório (pasta) para seu projeto&lt;/li&gt;
&lt;li&gt;Configurar o NPM no projeto&lt;/li&gt;
&lt;li&gt;Adicionar &lt;em&gt;TypeScript&lt;/em&gt; como dependência do projeto&lt;/li&gt;
&lt;li&gt;Configurar &lt;code&gt;tsconfig.json&lt;/code&gt; no projeto&lt;/li&gt;
&lt;li&gt;Nosso arquivo principal&lt;/li&gt;
&lt;li&gt;Nossos scripts&lt;/li&gt;
&lt;li&gt;Concluindo&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Então vamos lá.&lt;/p&gt;

&lt;h2&gt;
  
  
  Instalar NodeJS
&lt;/h2&gt;

&lt;p&gt;Para instalar o NodeJS recomendo acessar o &lt;a href="https://nodejs.org/pt-br"&gt;site oficial&lt;/a&gt;, faça o download da última versão LTS e instale em seu computador.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criar um diretório para seu projeto
&lt;/h2&gt;

&lt;p&gt;Isso pode ser feito utilizando a interface gráfica do seu sistema operacional ou pelo terminal de comandos e caso opte pelo terminal, abra seu VSCode e em seguida abra o terminal clicando no menu superior &lt;br&gt;
"&lt;em&gt;Terminal &amp;gt; New terminal&lt;/em&gt;" e então vamos para o comando&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;em&gt;Dica&lt;/em&gt;&lt;/em&gt;&lt;br&gt;
Não é uma boa prática o uso de caracteres especiais como acentos ou espaços para evitar erros de codificação. O ideal é que sejam utilizadas apenas letras e hífen para separação entre palavras.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;nome-do-projeto
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após criado, vamos abrir o projeto recém criado no &lt;em&gt;VSCode&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;code nome-do-projeto &lt;span class="nt"&gt;-r&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O parâmetro &lt;code&gt;-r&lt;/code&gt; indica que queremos abrir usando a mesma janela, evitando termos 2 janelas do VSCode abertas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurar o NPM no projeto
&lt;/h2&gt;

&lt;p&gt;O NPM (&lt;strong&gt;N&lt;/strong&gt;ode &lt;strong&gt;P&lt;/strong&gt;ackage &lt;strong&gt;M&lt;/strong&gt;anager) é o gerenciador de pacotes e com ele podemos usar bibliotecas escritas por outras pessoas ou publicar nossas próprias bibliotecas (escritas em JavaScript ou TypeScript) para que outros projetos usem.&lt;/p&gt;

&lt;p&gt;Bibliotecas usadas são dependências, e se tornam necessárias para que nosso código funcione, além disso também devemos informar suas respectivas versões.&lt;/p&gt;

&lt;p&gt;Quando executamos o comando &lt;code&gt;npm install&lt;/code&gt; estamos fazendo download destas dependências.&lt;/p&gt;

&lt;p&gt;Também definimos &lt;code&gt;scripts&lt;/code&gt; úteis. São comandos que deixarão nosso fluxo de desenvolvimento mais prático e fazemos isso configurando um objeto &lt;code&gt;{ "chave": "valor" }&lt;/code&gt; onde a chave é um apelido que podemos escolher como desejarmos, já o valor será o comando que será executado quando invocado através do comando &lt;code&gt;npm run chave&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ao executar&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Responderemos algumas perguntas&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Nome do projeto, padrão é o nome do diretório&lt;/li&gt;
&lt;li&gt;Versão do projeto, padrão é &lt;code&gt;1.0.0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Descrição do projeto, padrão em branco&lt;/li&gt;
&lt;li&gt;Ponto de entrada principal, o padrão é &lt;code&gt;index.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Comando para execução de testes&lt;/li&gt;
&lt;li&gt;Link do repositório git, padrão em branco&lt;/li&gt;
&lt;li&gt;Palavras chaves, padrão em branco&lt;/li&gt;
&lt;li&gt;Autor, padrão em branco&lt;/li&gt;
&lt;li&gt;Licença, padrão é &lt;a href="https://opensource.org/license/isc-license-txt/"&gt;ISC&lt;/a&gt; mas recomendo a &lt;a href="https://www.gnu.org/licenses/gpl-3.0.html"&gt;GPLv3&lt;/a&gt; &lt;a href="http://licencas.softwarelivre.org/gpl-3.0.pt-br.html"&gt;Tradução&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Adicionar &lt;em&gt;TypeScript&lt;/em&gt; como dependência do projeto
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-D&lt;/span&gt; typescript
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O parâmetro &lt;code&gt;-D&lt;/code&gt; indica que será uma dependência necessária apenas durante o desenvolvimento e não depois que estiver em produção. Este é o caso do TypeScript, visto que enviamos para produção apenas o código JavaScript gerado a partir do que escrevemos em TypeScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configurar &lt;code&gt;tsconfig.json&lt;/code&gt; no projeto
&lt;/h2&gt;

&lt;p&gt;Este arquivo indica que esse diretório é a raiz do projeto TypeScript e especifica os arquivos raiz e as configurações de compilação necessárias para o projeto, mais informações &lt;a href="https://www.typescriptlang.org/pt/docs/handbook/tsconfig-json.html"&gt;neste link&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Nosso arquivo principal
&lt;/h2&gt;

&lt;p&gt;Vamos cria-lo com o seguinte comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;code src/index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida vamos salva-lo.&lt;/p&gt;

&lt;p&gt;Agora que temos nosso arquivo no diretório &lt;code&gt;src&lt;/code&gt;, vamos alterar nosso &lt;code&gt;tsconfig.json&lt;/code&gt; descomentando as linhas &lt;code&gt;48&lt;/code&gt;, &lt;code&gt;50&lt;/code&gt; e &lt;code&gt;56&lt;/code&gt; e configurando desta forma&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tsconfig.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="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"sourceMap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sourceRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./src"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso define que o compilador deve procurar arquivos no diretório &lt;code&gt;"src"&lt;/code&gt; e o resultado deverá ser salvo no diretório &lt;code&gt;"dist"&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nossos scripts
&lt;/h2&gt;

&lt;p&gt;Um padrão muito utilizado são os comandos &lt;code&gt;"dev"&lt;/code&gt; e &lt;code&gt;"build"&lt;/code&gt;, faremos isso alterando o objeto &lt;code&gt;"scripts": {}&lt;/code&gt; no arquivo &lt;code&gt;package.json&lt;/code&gt;, com os comandos &lt;code&gt;tsc&lt;/code&gt; e &lt;code&gt;tsc -watch&lt;/code&gt;, respectivamente.&lt;/p&gt;

&lt;p&gt;&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="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc -watch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A partir de agora podemos desenvolver utilizando o comando &lt;code&gt;npm run dev&lt;/code&gt; e toda vez que alterarmos algum arquivo dentro do diretório &lt;code&gt;"src"&lt;/code&gt;, o compilador do TypeScript irá entrar em ação, colocando o resultado no diretório &lt;code&gt;"dist"&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concluindo
&lt;/h2&gt;

&lt;p&gt;Para saber se está tudo funcionando, adicione um log&lt;/p&gt;

&lt;p&gt;&lt;code&gt;src/index.ts&lt;/code&gt;&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;foi&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;E execute&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Provavelmente foi criado um diretório &lt;code&gt;"dist"&lt;/code&gt; com um arquivo &lt;code&gt;index.js&lt;/code&gt; e agora executamos&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node dist/index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se você viu escrito &lt;code&gt;"foi"&lt;/code&gt; no seu terminal, tivemos êxito e temos nosso projeto configurado!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>DOM Parser, parse de string para elementos DOM</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Sat, 17 Dec 2022 01:31:52 +0000</pubDate>
      <link>https://dev.to/guiseek/dom-parser-parse-de-string-para-elementos-dom-50de</link>
      <guid>https://dev.to/guiseek/dom-parser-parse-de-string-para-elementos-dom-50de</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Faça conversão de código XML ou HTML a partir de texto (string) para um documento DOM&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Como funciona
&lt;/h2&gt;

&lt;p&gt;A execução pode ser feita para XML ou HTML, de acordo com o tipo e retornará como resultado um documento (&lt;code&gt;Document&lt;/code&gt;). O tipo é informado como parâmetro e são aceitas as opções  &lt;code&gt;"text/html"&lt;/code&gt; , que por sua vez, invocará o parser HTML ou então &lt;code&gt;"text/xml"&lt;/code&gt;,  &lt;code&gt;"application/xml"&lt;/code&gt;,  &lt;code&gt;"application/xhtml+xml"&lt;/code&gt; e &lt;code&gt;"image/svg+xml"&lt;/code&gt;, qualquer uma das anteriores invocará o parser XML.&lt;/p&gt;

&lt;p&gt;Para o parser XML, caso a string não possa ser processada, o documento retornado deverá conter elementos descrevendo do erro retornado.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💬 &lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
Scripts não são executados durante o processamento e o resultado sempre será no formado &lt;strong&gt;UTF-8&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Caso seja informado um tipo diferente dos mencionados acima, uma exceção &lt;code&gt;TypeError&lt;/code&gt; será retornada.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interface
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;DOMParserSupportedType&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;application/xhtml+xml&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;application/xml&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;image/svg+xml&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;text/html&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;text/xml&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;DOMParser&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;parseFromString&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="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&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;DOMParserSupportedType&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Document&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;
  
  
  Exemplos
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Texto para elementos HTML
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;parseToHTML&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="kr"&gt;string&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;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DOMParser&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;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseFromString&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/html&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;h3&gt;
  
  
  Texto para elementos SVG
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;parseToSVG&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="kr"&gt;string&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;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;DOMParser&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;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parseFromString&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image/svg+xml&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;
  
  
  Casos de uso
&lt;/h2&gt;

&lt;p&gt;Vamos supor que eu esteja usando &lt;a href="https://vitejs.dev"&gt;Vite&lt;/a&gt; em um projeto e quero criar componentes da web nativos e, os templates ficarão em arquivos separados, algo como isso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;src/elements
├── form
│   ├── control.html
│   ├── control.ts
│   ├── error.html
│   ├── error.ts
│   ├── label.html
│   └── label.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fazendo &lt;code&gt;import&lt;/code&gt; de arquivos HTML, ele é recebido como &lt;code&gt;string&lt;/code&gt;&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;textTemplate&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;./error.html?raw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;textTemplate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// string&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meu arquivo HTML usa o elemento &lt;code&gt;template&lt;/code&gt;, então, antes de inserir ao &lt;code&gt;shadowRoot&lt;/code&gt;, eu quero encontrar o template usando &lt;code&gt;querySelector&lt;/code&gt; e depois clonar o elemento. Para que a busca funcione, precisamos que sejam elementos &lt;strong&gt;DOM&lt;/strong&gt;, correto?&lt;/p&gt;

&lt;p&gt;Desta forma eu poderia fazer:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shadow&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;attachShadow&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;mode&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;docTemplate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parseToHTML&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;textTemplate&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;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;docTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;template&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;shadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&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;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cloneNode&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Espero ter ajudado, valeu!&lt;br&gt;
[]s&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Arquitetura Front-end</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Mon, 19 Sep 2022 09:46:00 +0000</pubDate>
      <link>https://dev.to/guiseek/arquitetura-front-end-4ia6</link>
      <guid>https://dev.to/guiseek/arquitetura-front-end-4ia6</guid>
      <description>&lt;p&gt;Atualmente, com necessidades mais complexas e equipes numerosas, problemas e erros difíceis de resolver aparecem. É uma tendência natural que projetos se tornem obsoletos com o passar do tempo e, a dificuldade de mantê-los atualizados aumenta quando temos um número alto de dependências, fazendo com que a entropia do projeto cresça, afinal de contas é muito mais fácil adicionar uma biblioteca a um projeto, do que remover uma que está sendo usada em produção e em diversos lugares da aplicação.&lt;/p&gt;

&lt;p&gt;É aqui que a arquitetura de software entra em cena, pois ela vê o software como ponto principal para que o produto consiga gerar o valor esperado, planejando um design de alto nível que será o alicerce, a estrutura sobre a qual o software será desenvolvido.&lt;/p&gt;

&lt;p&gt;Fazendo uma analogia entre o desenvolvimento de software e a construção de um prédio, o arquiteto faz o desenho considerando suas necessidades estruturais e o uso que é previsto para ele, tanto em casos como intensidade. Então entrega aos engenheiros e técnicos que irão trabalhar na construção.&lt;/p&gt;

&lt;p&gt;Isso é muito importante na engenharia de software, porque diferente de um prédio, o software segue sendo construído e modificado sempre, e não concluído em 1 ou alguns poucos anos. É muito comum que novos planos apareçam com mudanças no escopo, o mercado digital é muito mais rápido, não só pelas variações de oferta e demandas, mas também por evoluções de tecnologias usadas.&lt;/p&gt;

&lt;p&gt;A arquitetura de software facilita o desenvolvimento de produtos mais robustos e sofisticados, criando diretrizes claras que permitem aos engenheiros saber a todo momento que tipo de código precisam construir para obter os resultados esperados.&lt;/p&gt;

&lt;p&gt;Tendo uma visão ampla sobre a vida útil de um software, os arquitetos podem incluir já nos estágios iniciais estruturas chaves que se feitas quando o produto estiver em produção, demandam alto custo de implementação, darei um exemplo. É comum que startups de tecnologia se concentrem mais na funcionalidade e na entrega de resultados imediatos do que na arquitetura e no ciclo de vida de seus produtos.&lt;br&gt;
Isso faz com que elas comecem a usar técnicas que não escalam bem e frameworks fáceis de usar ou que dependem muito de terceiros. Quando aparecem milhares ou milhões de usuários e os investidores exigem escalabilidade com estabilidade, as coisas se complicam.&lt;/p&gt;

&lt;p&gt;Alterar a estrutura de uma aplicação que ninguém usa e uma mudança global que afeta milhões de usuários ao mesmo tempo são coisas completamente diferentes, assim como mudar de servidor algo em desenvolvimento ou em produção com uso intensivo, pois em casos de falhas, mudanças assim poderiam custar milhões em perdas. Certamente não é a mesma coisa alterar a linguagem de programação de um aplicativo quando apenas algumas pessoas trabalham nele, que realizar isso com centenas de colaboradores envolvidos.&lt;/p&gt;

&lt;p&gt;É pra isso que existe a arquitetura de software, ela ajuda na tomada de decisões críticas a tempo de escolher quais riscos desejam ser assumidos e afetando para sempre o rumo do projeto.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📅 Publicação: 17/09/2022 por &lt;a href="https://twitter.com/guiseek"&gt;Guilherme Siquinelli&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>ENV vars with Angular &amp; Nx</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Thu, 21 Jul 2022 06:13:11 +0000</pubDate>
      <link>https://dev.to/guiseek/env-vars-with-angular-nx-26i9</link>
      <guid>https://dev.to/guiseek/env-vars-with-angular-nx-26i9</guid>
      <description>&lt;p&gt;Primeiro, instale &lt;code&gt;@types/node&lt;/code&gt; para que possamos usar &lt;code&gt;process.env&lt;/code&gt; em nosso código.&lt;br&gt;
&lt;/p&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; @types/node

&lt;span class="c"&gt;# Or with yarn&lt;/span&gt;
yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; @types/node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em seguida, atualize os targets &lt;code&gt;build&lt;/code&gt; e &lt;code&gt;serve&lt;/code&gt; (no arquivo &lt;code&gt;project.json&lt;/code&gt; ou &lt;code&gt;angular.json&lt;/code&gt;), para o seguinte.&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;NOTA:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;altere&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;o&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;executor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;para&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;um&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;que&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;suporte&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;configurações&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;personalizadas&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;webpack.&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"executor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@nrwl/angular:webpack-browser"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;recorte&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;NOTE:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;This&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;needs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;be&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;created.&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"customWebpackConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"apps/myapp/webpack.config.js"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;recorte&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"serve"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;NOTA:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;altere&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;o&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;executor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;para&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;um&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;que&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;suporte&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;configurações&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;personalizadas&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;do&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;webpack.&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"executor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@nrwl/angular:webpack-server"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;recorte&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Então, podemos usar &lt;code&gt;DefinePlugin&lt;/code&gt; em nossa configuração webpack personalizada.&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;// apps/myapp/webpack.config.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;webpack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&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;webpack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;getClientEnvironment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Grab NODE_ENV and MY_APP_* environment variables and prepare them to be&lt;/span&gt;
  &lt;span class="c1"&gt;// injected into the application via DefinePlugin in webpack configuration.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MY_APP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/^MY_APP_/i&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;raw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;key&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;MY_APP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&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;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&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;env&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;NODE_ENV&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;configuration&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;// Stringify all values so we can feed into webpack DefinePlugin&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;process.env&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&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;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&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;env&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="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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&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="nx"&gt;context&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;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;webpack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DefinePlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getClientEnvironment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configuration&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="nx"&gt;config&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;Agora, quando definimos variáveis ​​em nosso arquivo &lt;code&gt;.env&lt;/code&gt;, como...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# apps/myapp/.env
MY_APP_API_URL=http://localhost:3333
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finalmente, podemos usar variáveis ​​de ambiente em nosso código. Por exemplo:&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;// apps/myapp/src/main.ts&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;enableProdMode&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;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;platformBrowserDynamic&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;@angular/platform-browser-dynamic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;AppModule&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;./app/app.module&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NODE_ENV&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;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;enableProdMode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// This is defined in our .env file.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&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;&amp;gt;&amp;gt;&amp;gt; MY_APP_API_URL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&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_APP_API_URL&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nx"&gt;platformBrowserDynamic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bootstrapModule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AppModule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você também deve atualizar os arquivos &lt;code&gt;tsconfig.app.json&lt;/code&gt; e &lt;code&gt;tsconfig.spec.json&lt;/code&gt; para incluir tipos do node.&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"extends"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./tsconfig.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;recorte&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;recorte&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora basta servir a aplicação e sua variável estará no console do browser : )&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Nota:&lt;br&gt;
Isso foi testado em ambiente com versões:&lt;/p&gt;


&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "@nrwl/angular": "^14.4.3",
  "@nrwl/workspace": "14.4.3"
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;




&lt;p&gt;valeu&lt;br&gt;
[]s&lt;/p&gt;

</description>
      <category>angular</category>
      <category>nx</category>
      <category>env</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Você é autodidata?</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Sat, 16 Jul 2022 16:17:49 +0000</pubDate>
      <link>https://dev.to/guiseek/voce-e-autodidata-jl4</link>
      <guid>https://dev.to/guiseek/voce-e-autodidata-jl4</guid>
      <description>&lt;p&gt;Antes de qualquer coisa, vamos quebrar um mito aqui.&lt;/p&gt;

&lt;p&gt;Pessoas autodidatas não são pessoas que lêem uma única vez sobre algum assunto, absorvem, entendem e aprendem tudo o que leu pra sempre, como alguém que tivesse memória fotográfica, não. Pessoas autodidatas não são gênios.&lt;/p&gt;

&lt;p&gt;Pessoas autodidatas são pessoas teimosas, insistentes, perseverantes e por último e mais importante, são pessoas que não acham que errar é um problema.&lt;/p&gt;

&lt;p&gt;Elas têm o erro como o primeiro passo para solução, descobrir que está fazendo algo errado, é descobrir que está fazendo algo que ela julgava estar da forma correta, da forma errada. Aceitar o erro não é uma tarefa difícil para ela, mas sim uma oportunidade de fazer da forma certa.&lt;/p&gt;

&lt;p&gt;O segundo passo é identificar onde está o erro ou o quê está sendo feito errado e mais uma vez, isso nem de longe é motivo pra se aborrecer, pelo contrário, quando uma pessoa autodidata encontra onde está o erro, isso é motivo de alegria, como alguém que encontra a pista perfeita num jogo de palavras cruzadas.&lt;/p&gt;

&lt;p&gt;O terceiro passo é entender o problema, o motivo pelo qual a forma que estava sendo feita não funcionava, e então tentar de alguma outra forma que faça mais sentido para atingir o objetivo do que se está fazendo.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é, então, ser autodidata?
&lt;/h2&gt;

&lt;p&gt;Ser autodidata é fazer ciência com as suas ações, experimentando com a ajuda da razão, a lógica misturada a tentativa e erro até que chegue o momento em que os erros não apareçam mais naquela situação.&lt;/p&gt;

&lt;p&gt;Quando alguém se sujeita a não ser autodidata, (sim, usei o termo sujeita, pois automaticamente ela está sujeita a algo que ela não controla) ela está sujeita a limitação do que lhe é entregue como verdade. Mas e quando algo que ela aprendeu apresenta inconsistências, apresentando resultados inesperados e nos piores casos, resultados indesejados? Qual a solução? buscar quem ensinou, reclamar e pedir pra ensinar da forma correta para que não apresente mais erros? não é bem assim que as coisas funcionam no mundo real...&lt;/p&gt;

&lt;p&gt;E antes que eu me esqueça, é importante colocar alguns pingos nos i 's... Não estou dizendo que pessoas autodidatas devem aprender apenas com seus próprios erros, abandonando todo conhecimento externo... não, jamais, isso seria loucura!&lt;br&gt;
Muito pelo contrário, pessoas autodidata também procuram por pessoas com maior domínio em determinados assuntos com a finalidade de absorver ensinamentos que lhe serão entregues, este método na maior parte das vezes tende a ser menos inconsistente inicialmente, devido ao conhecimento que é transmitido de indivíduo para indivíduo ter sido sujeito a testes por pessoas e situações diferentes e em diferentes contextos.&lt;/p&gt;

&lt;p&gt;O Ponto aqui é única e exclusivamente sobre não se limitar, sobre ser crítico, curioso, saber experimentar, aprimorar seu raciocínio lógico e outro detalhe de extrema importância, sobre praticar! A prática é a maior de todas as professoras, é quando ela entra em cena que os mitos caem por terra, vale citar um comentário que uma amiga, Ana Elisa, me disse há um tempo atrás, muito pertinente.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Na teoria, teoria e prática são a mesma coisa. Na prática, não.&lt;/p&gt;
  &lt;cite&gt;– Ana Elisa&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;p&gt;É na prática que as coisas não funcionam e você precisa resolver o problema, é na prática que você tenta até acertar. É na prática que o problema é resolvido.&lt;/p&gt;
&lt;h2&gt;
  
  
  Autodidata e cursos
&lt;/h2&gt;

&lt;p&gt;Pessoas autodidatas não fazem cursos? Sim, fazem, não há motivos para não fazê-los, desde que seja acessível a seu contexto.&lt;/p&gt;

&lt;p&gt;Lev Vygotsky, psicólogo bielo-russo influenciou o que depois de sua morte se tornou a corrente pedagógica chamada de socioconstrutivismo ou sociointeracionismo. Para ele, a formação se dá numa relação dialética entre o sujeito e a sociedade a seu redor - ou seja, a pessoa modifica o ambiente e o ambiente modifica a pessoa.&lt;/p&gt;
&lt;h3&gt;
  
  
  Exemplo
&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;Uma criança nasce com as condições biológicas de falar, mas só desenvolverá a fala se aprender com os mais velhos da comunidade&lt;/p&gt;
  &lt;cite&gt;– Teresa Rego&lt;/cite&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ainda segundo o psicólogo, toda relação de uma pessoa com o mundo é feita por meio de instrumentos técnicos - como, por exemplo, as da linguagem - que trazem consigo conceitos consolidados da cultura à qual a pessoa está inserida.&lt;/p&gt;

&lt;p&gt;Todo aprendizado é necessariamente mediado, seja por uma pessoa dando aula, um livro ou artigo que outra pessoa escreveu e até ferramentas utilizadas no processo de aprendizagem. Isso torna o papel do ensino e do professor mais ativo e determinante. Piaget disse que cabe a instituição facilitar o processo que só pode ser conduzido pela própria pessoa, ao contrário, Vygotsky diz que é importante o primeiro contato de uma criança com novas atividades, habilidades ou informações terem a participação de alguém, e então, a criança "se apropria" dele, tornando-o voluntário e independente.&lt;/p&gt;

&lt;p&gt;Cursos são excelentes locais que nos dão um empurrão a mais. Outro ótimo ponto chave que não podemos nos esquecer é o network construído durante a interação com outras pessoas, que é muito valioso, arrisco dizer que seja muitas vezes fator decisivo pro caminho que vem pela frente.&lt;/p&gt;

&lt;p&gt;Escolha a dedo onde irá se inscrever, avalie se o conteúdo programático se encaixa com seu objetivo e se os profissionais envolvidos são competentes.&lt;/p&gt;
&lt;h2&gt;
  
  
  Existe uma receita de bolo?
&lt;/h2&gt;

&lt;p&gt;Alguns meses atrás, em uma conversa de mentoria, listei de forma rápida alguns itens que no momento entendia serem válidos, sempre que houvesse alguma dúvida, para serem lidos na tentativa de identificar se estamos no rumo ideal, que são estes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Aprenda aprender e onde aprender.&lt;/li&gt;
&lt;li&gt;Aprenda consultar e onde consultar.&lt;/li&gt;
&lt;li&gt;Aprenda registrar e onde registrar.&lt;/li&gt;
&lt;li&gt;Aprenda documentar, entenda que seu colega amanhã pode ser você ontem.&lt;/li&gt;
&lt;li&gt;Pense a longo prazo sempre e faça da melhor forma, ah... a melhor forma é relativa contexto e recursos disponíveis naquele dado momento.&lt;/li&gt;
&lt;li&gt;Aprenda automatizar tarefas repetitivas.&lt;/li&gt;
&lt;li&gt;Não tente, consiga. Pense no passado para encontrar o futuro.&lt;/li&gt;
&lt;li&gt;Argumente como se estivesse certa(o) mas ouça como se estivesse errada(o).&lt;/li&gt;
&lt;li&gt;Quando souber, fale mais do que ouve e quando não souber, ouça mais do que fale, mas saiba quando sabe e saiba quando não sabe.&lt;/li&gt;
&lt;li&gt;Questione, você pode estar certa(o).&lt;/li&gt;
&lt;li&gt;Peça conselhos a quem discorda de você..&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Técnicas de aprendizado
&lt;/h2&gt;

&lt;p&gt;Uma das características do autodidata é ter boas referências de estudo e consulta, isso é extremamente relevante quando estamos falando de encontrar a resposta que buscamos de forma eficiente e assertiva.&lt;/p&gt;

&lt;p&gt;Ficar pesquisando no Google todas as vezes que lhe surge uma dúvida não é a forma mais eficiente, você pode criar um catálogo, usando o favoritos do seu navegador por exemplo. Contendo boas referências sobre determinados assuntos, e quando algum destes aparecer como dúvida, você já sabe onde vai encontrar a resposta!&lt;/p&gt;

&lt;p&gt;Posso dar um exemplo que entendo ser um tanto óbvio, contudo tenho visto que não é tão óbvio assim. Como sou engenheiro web, frequentemente aparece alguma dúvida sobre o uso de algum atributo ou outro, o HTML é enorme, e quando a dúvida é muito específica acaba sendo difícil encontrar uma resposta com uma solução assertiva de forma rápida vinda de uma fonte confiável, e também, porque eu perderia meu precioso tempo de vida, procurando outra fonte confiável se eu já sei o endereço da &lt;a href="https://html.spec.whatwg.org/"&gt;documentação oficial&lt;/a&gt;!? Quando conhecemos alguma fonte certeira, vá direto nela!&lt;/p&gt;

&lt;p&gt;Mais importante que "decorar" tudo que você lê, é saber onde você vai encontrar as melhores respostas de forma ágil. Melhor ainda é se você optar por escrever um artigo, um post, enfim, publicar algo sobre o assunto, ou melhor ainda: Submeta uma palestra para comunidade, passando tudo que aprendeu para outras pessoas! Apesar disso aparentar algo inalcançável para alguns ou caridosa para outros, no final das contas, acaba sendo para benefício próprio. É uma das minhas técnicas de estudo, não só minha, mas de muita gente no ecossistema de desenvolvimento de software.&lt;/p&gt;

&lt;p&gt;Existem diversas técnicas de estudo, uma bem conhecida é a criada pelo físico renomado e que infelizmente já não está mais entre nós, Richard Feynman.&lt;/p&gt;
&lt;h3&gt;
  
  
  Técnica Feynman
&lt;/h3&gt;

&lt;p&gt;Existem técnicas para se aprender com eficiência, uma delas que se encaixa perfeitamente no modelo de submissão de palestras para comunidade é a técnica de &lt;strong&gt;Richard Feynman&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Essa técnica é dividida em quatro etapas:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Escolha um conceito;&lt;/li&gt;
&lt;li&gt;Ensine ou finja ensinar a uma criança;&lt;/li&gt;
&lt;li&gt;Identifique falhas na compreensão;&lt;/li&gt;
&lt;li&gt;Revise e simplifique.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A teoria dele é que existem dois tipos de sabedoria:&lt;br&gt;
Uma delas é focada em saber apenas o nome, e a outra é focada em entender.&lt;br&gt;
Assim, em vez de apenas memorizar datas, nomes e conceitos, ele orienta a ter de fato uma compreensão profunda sobre o tema.&lt;/p&gt;
&lt;h3&gt;
  
  
  Passo a passo da técnica:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Escolha um conceito ou assunto&lt;br&gt;
A proposta é aprender e vale para todos os assuntos. Dessa forma, escolha um tema que desejar, pode ser uma lei, uma fórmula matemática, uma escola literária, um tipo de meditação ou qualquer outro conceito. Quanto mais específico, melhor. &lt;br&gt;&lt;br&gt;
Liste o nome do conceito no cabeçalho de uma folha e abaixo dele escreva tudo o que você sabe sobre ele. Ao longo da técnica, você provavelmente irá aprender mais coisas sobre o conceito, anote também na folha.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensine para uma criança&lt;br&gt;
A segunda etapa consiste em ensinar ou simular a explicação do conceito para uma criança. Você pode fazer isso de forma escrita ou oral, mas é importante transmitir essas informações de forma clara e simples. &lt;br&gt;&lt;br&gt;
&lt;strong&gt;Evite:&lt;/strong&gt; terminologias complexas e jargões;&lt;br&gt;
&lt;strong&gt;Seja:&lt;/strong&gt; breve e criativo. &lt;br&gt;&lt;br&gt;
Certamente você encontrou lacunas no seu conhecimento e teve coisas que não soube explicar. Aqui é o ponto onde o aprendizado acontece, e você deve se perguntar: “o que deixei passar?” e “o que eu ainda não sei?”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Identifique falhas na compreensão&lt;br&gt;
Feito isso, anote as falhas na compreensão e volte para a pesquisa. Utilize suas anotações iniciais, recorra ao google, consulte livros, apostilas, slides, etc... Estude!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Revise e simplifique&lt;br&gt;
A última fase consiste em revisar todo o conteúdo e simplificar sua linguagem e organização. Após isso, leia em voz alta o que foi escrito e veja se há linearidade e coerência na sua explicação.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Originalmente, Feynman aplicou a sua técnica para explicar os fundamentos da física de partículas, algo que é extremamente difícil. Esse seu trabalho ajudou outros cientistas a rastrear os movimentos das partículas a partir de ilustrações e equações visuais.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Professor Pier
&lt;/h3&gt;

&lt;p&gt;Outra lenda que tem excelentes dicas sobre como aprender, é o Pierluigi Piazzi ou Professor Pier.&lt;/p&gt;

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

&lt;p&gt;Este foi o primeiro vídeo que assisti dele, me lembro que fiquei abismado com as palavras dele fazendo meu tico e teco darem um empurrão um ao outro, acreditando ainda mais que o futuro é autodidata, ainda mais com a ajuda desse mar de informações espalhadas na rede que chamamos de Internet. Temos muito a agradecer ao Sir. Tim Berners-Lee, por essa imensurável contribuição ao nosso mundo.&lt;/p&gt;

&lt;p&gt;Mas e você, é autodidata?&lt;/p&gt;

&lt;p&gt;Comente aí embaixo qual sua melhor técnica de estudo para que ajude outras pessoas a tentarem de outra forma, afinal, cada um deve encontrar qual seu melhor método de aprender.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Por que os desenvolvedores precisam de um plano de carreira</title>
      <dc:creator>Guilherme Siquinelli</dc:creator>
      <pubDate>Sat, 08 Jan 2022 13:33:22 +0000</pubDate>
      <link>https://dev.to/guiseek/por-que-os-desenvolvedores-precisam-de-um-plano-de-carreira-4g9p</link>
      <guid>https://dev.to/guiseek/por-que-os-desenvolvedores-precisam-de-um-plano-de-carreira-4g9p</guid>
      <description>&lt;p&gt;Se você não tem destino, não importa em que direção você está viajando.&lt;br&gt;
Geralmente esta não é uma tarefa difícil, pois nos mantém numa zona de conforto "boa".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Acho que todos deveriam experimentar uma derrota pelo menos uma vez na carreira. Você aprende muito com isso."&lt;br&gt;
-- Lou Holtz&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Esta é uma frase já traduzida dele, que é um jogador de futebol americano, mas sem mais devaneios, é hora de adentrar ao assunto que trataremos.&lt;/p&gt;




&lt;p&gt;Desenvolvedores muitas vezes reviram os olhos quando lhes pergunto se eles tem um plano de carreira ou sabem qual é o papel dos seus sonhos. Planos de carreira parecem muito comerciais e enfadonhos para desenvolvedores interessados em codificar.&lt;/p&gt;

&lt;p&gt;Provavelmente você obterá uma resposta diferente se perguntar a alguém se essa pessoa gostaria de receber mais dinheiro, de ter uma carreira de sucesso ou trabalhar em uma função que goste.&lt;/p&gt;

&lt;p&gt;Perguntas diferentes, mas a solução é a mesma. Você precisa saber para onde está indo e, em seguida, fazer um plano de como chegar lá.&lt;/p&gt;

&lt;p&gt;Às vezes, para obter uma resposta diferente, você precisa perguntar de uma maneira diferente e inverte-la negativamente é uma forma.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Você desistiu de sua carreira ou progressão?
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;ou&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  É esta função em que você ficará feliz trabalhando pelo resto de sua carreira?
&lt;/h3&gt;
&lt;/blockquote&gt;

&lt;p&gt;Usar uma pergunta negativa ajuda o desenvolvedor a ver se ele não tem um plano que está escolhendo para permanecer em sua função atual.&lt;br&gt;
O desenvolvedor é a única pessoa que pode fazer o trabalho necessário e imprescindível para progredir na carreira. Claramente existem outros envolvidos no processo, porém, de nada importa se o maior interessado não agir conforme a premissa.&lt;/p&gt;

&lt;h2&gt;
  
  
  Planos
&lt;/h2&gt;

&lt;p&gt;Se você não sabe para onde está indo ou a função que deseja, acabará desempenhando a função que outra pessoa deseja que você desempenhe. Essa função irá beneficiar a empresa e, se você tiver sorte, irá beneficiar você também.&lt;/p&gt;

&lt;p&gt;Na maioria das vezes, o desenvolvedor obterá um benefício mínimo porque será colocado em uma função usando habilidades que possui atualmente. É improvável que essas sejam as habilidades, conhecimentos ou experiência para que você obtenha uma nova função ou seja promovido.&lt;/p&gt;

&lt;p&gt;Os desenvolvedores deixam a responsabilidade por suas carreiras e recompensas para outras pessoas. Eles fazem isso por não terem um plano ou meta para sua carreira e se um desenvolvedor não tiver um plano; significa que o desenvolvedor está seguindo um plano criado pela empresa para qual trabalha.&lt;/p&gt;

&lt;p&gt;No livro Alice no País das Maravilhas de Lewis Carroll, um Gato falante pergunta a Alice para onde ela está indo.&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;em&gt;Gato&lt;/em&gt;: Aonde você vai?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Alice&lt;/em&gt;: Qual caminho devo seguir?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Gato&lt;/em&gt;: Isso depende de para onde você está indo.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Alice&lt;/em&gt;: Não sei.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Gato&lt;/em&gt;: Então não importa para onde você vai.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Um desenvolvedor sem plano está dizendo que não importa para onde vá sua carreira ou a função que deseja desempenhar um dia, pois não está se importando o suficiente para influenciar de alguma forma que este rumo não seja perdido.&lt;/p&gt;

&lt;h2&gt;
  
  
  O planejamento é essencial
&lt;/h2&gt;

&lt;p&gt;Criar um plano é sair da roda do hamster. e avaliar sua carreira. Saber onde você está agora e pensar para onde você quer chegar.&lt;/p&gt;

&lt;p&gt;Depois de saber aonde quer chegar, você pode fazer um plano para obter as habilidades, conhecimentos, experiências e contatos para chegar lá.&lt;/p&gt;

&lt;p&gt;Nenhum plano de carreira sobrevive ao contato com o trabalho, mas isso significa que você já pensou sobre isso. Conforme o ano avança, suas metas, planos e atividades podem mudar conforme suas prioridades e oportunidades mudam.&lt;/p&gt;

&lt;p&gt;Depois de identificar o rumo que deseja para sua carreira, é provável que você perceba oportunidades que o ajudarão com seus objetivos.&lt;br&gt;
Mencionar seus objetivos de carreira para seu gerente e outros colegas convida mais pessoas a ajudar em sua carreira, porque elas também podem procurar oportunidades (se você tiver construído um bom relacionamento)&lt;/p&gt;

&lt;h2&gt;
  
  
  Planos dão feedback
&lt;/h2&gt;

&lt;p&gt;Você pode lidar com um plano que falhou porque o motivo é que o plano não foi bom ou a execução não foi boa.&lt;/p&gt;

&lt;p&gt;É um problema de lógica ou de execução. Você pode refletir sobre isso e, em seguida fazer a mudança necessária. &lt;strong&gt;Se você não tem nenhum plano e sua carreira estagna - como saber qual é o problema?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Muitos desenvolvedores não buscam nada e o alcançam, mas no final do ano ficam desapontados por não terem progredido.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hábitos
&lt;/h2&gt;

&lt;p&gt;Qualquer objetivo significativo ou progressão na carreira envolve a obtenção de novas habilidades, novos conhecimentos, novas experiências e, possivelmente, novas pessoas (conexões, rede e relacionamentos).&lt;/p&gt;

&lt;p&gt;Você constrói habilidades, conhecimentos e experiências fora de seu trabalho diário, onde usa habilidades que já possui.&lt;/p&gt;

&lt;p&gt;Você precisa colocar as ações em seu calendário e fazer com que essas melhorias se tornem um hábito regular.&lt;/p&gt;

&lt;p&gt;Qualquer plano que você seguir precisa ser dividido em tarefas e registradas no diário para então serem transformadas em hábitos.&lt;/p&gt;

&lt;p&gt;Espero que esta reflexão também ajude outras pessoas desenvolvedoras.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://javascript.plainenglish.io/why-developers-need-a-career-plan-1762011496ac"&gt;Post&lt;/a&gt; original em inglês&lt;/p&gt;

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