<?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: Luciano Graziani</title>
    <description>The latest articles on DEV Community by Luciano Graziani (@lgraziani2712).</description>
    <link>https://dev.to/lgraziani2712</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%2F28165%2Fc82506a8-53a7-49d6-b457-e7e94594db9f.jpg</url>
      <title>DEV Community: Luciano Graziani</title>
      <link>https://dev.to/lgraziani2712</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lgraziani2712"/>
    <language>en</language>
    <item>
      <title>CSS MediaQuery for making a board game responsive</title>
      <dc:creator>Luciano Graziani</dc:creator>
      <pubDate>Wed, 29 Jul 2020 23:41:32 +0000</pubDate>
      <link>https://dev.to/lgraziani2712/css-mediaquery-for-making-a-board-game-responsive-21eb</link>
      <guid>https://dev.to/lgraziani2712/css-mediaquery-for-making-a-board-game-responsive-21eb</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cover from &lt;a href="https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2015/04/colortheory.jpg"&gt;https://cdn0.tnwcdn.com/wp-content/blogs.dir/1/files/2015/04/colortheory.jpg&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Today I was working in a little board game I started with a friend and tried to solve something I was avoiding for some time now: how to make the board responsive.&lt;/p&gt;

&lt;p&gt;I used CSS Grid for making a 9x9 board with as much space as possible, given the height/width of the window. I also tried using the &lt;code&gt;vw&lt;/code&gt; unit, but when the window's height was less than the width, the page size would overflow vertically. The same did happened with &lt;code&gt;vh&lt;/code&gt; but with a horizontal overflow.&lt;/p&gt;

&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;p&gt;So, how is it possible to adapt a fixed css grid with 9x9 (or whatever) squares? With Media Queries! (or at least is what I found.) Using the &lt;code&gt;orientation&lt;/code&gt; condition we can change the unit we're using. This specific snippet is what I used for the board:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.board&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10vh&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10vh&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orientation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;portrait&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.board&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;/* no more overflow with this! yay! */&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10vw&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10vw&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;h1&gt;
  
  
  Demo
&lt;/h1&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/lgraziani/embed/wvMLJmG?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If you know something better than this approach, feel free to respond! Thank you 😄!&lt;/p&gt;

</description>
      <category>css</category>
      <category>beginners</category>
      <category>design</category>
      <category>game</category>
    </item>
    <item>
      <title>How to make TS more intelligent?</title>
      <dc:creator>Luciano Graziani</dc:creator>
      <pubDate>Mon, 09 Dec 2019 14:40:21 +0000</pubDate>
      <link>https://dev.to/lgraziani2712/how-to-make-ts-more-intelligent-i8f</link>
      <guid>https://dev.to/lgraziani2712/how-to-make-ts-more-intelligent-i8f</guid>
      <description>&lt;p&gt;I have a monorepo like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root/packages
  |-lib1
  |-lib2
  |-lib3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;lib3&lt;/code&gt; depends of both &lt;code&gt;lib1&lt;/code&gt; and &lt;code&gt;lib2&lt;/code&gt;. I'm using TS v3.7.2 with &lt;code&gt;composite&lt;/code&gt; (true), &lt;code&gt;baseUrl&lt;/code&gt;, &lt;code&gt;paths&lt;/code&gt; and &lt;code&gt;references&lt;/code&gt; props to be able to work with the new &lt;a href="https://www.typescriptlang.org/docs/handbook/project-references.html"&gt;ts project references&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Everything is ok except for one thing: I'm using VSCode, I'm writing something for &lt;code&gt;lib3&lt;/code&gt; and using an enum from &lt;code&gt;lib1&lt;/code&gt;, but the enum is still not imported. When I ask VSCode to show me the possible imports for the enum, it doesn't show anything, but if I write the import by hand, it recognize it.&lt;/p&gt;

&lt;p&gt;E.g:&lt;/p&gt;

&lt;h4&gt;
  
  
  file in lib3 where VSCode doesn't know where to import from
&lt;/h4&gt;



&lt;div class="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;bla&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="nx"&gt;EnumFromLib1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  file in lib3 where VSCode know
&lt;/h4&gt;



&lt;div class="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="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lib1/some/path/to/file&lt;/span&gt;&lt;span class="dl"&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;function&lt;/span&gt; &lt;span class="nx"&gt;bla&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="nx"&gt;EnumFromLib1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the second example, if I press the keyboard shorcut for importing &lt;code&gt;EnumFromLib1&lt;/code&gt; it will list the possibility from the &lt;code&gt;lib1/some/path/to/file&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;So, the question is: How can I configure TS to help him know beforehand that I have more elements in those files?&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>help</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Using Jest with coverage and BenchmarkJS helped me identify optimization opportunities for my recursive lib</title>
      <dc:creator>Luciano Graziani</dc:creator>
      <pubDate>Sat, 26 Oct 2019 17:14:55 +0000</pubDate>
      <link>https://dev.to/lgraziani2712/using-jest-with-coverage-and-benchmarkjs-helped-me-identify-optimization-opportunities-for-my-recursive-lib-39f7</link>
      <guid>https://dev.to/lgraziani2712/using-jest-with-coverage-and-benchmarkjs-helped-me-identify-optimization-opportunities-for-my-recursive-lib-39f7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cover image from &lt;a href="http://www.picswalls.com/pic/beautiful-road-wallpapers/" rel="noopener noreferrer"&gt;picwalls&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The problem I tried to solve
&lt;/h3&gt;

&lt;p&gt;By default, GraphQL adds a &lt;code&gt;__typeName&lt;/code&gt; attribute to every element for each query. This attribute helps you determine what &lt;code&gt;type&lt;/code&gt; represents each &lt;code&gt;object&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;GraphQL services provide a few meta fields, the rest of which are used to expose the Introspection system.&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://graphql.org/learn/queries/#meta-fields" rel="noopener noreferrer"&gt;https://graphql.org/learn/queries/#meta-fields&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But when you have to invoke a mutation, you cannot pass everything. GraphQL will complain if you have unknown attributes for a given &lt;code&gt;input&lt;/code&gt; or &lt;code&gt;type&lt;/code&gt;. Hence, you need to remove, &lt;em&gt;at least&lt;/em&gt;, the &lt;code&gt;__typeName&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;In addition, we can have multiple structures: a simple object, an array of simple objects, an object with nested object, an array of objects with nest... Ok, yes, &lt;em&gt;a lot&lt;/em&gt; of possibilities.&lt;/p&gt;

&lt;p&gt;So, how could you remove each of those attributes without knowing that much about the structure of the data?&lt;/p&gt;

&lt;h3&gt;
  
  
  The first solution
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Github repo: &lt;a href="https://github.com/lgraziani2712/deep-delete" rel="noopener noreferrer"&gt;https://github.com/lgraziani2712/deep-delete&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The key point to solve the problem is recursivity. Since you don't know how many objects and array you have, the function must access and process those structures and then &lt;em&gt;return&lt;/em&gt; each time the data is not an array nor an object (the &lt;em&gt;base case&lt;/em&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A recursive function definition has one or more base cases, meaning input(s) for which the function produces a result trivially (without recurring), and one or more recursive cases, meaning input(s) for which the program recurs (calls itself).&lt;/p&gt;

&lt;p&gt;Source: &lt;a href="https://en.wikipedia.org/wiki/Recursion_(computer_science)#Recursive_functions_and_algorithms" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Recursion_(computer_science)#Recursive_functions_and_algorithms&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First &lt;a href="https://github.com/lgraziani2712/deep-delete/commit/3cf57217e251a9b35d062720bd6fbe1b0cf9809d#diff-1fdf421c05c1140f6d71444ea2b27638" rel="noopener noreferrer"&gt;commit&lt;/a&gt; solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deepDelete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyToSearch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&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="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Recursive case&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;deepDelete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyToSearch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;element&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&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="c1"&gt;// Base case (anything different than array or data)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;partial&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;keyToSearch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Base case (the key to be deleted)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Recursive case&lt;/span&gt;
    &lt;span class="nx"&gt;partial&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="nf"&gt;deepDelete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;keyToSearch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&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;partial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Limitations of this solution
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;What would happen if I want to remove more than one key? I need to process my data multiple time just for that? (It's insane, yeah).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is solved in v1.1.0. You can pass an array of strings as a first param.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Is it really works as expected?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I'm not 100% sure. It doesn't have tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Are since v2.1.0.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;How many times (hence, resource consumtion) is the function called?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I don't know. I don't have metrics nor code coverage.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Are since v2.1.0.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;What &lt;em&gt;really&lt;/em&gt; are the types that must accept the &lt;code&gt;data&lt;/code&gt; parameter? Can be anything, or just one or two?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Since v2.1.0 it only accepts &lt;code&gt;Object | Array&amp;lt;Object&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Can take advantage of things like V8 TurboFan optimizing compiler?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I don't really know.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Latests benchmark results
&lt;/h3&gt;

&lt;p&gt;Before I talk about how I found optimization opportunities, I want to show you the latests benchmark results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fl8zc0ya9qdeatlmbnkev.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fl8zc0ya9qdeatlmbnkev.png" alt="Image of the latests benchmark results. Version 2.1.0 is the fastest"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see (or hear), the version &lt;code&gt;v2.1.0&lt;/code&gt; is the fastest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Coverage really helped me find optimization opportunities
&lt;/h3&gt;

&lt;p&gt;When I was writting tests, I configured Jest to generate the test coverage, to help me know if I was testing everything. What I didn't know was that the coverage it also tells you how many times a line is executed, as you can see in the following image:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Foespllbd63tlo7uwtxpd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Foespllbd63tlo7uwtxpd.jpg" alt="Test coverage result for version 1.2.0"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's analyse the result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Line 10 was executed 10/24 times. The &lt;code&gt;data&lt;/code&gt; parameter had an array 10 times.&lt;/li&gt;
&lt;li&gt;Line 13 was executed 8/24 times. The &lt;code&gt;data&lt;/code&gt; parameter had an empty value or something different than an object.&lt;/li&gt;
&lt;li&gt;Line 17 was executed 6/24 times, so there were 6 objects.&lt;/li&gt;
&lt;li&gt;Line 19 was executed 4/8 times, which means that there were deleted four keys.&lt;/li&gt;
&lt;li&gt;Line 21 was executed 4/8 times. This means that the object had other 4 keys that were needed to be processed by calling &lt;code&gt;deepDelete&lt;/code&gt; again just to returns itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Viewing this made me think that there were a lot of function calls, more than the necessary. At that point, &lt;code&gt;deepDelete&lt;/code&gt; was being called for every type of value. Every. Type. Of. Value. There are two lines in where was possible to improve this. Those lines are 10 and 21. Instead of just invoking the function, it could check if the element is an array or an object, and if not, not calling it.&lt;/p&gt;

&lt;p&gt;This improvement was made for version 2.0.1:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7c83eemyk4awiivzb5r7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F7c83eemyk4awiivzb5r7.jpg" alt="Test coverage result for version 2.0.1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this changes and a few minor fixes &amp;amp; improvements, I was able to reach v2.1.0 and get the results of the benchmark mentioned before.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Code coverages not also let you know which paths of your application you're testing but it also can help determine optimization points. Using it in conjunction with BenchmarkJS you'll be able to have more metrics about your code!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>benchmarks</category>
      <category>metrics</category>
      <category>testing</category>
    </item>
    <item>
      <title>Stop copying your process.env.NODE_ENV to local variables! 🤯</title>
      <dc:creator>Luciano Graziani</dc:creator>
      <pubDate>Fri, 12 Apr 2019 15:45:05 +0000</pubDate>
      <link>https://dev.to/lgraziani2712/stop-copying-your-process-env-vars-to-local-variables-3jen</link>
      <guid>https://dev.to/lgraziani2712/stop-copying-your-process-env-vars-to-local-variables-3jen</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cover image from&lt;br&gt;
&lt;a href="https://www.nationalgeographic.com/photography/proof/2017/06/bird-gallery/"&gt;https://www.nationalgeographic.com/photography/proof/2017/06/bird-gallery/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Instead of this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example nº 1:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;localAndLessCode&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;NODE_ENV&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;localAndLessCode&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="c1"&gt;// do dev-only things&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;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[dev-only] Warnings to help devs!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;anotherFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&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;localAndLessCode&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="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[dev-only] Warnings to help devs!&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="c1"&gt;// Do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Do the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example nº 2:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;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="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="c1"&gt;// do dev-only things&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;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[dev-only] Warnings to help devs!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;anotherFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&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;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="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="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[dev-only] Warnings to help devs!&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="c1"&gt;// Do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Tools like babel will replace every &lt;code&gt;process.env.NODE_ENV&lt;/code&gt; (and any other &lt;code&gt;proces.env&lt;/code&gt; variable) with its value. Then, the examples above would be transformed like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example nº 1 transformed:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;localAndLessCode&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;localAndLessCode&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="c1"&gt;// do dev-only things&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;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[dev-only] Warnings to help devs!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;anotherFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&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;localAndLessCode&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="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[dev-only] Warnings to help devs!&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="c1"&gt;// Do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Example nº 2 transformed:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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="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="c1"&gt;// do dev-only things&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;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[dev-only] Warnings to help devs!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;anotherFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&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="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="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="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[dev-only] Warnings to help devs!&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="c1"&gt;// Do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As you can see, in the second example, both comparisons are static. This is something that uglifiers like the webpack's &lt;code&gt;TerserPlugin&lt;/code&gt; or &lt;code&gt;babel-minify&lt;/code&gt; will take as advantage to literally remove those ifs (and their content!).&lt;/p&gt;

&lt;h3&gt;
  
  
  It's free!
&lt;/h3&gt;

&lt;p&gt;This is really cool because you don't have to configure anything to reduce your bundle size, it's something you can &lt;em&gt;fix&lt;/em&gt; in your code! And it will help you reduce &lt;em&gt;a lot&lt;/em&gt; of code you don't want to have in production builds!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>babel</category>
      <category>webpack</category>
      <category>webperf</category>
    </item>
    <item>
      <title>Add file extensions to your dynamic imports to reduce size</title>
      <dc:creator>Luciano Graziani</dc:creator>
      <pubDate>Fri, 12 Apr 2019 00:43:06 +0000</pubDate>
      <link>https://dev.to/lgraziani2712/add-file-extensions-to-your-dynamic-imports-to-reduce-size-4b86</link>
      <guid>https://dev.to/lgraziani2712/add-file-extensions-to-your-dynamic-imports-to-reduce-size-4b86</guid>
      <description>&lt;p&gt;UPDATE: Here's a codesandbox with this situation: &lt;a href="https://codesandbox.io/s/webpack-dynamic-import-duplication-array-gv0gq"&gt;https://codesandbox.io/s/webpack-dynamic-import-duplication-array-gv0gq&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Instead of writing dynamic imports like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`./my-path/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Write them like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`./my-path/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.ext`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It will reduce the bundle size!&lt;/p&gt;

&lt;h2&gt;
  
  
  Long explanation
&lt;/h2&gt;

&lt;p&gt;Yesterday I was reading the generated code by webpack and found something interesting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="o"&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;./en/_extras&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./en/_extras.js&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./en/color&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="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;5&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./en/color.js&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="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;5&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="c1"&gt;// The rest of the files&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;map&lt;/code&gt; object represent every possible chunk for an specific dynamic import, and it was twice the size I expected.&lt;/p&gt;

&lt;p&gt;Then it hit me: I didn't wrote the file extension in my dynamic imports. When I did it, each of those objects reduced its sizes to match the numbers of files!&lt;/p&gt;

&lt;p&gt;It's not like it will massively reduce your bundle size, but it's something you could get for free!&lt;/p&gt;

</description>
      <category>webperf</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>webpack</category>
    </item>
    <item>
      <title>I wrote my first babel plugin! (And it wasn't that hard!)</title>
      <dc:creator>Luciano Graziani</dc:creator>
      <pubDate>Tue, 05 Mar 2019 22:35:58 +0000</pubDate>
      <link>https://dev.to/lgraziani2712/i-wrote-my-first-babel-plugin-and-it-wasnt-that-hard-4f9h</link>
      <guid>https://dev.to/lgraziani2712/i-wrote-my-first-babel-plugin-and-it-wasnt-that-hard-4f9h</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cover image from &lt;a href="https://www.grimms.eu/en/products/building-amp-rainbow-worlds/organic-shapes/1240/colored-waldorf-blocks"&gt;https://www.grimms.eu/en/products/building-amp-rainbow-worlds/organic-shapes/1240/colored-waldorf-blocks&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Today I wrote a tiny babel plugin for reducing the size of a vue proyect by transforming the &lt;code&gt;props&lt;/code&gt; attribute in their minimal expression (and at the same time, removing &lt;code&gt;vue-types&lt;/code&gt; as a dependency).&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps I did to learn how to write a babel plugin
&lt;/h3&gt;

&lt;p&gt;To understand (at least something, lol) how babel's plugin system works, I did the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up vscode to be able to debug the plugin.&lt;/li&gt;
&lt;li&gt;Read the plugin section of the babel-handbook: &lt;a href="https://github.com/jamiebuilds/babel-handbook"&gt;https://github.com/jamiebuilds/babel-handbook&lt;/a&gt;. I didn't read it all, though. And the first time didn't understood anything.&lt;/li&gt;
&lt;li&gt;Read other plugins' code.&lt;/li&gt;
&lt;li&gt;Install &lt;code&gt;@types/babel__core&lt;/code&gt;. The autocomplete (even in JS) in vscode is lit. Really helpful!&lt;/li&gt;
&lt;li&gt;Debug a lot. In conjunction with the handbook, it made me understand a little how to understand how the code is interpreted and how to modify it.&lt;/li&gt;
&lt;li&gt;Add jsdoc everytime you can. You help vscode to help you ;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The following snipet is the vscode launch's configuration for debugging a babel plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;"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;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"request"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"launch"&lt;/span&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;"Debug babel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"console"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"integratedTerminal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"autoAttachChildProcesses"&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="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"program"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}/node_modules/@babel/cli/bin/babel.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"args"&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="s2"&gt;"--config-file=${workspaceFolder}/babel.config.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"${workspaceFolder}/path/to/file.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="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;The string &lt;code&gt;"${workspaceFolder}/path/to/file.js"&lt;/code&gt; is the file to be compiled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Babel plugin basic structure
&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;declare&lt;/span&gt; &lt;span class="p"&gt;}&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;@babel/helper-plugin-utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;types&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="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;@babel/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;declare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// If the plugin requires babel 7++&lt;/span&gt;
  &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assertVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// For what I learned, although the name is not required,&lt;/span&gt;
    &lt;span class="c1"&gt;// if you add one, remember to NOT add the "babel-plugin"&lt;/span&gt;
    &lt;span class="c1"&gt;// prefix. E.g., if the package's name is&lt;/span&gt;
    &lt;span class="c1"&gt;// "babel-plugin-transform-vue-props", the name would be&lt;/span&gt;
    &lt;span class="c1"&gt;// the following:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;transform-vue-props&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="cm"&gt;/**
       * @param {babel.types.ImportDeclaration} path Import's node
       * @return {void}
       */&lt;/span&gt;
      &lt;span class="nx"&gt;ImportDeclaration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&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;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-types&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;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;visitors&lt;/code&gt; prop its where everything happens.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When we talk about "going" to a node, we actually mean we are visiting them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md#toc-visitors"&gt;Handbook: Visitors&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each node has a type, and everyone of them can be visited. In the example above we are visiting each import declaration and remove them if they are importing the &lt;code&gt;vue-types&lt;/code&gt; library.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to transform code
&lt;/h3&gt;

&lt;p&gt;By the way, if you want to transform, e.g. an object, into an array of strings (the keys), you would have to do the following:&lt;/p&gt;

&lt;p&gt;Consider this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Luciano&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;28&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;If you want to transform it to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&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;name&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="s1"&gt;age&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;You would have to do the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;declare&lt;/span&gt; &lt;span class="p"&gt;}&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;@babel/helper-plugin-utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;types&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="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;@babel/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;declare&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;transform-obj-to-array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="cm"&gt;/**
       * @param {babel.types.VariableDeclarator} path Declaration
       * @return {void}
       */&lt;/span&gt;
      &lt;span class="nx"&gt;VariableDeclarator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&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;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&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="o"&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;isObjectExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&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;arrayExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;stringLiteral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;By the way, I had to debug it until I could find the correct visitor (wasn't &lt;code&gt;VariableDeclaration&lt;/code&gt; nor &lt;code&gt;AssignmentExpression&lt;/code&gt;). JSDoc + &lt;code&gt;@types/babel__core&lt;/code&gt; + VSCode FTW.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see, isn't as simple as to replace it like a string. The &lt;code&gt;types&lt;/code&gt; (aka &lt;code&gt;t&lt;/code&gt;) prop from &lt;code&gt;@babel/core&lt;/code&gt; it's very helpful for validating what structure is something and for building new ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  babel-plugin-transform-vue-props
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The lib can be found here &lt;a href="https://github.com/lgraziani2712/babel-plugin-transform-vue-props"&gt;https://github.com/lgraziani2712/babel-plugin-transform-vue-props&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;It &lt;em&gt;really&lt;/em&gt; helps to remove &lt;code&gt;vue-types&lt;/code&gt; as dependency (since it does nothing in production), which can be weight between 25kb~ to 3.5kb~ gzipped and if webpack (or any bundler) is configured to use the production file (&lt;a href="https://github.com/dwightjack/vue-types#production-build"&gt;https://github.com/dwightjack/vue-types#production-build&lt;/a&gt;). This size doesn't counts the use of &lt;code&gt;vue-types&lt;/code&gt; in every component.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;I &lt;em&gt;reaaaally&lt;/em&gt; love to resolve optimization problems, and I wanted to remove &lt;code&gt;vue-types&lt;/code&gt; from the production bundle. I searched everywhere but didn't find anything confortable to use. I also rediscovered this doc &lt;a href="https://vuejs.org/v2/guide/components-props.html#Prop-Types"&gt;https://vuejs.org/v2/guide/components-props.html#Prop-Types&lt;/a&gt; and remember what is the most simple definition of the &lt;code&gt;props&lt;/code&gt; attribute of a component.&lt;/p&gt;

&lt;p&gt;EDIT: I just found &lt;a href="https://astexplorer.net/"&gt;https://astexplorer.net/&lt;/a&gt;. Is really dope!&lt;/p&gt;




&lt;p&gt;I hope this post will motivate anyone who wants to explore the world of babel plugins but don't know where or how to start! Cheers!&lt;/p&gt;

</description>
      <category>babel</category>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The value of unit or integration testing</title>
      <dc:creator>Luciano Graziani</dc:creator>
      <pubDate>Mon, 17 Dec 2018 17:08:01 +0000</pubDate>
      <link>https://dev.to/lgraziani2712/the-value-of-unit-or-integration-testing-56i0</link>
      <guid>https://dev.to/lgraziani2712/the-value-of-unit-or-integration-testing-56i0</guid>
      <description>&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%2F9x97ar5we0c25zqkrtrh.jpg" 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%2F9x97ar5we0c25zqkrtrh.jpg" alt="Where are the tests?" width="650" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Comic by CommitStrip: &lt;a href="http://www.commitstrip.com/en/2017/02/08/where-are-the-tests/" rel="noopener noreferrer"&gt;http://www.commitstrip.com/en/2017/02/08/where-are-the-tests/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Try to write unit/integration tests, at least, for you core processes. Your future self will thank you.&lt;/p&gt;




&lt;p&gt;A few days ago I had to refactor two processes in a stock system: sales and purchases. Both have, at least, one step in common: they query a list of products filtering by a list of IDs. Both use the same data except that sales uses the &lt;code&gt;sale_price&lt;/code&gt; (aliased as &lt;code&gt;unit_price&lt;/code&gt;) and purchases uses the &lt;code&gt;unit_price&lt;/code&gt;. Both manage a "unit price", one as the unit price for sale, and another for purhcase.&lt;/p&gt;

&lt;p&gt;The sales process was written by me and the purchases process was written by a teammate, so, even when they have that step in common, both processes did in different ways. It's OK and normal. We didn't knew what they'll have in common until we wrote the code.&lt;/p&gt;

&lt;p&gt;Those processes are &lt;em&gt;extremely&lt;/em&gt; important and sensitive because they are the core of the system AND manage money. Because of that, we decided to add unit and integration tests for each constraint they have.&lt;/p&gt;

&lt;p&gt;Because of that decision, &lt;em&gt;even&lt;/em&gt; when my teammate, who isn't used to write tests, didn't wanted to "waste" time written them, today I could refactor both processes and prevented a dangerous bug to emerge:&lt;/p&gt;

&lt;p&gt;While refactoring that common step in one method, I decided to query every attribute required by the sales and purchases processes, which means that now both will have accessible the &lt;code&gt;sale_price&lt;/code&gt; and &lt;code&gt;unit_price&lt;/code&gt; props. But I didn't remembered that inside the sales process, the total attribute was being calculated using the old &lt;code&gt;sale_price&lt;/code&gt; alias: &lt;code&gt;unit_price&lt;/code&gt;. With the change, everything still worked fine, but the total, instead of multipliying the &lt;code&gt;sale_price&lt;/code&gt; for the amount of products, was using the &lt;em&gt;real&lt;/em&gt; &lt;code&gt;unit_price&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Only because the snapshot tests warned me about a diff, I could catch the error. Only because we decided to add tests to our processes, instead of letting the user catch us for us, with everything that means.&lt;/p&gt;

&lt;p&gt;I hope this experience will motivate you to write tests!&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>testing</category>
      <category>beginners</category>
    </item>
    <item>
      <title>I want to store my benchmarks.js results</title>
      <dc:creator>Luciano Graziani</dc:creator>
      <pubDate>Sun, 11 Nov 2018 20:19:05 +0000</pubDate>
      <link>https://dev.to/lgraziani2712/i-want-to-store-my-benchmarksjs-results-20fl</link>
      <guid>https://dev.to/lgraziani2712/i-want-to-store-my-benchmarksjs-results-20fl</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cover image by &lt;a href="https://es.semrush.com/blog/benchmarking-fortalecer-imagen-corporativa/" rel="noopener noreferrer"&gt;Teresa Alba&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This past week I've been searching for a library that generates a JSON for benchmark.js' results. Since I didn't find anything, I've written one myself.&lt;/p&gt;

&lt;p&gt;By default, it stores everything in a file. But it has a callback function so you can do whatever you want, like storing it in a database.&lt;/p&gt;

&lt;p&gt;It also uses &lt;a href="https://www.npmjs.com/package/systeminformation" rel="noopener noreferrer"&gt;systeminformation&lt;/a&gt; to store static data about the machine is running the benchmarks.&lt;/p&gt;

&lt;p&gt;I think this lib is cool since it makes it possible to run your benchmarks in the CI pipeline and store the results in a database for future analysis.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, how can I start using it today?
&lt;/h2&gt;

&lt;p&gt;First, you need to install the dependencies:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;yarn add benchmark benchmark-json-reporter&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Or&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install --save benchmark benchmark-json-reporter&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Last, you have to create a file that will run your benchmarks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Benchmark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;benchmark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsonReporter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;benchmark-json-reporter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;suite&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;Benchmark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Suite&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-bench-suite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Just this&lt;/span&gt;
&lt;span class="nf"&gt;jsonReporter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;suite&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;suite&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bench-name-1&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Faster heavy process&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bench-name-n&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Slower heavy process&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="c1"&gt;// run async&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;async&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;This basic example will store the results in the following file: &lt;code&gt;&amp;lt;rootFolder&amp;gt;/benchmarks/my-bench-suite-({md5-hash}.log)&lt;/code&gt;. The md5-hash is used to identify a machine univocally.&lt;/p&gt;

&lt;p&gt;By the way, you can also store your benchmarks in a database like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Benchmark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;benchmark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsonReporter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;benchmark-json-reporter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;suite&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;Benchmark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Suite&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-bench-suite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Just this&lt;/span&gt;
&lt;span class="nf"&gt;jsonReporter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;suite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hashId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;folder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Connect to a database&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SomeEndPoint&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// 2. Store the sysinfo with the hashId as a main ID&lt;/span&gt;
    &lt;span class="nx"&gt;connection&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hashId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&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;sysinfo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sysinfo&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
        &lt;span class="c1"&gt;// 3. Store the benchmarks&lt;/span&gt;
        &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;benchs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bench&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
            &lt;span class="c1"&gt;// For each benchmark, push the result into the collection&lt;/span&gt;
            &lt;span class="nx"&gt;connection&lt;/span&gt;
              &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hashId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getProp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;benchmarks&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="nf"&gt;getCollection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bench&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&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="nx"&gt;bench&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 4. Close the database connection&lt;/span&gt;
        &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="c1"&gt;// 5. Profit.&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;suite&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bench-name-1&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Faster heavy process&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bench-name-n&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Slower heavy process&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="c1"&gt;// run async&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;async&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;Thank you for reading! And if you have any question, don't hesitate to ask!&lt;/p&gt;

</description>
      <category>benchmarks</category>
      <category>metrics</category>
      <category>ci</category>
      <category>node</category>
    </item>
    <item>
      <title>How a conference can be so rewarding</title>
      <dc:creator>Luciano Graziani</dc:creator>
      <pubDate>Sat, 27 Oct 2018 18:36:33 +0000</pubDate>
      <link>https://dev.to/lgraziani2712/how-a-conference-can-be-so-rewarding-4amb</link>
      <guid>https://dev.to/lgraziani2712/how-a-conference-can-be-so-rewarding-4amb</guid>
      <description>&lt;p&gt;TL;DR. If you have to travel to go to conferences, try it! At least one time. Save money, if you can, and try it! I think you won't be disappointed. And it's OK to go alone (maybe better: it's easier to talk to strangers.)&lt;/p&gt;

&lt;p&gt;Last weekend I went to my first big conferece: NodeConfArg at Buenos Aires. I'm from a city from the north Patagonia where are no meetups and no one is organizing anything, which makes it difficult to find people with the same technical profile.&lt;/p&gt;

&lt;p&gt;I went alone. My actual work allowed me to take those days off, but it didn't help me economically in any way. This made imposible to some of my teammates to go, since they have more responsabilities than me, like their house or family. This experience costed me half of my monthly salary.&lt;/p&gt;

&lt;p&gt;Please, please, if you have a job like this, update your CV and send it to other places, even if you don't think your expertise/experience is sufficient. I'm doing this right now because I don't want to spend my time in a place that doesn't care about the improvement of their human resources.&lt;/p&gt;

&lt;p&gt;Ok, enough ranting. At the NodeConfArg, I could talk to people from other countries like Bolivia, Perú or USA. I could also meet and exchange some words with some speakers (by the way, everyone was super cool). I could also meet an online friend of mine and their teammates from the other extreme of my country. I felt multiple emotions at the same time.&lt;/p&gt;

&lt;p&gt;The first day had workshops. I register to two: the first one was about the &lt;a href="https://datproject.org/"&gt;dat project&lt;/a&gt;, a p2p protocol for the web. It was really &lt;em&gt;really&lt;/em&gt; amazing. Both teachers had good charisma and passion about what they were teaching. By the way, here's the repo: &lt;a href="https://github.com/geut/dat-workshop"&gt;https://github.com/geut/dat-workshop&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second and third day had talks only (and an amazing panel). Every talk was fabulous. In total where 20 incredible talks which blown my mind. Mostly everything was new to me. Since I'm not working at scale, and since most of the talks were about optimization, I could learn &lt;em&gt;a lot&lt;/em&gt;. By the way, it's &lt;em&gt;OK&lt;/em&gt; to &lt;em&gt;not&lt;/em&gt; know about the topics (and maybe even better).&lt;/p&gt;

&lt;p&gt;There were talks about iot, communication through sounds (using &lt;a href="https://chirp.io/"&gt;https://chirp.io/&lt;/a&gt;), the use of monorepos, ia and art, inclussion, standards, optimization (a looot), native extensions, tracing and metrics, serverless, p2p and about the state of node+js as a community. A lot of topics.&lt;/p&gt;

&lt;p&gt;I'm conscient that I'll implement near nothing about everything I learned right now. But! I can say that &lt;em&gt;now&lt;/em&gt; I have curiosity about those topics (so I will start reading about them).&lt;/p&gt;

&lt;p&gt;Thank you for reading this!&lt;/p&gt;

&lt;p&gt;See you next time!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>career</category>
    </item>
    <item>
      <title>How scoop made my dev experience in Windows so great</title>
      <dc:creator>Luciano Graziani</dc:creator>
      <pubDate>Wed, 17 Oct 2018 18:07:15 +0000</pubDate>
      <link>https://dev.to/lgraziani2712/how-scoop-made-my-dev-experience-in-windows-so-great-3k20</link>
      <guid>https://dev.to/lgraziani2712/how-scoop-made-my-dev-experience-in-windows-so-great-3k20</guid>
      <description>&lt;p&gt;Since I started programming, I used Windows for the most part. I always had problems while configuring everything I needed every time I formatted the PC or changed it. At the beggining I tried to use xamp or wamp, but I was uncomfortable with those tools, things were difficult to update, change and share configuration between teammates.&lt;/p&gt;

&lt;p&gt;The windows' &lt;code&gt;cmd&lt;/code&gt; is extremely uncomfortable for me too. Since I learned to use the CLI with Linux (vi 4ever, lol). I felt in love at first sight when I started using Cmder.&lt;/p&gt;

&lt;p&gt;I've been working with a 4-person team mainly using nodejs or php7.2 in the backend and vue in the frontend. Early this year, when we started a new project, I truly wanted to share how I configured my dev environment with them since everyone uses Windows.&lt;/p&gt;

&lt;p&gt;I started searching some package manager but for Windows. I found chocolatey first, and I tried it but I didn't like it (I don't remember why). So I continued searching until I found &lt;code&gt;scoop&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scoop
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Scoop is a command-line installer for Windows.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Github repository: &lt;a href="https://github.com/lukesampson/scoop"&gt;https://github.com/lukesampson/scoop&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tool made my dev environment configuration a breeze. I could even create a git repository and store every configuration for every tool. This allowed me and my teammates to install, keep updated and configure everything from php (with x-debug), apache, nodejs, yarn, mariadb, composer, cmder, and other general tools like gimp, screentogif (another excellent oss tool) or filezilla in less than an hour.&lt;/p&gt;

&lt;p&gt;Today I had to install everything from scratch in another laptop and I only had to install scoop, clone the configuration repo and start installing everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  So how I can start using scoop with a git repo?
&lt;/h2&gt;

&lt;p&gt;First of all, you have to install scoop (extracted from the official page):&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Windows 7 SP1+ / Windows Server 2008+&lt;/li&gt;
&lt;li&gt;PowerShell 3 (or later) and .NET Framework 4.5+&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PowerShell must be enabled for your user account e.g.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;set-executionpolicy remotesigned -s currentuser&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;Run this command from your PowerShell to install scoop to it's default location (C:\Users&amp;lt;user&amp;gt;\scoop):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;iex &lt;span class="o"&gt;(&lt;/span&gt;new-object net.webclient&lt;span class="o"&gt;)&lt;/span&gt;.downloadstring&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'https://get.scoop.sh'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Create your configuration repository
&lt;/h3&gt;

&lt;p&gt;Considering you installed scoop at the default location (C:\Users&amp;lt;user&amp;gt;\scoop), you have to access the &lt;code&gt;C:\Users\&amp;lt;user&amp;gt;\scoop\persist&lt;/code&gt; folder. Every scoop app will store their configuration in this folder which isn't affected by uninstalls. Then you could run &lt;code&gt;git init&lt;/code&gt; and start persisting you configuration.&lt;/p&gt;

&lt;p&gt;By the way, before you start committing and pushing everything, take into account that there are some special files that we don't want to push. To prevent files like those binaries from mariadb, or nodejs caches, we have to create a &lt;code&gt;.gitignore&lt;/code&gt; file at the root of the repository, in other words, inside the &lt;code&gt;persist&lt;/code&gt; folder. It's OK to add custom files to it.&lt;/p&gt;

&lt;p&gt;My &lt;code&gt;.gitignore&lt;/code&gt; has the following values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vendor
cache
data
plugins
composer
nodejs
yarn
log.*
user-ConEmu.xml
.history
*.dmp

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



&lt;p&gt;I also written a &lt;code&gt;README.md&lt;/code&gt; file with everything everyone needs to know to configure each app by hand, like mariadb, or adding apache and mariadb as a windows services.&lt;/p&gt;

&lt;p&gt;Things like configuring php with xdebug, which for me was always cumbersome, for the first time was as easy as install it. By default, when you install &lt;code&gt;php-xdebug&lt;/code&gt;, scoop creates a &lt;code&gt;xdebug.ini&lt;/code&gt; file inside &lt;code&gt;C:\Users\&amp;lt;user&amp;gt;\scoop\persist\php\conf.d\&lt;/code&gt; folder with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zend_extension=C:\Users\&amp;lt;user&amp;gt;\scoop\apps\php-xdebug\current\php_xdebug
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But the thing is, if I want to have a generic configuration which can be used by everyone, I cannot have absolute paths. The following configuration is what I have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;zend_extension=../../../../apps/php-xdebug/current/php_xdebug

[XDebug]
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The new &lt;code&gt;[XDebug]&lt;/code&gt; configuration allows IDE's like VSCode to debug php code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Share the configuration between teammates
&lt;/h2&gt;

&lt;p&gt;Once you started pushing your configuration into your repository, you can now share it. Since the &lt;code&gt;persist&lt;/code&gt; folder will contain data right after the installation, &lt;code&gt;git&lt;/code&gt; will complain if you try to clone something inside. To resolve this problem, you have to do the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init 

git remote add origin PATH/TO/REPO 

git fetch 

git checkout -t origin/master -f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Source: &lt;a href="https://stackoverflow.com/a/43287779/2862917"&gt;https://stackoverflow.com/a/43287779/2862917&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this help to simplify the configuration process to anyone using Windows! Feel free to ask me anything!&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>windows</category>
      <category>scoop</category>
    </item>
  </channel>
</rss>
