<?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: Nabil Tharwat</title>
    <description>The latest articles on DEV Community by Nabil Tharwat (@kl13nt).</description>
    <link>https://dev.to/kl13nt</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%2F241135%2Fd8546451-0e78-468f-a133-b4709ad1b276.jpg</url>
      <title>DEV Community: Nabil Tharwat</title>
      <link>https://dev.to/kl13nt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kl13nt"/>
    <language>en</language>
    <item>
      <title>Boosting My Productivity With Git Worktrees</title>
      <dc:creator>Nabil Tharwat</dc:creator>
      <pubDate>Tue, 17 Sep 2024 18:43:05 +0000</pubDate>
      <link>https://dev.to/kl13nt/using-git-worktrees-to-boost-my-productivity-18m4</link>
      <guid>https://dev.to/kl13nt/using-git-worktrees-to-boost-my-productivity-18m4</guid>
      <description>&lt;p&gt;I often work on several features simultaneously, which leads me to stash changes and forget about them while switching to other tasks. I tried using git hooks and terminal aliases as reminders, but they were either too much hassle or easy to ignore. So, I had to find a better solution.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This article was originally posted on my blog over a year ago but I keep coming back to it. Re-sharing it to the world :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Git in a nutshell
&lt;/h2&gt;

&lt;p&gt;Git stores information as a list of &lt;em&gt;snapshots&lt;/em&gt;. A &lt;em&gt;snapshot&lt;/em&gt; is a stored version of the repository at a given point in time. Each commit represents a snapshot in the git world. &lt;/p&gt;

&lt;p&gt;The working tree is a single checkout of one version of the project. These files are pulled out of the compressed database in the Git directory and placed on disk for you to use or modify. This is the place in which you do your work before staging and committing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git Work Trees
&lt;/h2&gt;

&lt;p&gt;Git Worktrees are a way to manage multiple git working trees at the same time without the hassle of git stash. They allow us to work on branches as sub-directories to a repository, completely alleviating the pain of stashing changes when an urgent, unrelated change is required.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;worktree&lt;/em&gt; module allows you to checkout multiple versions of the project in separate sub-directories in the same root directory of the repository. Take the following diagram for example on the traditional approach:&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%2Fb6ngautwoikcvrqekg81.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%2Fb6ngautwoikcvrqekg81.png" alt="Branches approach" width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example I have two stashed changes (which could be hundreds of lines of code) and 3 branches, &lt;em&gt;feature-1&lt;/em&gt;, &lt;em&gt;feature-2&lt;/em&gt;, and &lt;em&gt;fix-1&lt;/em&gt;. By the time I finish working on the &lt;em&gt;fix-1&lt;/em&gt; branch and push it my brain would've jumped to the next task and completely forgot about the previous features until I'm reminded of them again. &lt;/p&gt;

&lt;p&gt;Instead, with worktrees, it looks like this:&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%2Fwcgmogr6a3nwek0vkty9.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%2Fwcgmogr6a3nwek0vkty9.png" alt="Worktree based approach" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With worktrees the directory structure contains each worktree (branch) in a separate directory. This allows me to seamlessly switch from a branch to another simply by changing the directory I'm currently working in. My usual workflow with this approach consists of the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open a terminal in the project's directory&lt;/li&gt;
&lt;li&gt;Create a worktree with a branch name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;code .&lt;/code&gt; to open VSCode in the worktree directory&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When I want to switch from a worktree to another all I have to do is either create a different worktree using the same steps if I don't have it created already, or simply open a different directory with VSCode and start hacking away immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a worktree
&lt;/h2&gt;

&lt;p&gt;Creating a worktree is as simple as running &lt;code&gt;git worktree add directory-name branch-name&lt;/code&gt; for existing branches or &lt;code&gt;git worktree add directory-name -b branch-name&lt;/code&gt; to create a new branch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deleting a worktree
&lt;/h2&gt;

&lt;p&gt;After you're done working on a branch you can safely remove the worktree to stop polluting your directory structure. Simply run &lt;code&gt;git worktree remove directory-name&lt;/code&gt;. This doesn't delete the underlying branches so you can safely check them out again later. &lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas
&lt;/h2&gt;

&lt;p&gt;Worktrees are checkouts of repository branches, therefore untracked files are not copied. Files like &lt;code&gt;.env&lt;/code&gt; won't be copied, so make sure to copy them after creating a worktree and install dependencies if any exist. &lt;/p&gt;

&lt;p&gt;Also note that the directories created for the worktrees will show up in &lt;code&gt;git status&lt;/code&gt; logs when executed in the root repository directory. These gotchas are nothing to me compared to forgetting hours of work though. &lt;/p&gt;




&lt;p&gt;Thank you for reading! You can read more on my &lt;a href="https://nabiltharwat.com/blog" rel="noopener noreferrer"&gt;blog&lt;/a&gt; and support my work on &lt;a href="https://github.com/sponsors/KL13NT" rel="noopener noreferrer"&gt;GitHub Sponsors&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>git</category>
    </item>
    <item>
      <title>Big O Notation</title>
      <dc:creator>Nabil Tharwat</dc:creator>
      <pubDate>Fri, 21 Jun 2024 11:30:50 +0000</pubDate>
      <link>https://dev.to/kl13nt/big-o-notation-1id1</link>
      <guid>https://dev.to/kl13nt/big-o-notation-1id1</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/cs"&gt;DEV Computer Science Challenge v24.06.12: One Byte Explainer&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explainer
&lt;/h2&gt;

&lt;p&gt;Big O describes the efficiency of the worst case scenario of an algorithm. It helps categorize algorithms, but isn't accurate to describe real performance. An algorithm that does constant time O(1) may be slower due to complexity than a linear one O(N). &lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>cschallenge</category>
      <category>computerscience</category>
      <category>beginners</category>
    </item>
    <item>
      <title>You're doing state wrong</title>
      <dc:creator>Nabil Tharwat</dc:creator>
      <pubDate>Sun, 09 Jun 2024 12:40:51 +0000</pubDate>
      <link>https://dev.to/kl13nt/youre-doing-state-wrong-2ch8</link>
      <guid>https://dev.to/kl13nt/youre-doing-state-wrong-2ch8</guid>
      <description>&lt;p&gt;Implementing component state as a combination of booleans may seem like the easiest way to do it, but let's do something different.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover by Namroud Gorguis on Unsplash&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This article is framework- and language- agnostic. Code examples presented are written in a generic form.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Consider a music player
&lt;/h2&gt;

&lt;p&gt;That can play, pause, and stop. Developers are often tempted to represent&lt;br&gt;
each state in a separate boolean:&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;isStopped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isPlaying&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isPaused&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you think about this for a moment, each of those boolean states can be either true or false. Counting all possibilities yields 8 possible state variations, when our component only has 3 actual states. Which means we have 5 &lt;strong&gt;impossible states&lt;/strong&gt; in our tiny component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Impossible states&lt;/strong&gt; are states that the component is &lt;strong&gt;never&lt;/strong&gt; meant to be in, usually indicating a logic error. The music player can't be playing and stopped at the same time. It also can't be paused and playing at the same time. And so on.&lt;/p&gt;

&lt;p&gt;Guard statements usually accompany boolean states for this reason:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isStopped&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isPlaying&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isPaused&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// display stopped UI&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;isStopped&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;isPlaying&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isPaused&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// display playing UI&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;isStopped&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isPlaying&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;isPaused&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// display paused UI&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And state updates turn into a repetitive set of instructions:&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;// To play&lt;/span&gt;
&lt;span class="nf"&gt;setIsPlaying&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;setIsPaused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;setIsStopped&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// To stop&lt;/span&gt;
&lt;span class="nf"&gt;setIsPlaying&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;setIsPaused&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;setIsStopped&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;Each addition and modification later to the component needs to respect these 3 valid states, and to guard against those 5 &lt;strong&gt;impossible states&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hello, state machines!
&lt;/h2&gt;

&lt;p&gt;Every program can be simplified into a state machine. A state machine is a mathematical model of computation, an abstract machine that can be in exactly one of a finite number of states at any given time.&lt;/p&gt;

&lt;p&gt;It has a list of transitions between its defined states, and may execute &lt;strong&gt;effects&lt;/strong&gt; as a result of a transition.&lt;/p&gt;

&lt;p&gt;If we convert our media player states into a state machine we end up with a machine containing exactly 3 states (stopped, playing, and paused), and 5 transitions.&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%2Frza4bk2x2vcpx0fwqtep.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%2Frza4bk2x2vcpx0fwqtep.jpg" alt="Media player state machine" width="800" height="869"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can represent our simple machine in a single state that can be anything, from a Union Type to an Enum:&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;State&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stopped&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;playing&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;paused&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;STOPPED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;PLAYING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;PAUSED&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now state updates can be a single, consistent instruction:&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="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stopped&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// or&lt;/span&gt;
&lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;STOPPED&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this approach we completely eliminate &lt;strong&gt;impossible states&lt;/strong&gt;, make our state easier to control, and improve the component's readability.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about effects?
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;effect&lt;/strong&gt; is anything secondary to the component's functionality, like loading the track, submitting a form's data, etc. An &lt;strong&gt;action&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's consider forms. A form is usually found in one of four states: idle, submitting, success, and error. If we use boolean states we end up with 4 booleans, 16 possible combinations, and 12 &lt;strong&gt;impossible states&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead, let's make it a state machine too!&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%2Fdz41tizodnfhclffs1z3.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%2Fdz41tizodnfhclffs1z3.jpg" alt="Form state machine" width="800" height="708"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code behind this machine can be as simple as another method on the component:&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="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;IDLE&lt;/span&gt; &lt;span class="cm"&gt;/* default state */&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SUBMITTING&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;SUCCESS&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;submit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SUBMITTING&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;postFormUtility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&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="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SUCCESS&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;catch&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ERROR&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;h2&gt;
  
  
  The exception
&lt;/h2&gt;

&lt;p&gt;Obviously there are cases where a component may truly have only 2 states, therefore using a boolean for it works perfectly. Examples of this are modals to control their visibility, buttons to indicate a11y activation, etc.&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;isVisible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toggle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isVisible&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 problem starts to form when you introduce multiple booleans to represent variations of the state.&lt;/p&gt;

&lt;h2&gt;
  
  
  I still need booleans!
&lt;/h2&gt;

&lt;p&gt;You can derive booleans from your state. Control your component through a single state machine variable, but derive a hundred booleans from it if you want.&lt;/p&gt;

&lt;p&gt;Using the form example:&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="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;IDLE&lt;/span&gt; &lt;span class="cm"&gt;/* default state */&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;SUBMITTING&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;SUCCESS&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;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IDLE&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;isSubmitting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SUBMITTING&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ERROR&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isSuccessful&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SUCCESS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrap up
&lt;/h2&gt;

&lt;p&gt;Thinking of components as state machines has helped me simplify a lot of codebases. It's effect on the overall accessibility of a codebase is truly immense. Try it and tell me what you think! 👀&lt;/p&gt;




&lt;p&gt;Thanks for reading! You can follow me on &lt;a href="https://twitter.com/kl13nt"&gt;Twitter&lt;/a&gt;, or read more of my content on my &lt;a href="https://nabiltharwat.com/blog"&gt;blog&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Making a Build System Using NPM Scripts</title>
      <dc:creator>Nabil Tharwat</dc:creator>
      <pubDate>Fri, 02 Dec 2022 15:21:35 +0000</pubDate>
      <link>https://dev.to/kl13nt/making-a-build-system-using-npm-scripts-40oh</link>
      <guid>https://dev.to/kl13nt/making-a-build-system-using-npm-scripts-40oh</guid>
      <description>&lt;p&gt;&lt;em&gt;Cover by Guillaume TECHER on Unsplash.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This article was written on my phone. Do not expect these scripts to actually work except for the last set.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;npm scripts are a way to execute multiple npm modules and system commands through npm. You may already be familiar with &lt;code&gt;npm run&lt;/code&gt;, which is the interface we use with npm to execute those commands, and the interface we'll use to run our build system by the end of this article.&lt;/p&gt;

&lt;p&gt;From my &lt;a href="https://www.freecodecamp.org/news/release-management-modern-software-development/" rel="noopener noreferrer"&gt;Release Management for Modern Software Development&lt;/a&gt; article:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A build system is a set of transformations that transform a source into an artefact. It may be a simple command that starts up a compiler, a script to generate pdf from text files, or even a GUI solution that builds your project and generates a binary.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Our build system will be composed of the following steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linting&lt;/li&gt;
&lt;li&gt;Type-checking&lt;/li&gt;
&lt;li&gt;Unit testing&lt;/li&gt;
&lt;li&gt;Snapshot testing&lt;/li&gt;
&lt;li&gt;E2E testing&lt;/li&gt;
&lt;li&gt;Building&lt;/li&gt;
&lt;li&gt;Generating static content from build&lt;/li&gt;
&lt;li&gt;Pushing built assets to a live deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Basics
&lt;/h2&gt;

&lt;p&gt;npm scripts are stored in the &lt;code&gt;package.json&lt;/code&gt; under "scripts". Each key in the "scripts" object corresponds to a script that can execute multiple commands. They allow us to execute system commands, user executables, and executable nodejs command-line scripts.&lt;/p&gt;

&lt;p&gt;The following is a simple &lt;code&gt;package.json&lt;/code&gt; with a single command that prints "Hello, world!" to the terminal.&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="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;"echo"&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;Hello, world!&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&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="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;Notice I escaped the quotation marks. This is to avoid operating system differences. Windows handles chunks of text using double quotes, while most Linux distributions can handle them using single quotes. &lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;npm run echo&lt;/code&gt; in a terminal window should execute the &lt;code&gt;echo&lt;/code&gt; command specified then print "Hello, world!" to that terminal window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exit Codes
&lt;/h2&gt;

&lt;p&gt;Running processes return a code to the parent process or operating system known as "exit code" or "return code" upon termination. This code generally helps the operating system and other scripts decide what to do.&lt;/p&gt;

&lt;p&gt;For example, on POSIX systems a process exit code &lt;code&gt;0&lt;/code&gt; is a graceful termination. Meanwhile, an exit code between 1 to 255 would mean the process terminated unexpectedly. In case a code is not returned the code of the previous command is used.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Chaining Operators
&lt;/h2&gt;

&lt;p&gt;Terminal commands allow us to use several special operators to do more than run a single command. The &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; (and) operator allows us to execute multiple commands in series provided they all return exit code 0 or nothing at all. The &lt;code&gt;||&lt;/code&gt; (or) operator allows us to run multiple commands in series conditionally, running only each command iff the preceding command fails (returns exit code other than 0).&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;echo \"hello\" &amp;amp;&amp;amp; play&lt;/code&gt; will execute the &lt;code&gt;echo&lt;/code&gt; and if that succeeds will execute the &lt;code&gt;play&lt;/code&gt;. If the &lt;code&gt;echo&lt;/code&gt; fails then the whole script will terminate and the initiating process will terminate with code other than 0. &lt;/p&gt;

&lt;p&gt;On the other hand, &lt;code&gt;invalid_command || echo "\hello"\&lt;/code&gt; will execute the echo iff the &lt;code&gt;invalid_command&lt;/code&gt; command fails.&lt;/p&gt;

&lt;p&gt;There are tons of operators we can use in our npm scripts but I won’t go through them for the sake of simplicity. I will however use a utility called npm-run-all that will help us make our build system with simpler commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initial Build Scripts
&lt;/h2&gt;

&lt;p&gt;The simplest version of our build system is a collection of commands that execute in series using the &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator. We'll also depend on executing npm scripts through other npm scripts. Let's assume these commands actually work.&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="s2"&gt;"npm run checks &amp;amp;&amp;amp; npm run test &amp;amp;&amp;amp; npm run transpile &amp;amp;&amp;amp; npm run css &amp;amp;&amp;amp; npm run generate &amp;amp;&amp;amp; npm run deploy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"transpile"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"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;"css"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"postcss"&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;"npm run unit &amp;amp;&amp;amp; npm run snap &amp;amp;&amp;amp; npm run e2e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"checks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run lint &amp;amp;&amp;amp; npm run typecheck"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"typecheck"&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 --noEmit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eslint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"generate"&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 scripts/generate.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;"deploy"&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 scripts/deploy.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;"e2e"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cypress"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"unit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"snap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jest"&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;In this example, we assume we have a few JS script files in the &lt;code&gt;/scripts&lt;/code&gt; directory. Our &lt;code&gt;build&lt;/code&gt; script runs all the checks and build steps we need. If any of these commands fails the whole chain fails and the build is terminated.&lt;/p&gt;

&lt;p&gt;To execute this build system we would need to either create a script that combines multiple commands &lt;code&gt;npm run checks &amp;amp;&amp;amp; npm run test &amp;amp;&amp;amp; npm run build &amp;amp;&amp;amp; npm run generate &amp;amp;&amp;amp; npm run deploy&lt;/code&gt; like I did in &lt;code&gt;build&lt;/code&gt; or run this whole line by hand every time. Maybe save it as an alias. This is difficult to read and requires a lot of repeatedly nested &lt;code&gt;npm run&lt;/code&gt;. We can change that with &lt;code&gt;npm-run-all&lt;/code&gt; though!&lt;/p&gt;

&lt;h2&gt;
  
  
  npm-run-all
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;{
&lt;span class="gd"&gt;- "build": "npm run checks &amp;amp;&amp;amp; npm run test &amp;amp;&amp;amp; npm run transpile &amp;amp;&amp;amp; npm run css &amp;amp;&amp;amp; npm run generate &amp;amp;&amp;amp; npm run deploy",
&lt;/span&gt;&lt;span class="gi"&gt;+ "build": "run-s --print-name checks test transpile css generate deploy",
&lt;/span&gt;&lt;span class="gd"&gt;- "test": "npm run unit &amp;amp;&amp;amp; npm run snap &amp;amp;&amp;amp; npm run e2e",
&lt;/span&gt;&lt;span class="gi"&gt;+ "test": "run-s --print-name unit snap e2e",
&lt;/span&gt;&lt;span class="gd"&gt;- "checks": "npm run lint &amp;amp;&amp;amp; npm run typecheck",
&lt;/span&gt;&lt;span class="gi"&gt;+ "checks": "run-s --print-name lint typecheck",
&lt;/span&gt;  "transpile": "babel",
  "css": "postcss",
  "typecheck": "tsc --noEmit",
  "lint": "eslint",
  "generate": "node scripts/generate.js",
  "deploy": "node scripts/deploy.js",
  "e2e": "cypress",
  "unit": "jest",
  "snap": "jest"
  "typecheck": "tsc --noEmit",
  "lint": "eslint",
  "generate": "node scripts/generate.js",
  "deploy": "node scripts/deploy.js",
  "e2e": "cypress",
  "unit": "jest",
  "snap": "jest",
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we utilise the helper binary &lt;code&gt;run-s&lt;/code&gt; from npm-run-all to execute multiple commands in series without the &lt;code&gt;npm run&lt;/code&gt; spam. This is much easier to read and provides more fine-grained control over our scripts. The &lt;code&gt;--print-name&lt;/code&gt; flag prints the name of the script before it’s run so we can differentiate the output logs better. Its shorthand is &lt;code&gt;-n&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parallelised Scripts
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;run-p&lt;/code&gt; is another utility which, as you might have already guessed, executes scripts in parallel. Each script in its own child-process. &lt;code&gt;run-p&lt;/code&gt; is useful for development scenarios where you want to run multiple servers with a single command (e.g., local dev database and a nodejs dev server), and can used to&lt;br&gt;
parallelise testing and pre-build checks to improve our build times. So, let’s parallelise our testing scripts!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;{
&lt;span class="gd"&gt;- "test": "run-s -n unit snap e2e",
&lt;/span&gt;&lt;span class="gi"&gt;+ "test": "run-p -n --aggregate-output unit snap e2e",
&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I supplied the &lt;code&gt;--aggregate-output&lt;/code&gt; flag to avoid interleaving the output of every parallel command. This delays the printing of each command’s output until it has finished so we can have comprehensible logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre And Post Scripts
&lt;/h2&gt;

&lt;p&gt;pre- and post- scripts are npm scripts that execute before and after another script with a matching name. They allow us to simplify our commands and give them more semantic meaning. Npm executes these scripts on its own once we execute a command with matching pre- and post- scripts. You can have either or both at the same time, npm won't mind. This example from the npm docs sums it up pretty well:&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;"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;"precompress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{{ executes BEFORE the `compress` script }}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"compress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{{ run command to compress files }}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"postcompress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{{ executes AFTER `compress` script }}"&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;Applying this to the build scripts we end up with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;{
&lt;span class="gi"&gt;+ "prebuild": "run-s -n checks test",
&lt;/span&gt;&lt;span class="gd"&gt;- "build": "run-s -n checks test transpile css generate deploy",
&lt;/span&gt;&lt;span class="gi"&gt;+ "build": "run-s -n babel &amp;amp; css",
+ "postbuild": "run-s -n generate deploy",
&lt;/span&gt;}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can take this build system one step further and utilise glob-like execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  npm-run-all glob-like execution
&lt;/h2&gt;

&lt;p&gt;We can use &lt;a href="https://en.wikipedia.org/wiki/Glob_(programming)" rel="noopener noreferrer"&gt;glob&lt;/a&gt;-like patterns to specify npm-scripts. The difference is one; the separator is &lt;code&gt;:&lt;/code&gt; instead of &lt;code&gt;/&lt;/code&gt;. We call scripts with the &lt;code&gt;:&lt;/code&gt; separator subcommands. A &lt;code&gt;test:e2e&lt;/code&gt; script can be referred to as subcommand &lt;code&gt;e2e&lt;/code&gt; of &lt;code&gt;test&lt;/code&gt;. &lt;code&gt;npm-run-all&lt;/code&gt; can execute all subcommands of a given command through the &lt;code&gt;*&lt;/code&gt; glob operator. For example, &lt;code&gt;run-s test:*&lt;/code&gt; executes all subcommands of &lt;code&gt;test&lt;/code&gt; which may include &lt;code&gt;test:e2e&lt;/code&gt; and &lt;code&gt;test:unit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We’ll use it to structure our commands into a neater flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;{
&lt;span class="gd"&gt;- "prebuild": "run-s -n checks test",
&lt;/span&gt;&lt;span class="gi"&gt;+ "prebuild": "run-s -n check:* &amp;amp;&amp;amp; run-p -n --aggregate-output test:*",
&lt;/span&gt;  "build": "run-s transpile css",
  "postbuild": "run-s -n generate deploy",
&lt;span class="gd"&gt;- "test": "run-p -n --aggregate-output unit snap e2e",
- "checks": "run-s -n lint typecheck",
- "typecheck": "tsc --noEmit",
&lt;/span&gt;  "transpile": "babel",
  "css": "postcss",
&lt;span class="gi"&gt;+ "check:types": "tsc --noEmit",
&lt;/span&gt;&lt;span class="gd"&gt;- "lint": "eslint",
&lt;/span&gt;&lt;span class="gi"&gt;+ "check:lint": "eslint",
&lt;/span&gt;&lt;span class="gd"&gt;- "e2e": "cypress",
- "unit": "jest",
- "snap": "jest",
&lt;/span&gt;&lt;span class="gi"&gt;+ "test:e2e": "cypress",
+ "test:unit": "jest",
+ "test:snap": "jest",
&lt;/span&gt;  "generate": "node scripts/generate.js",
  "deploy": "node scripts/deploy.js",
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’ve created a simple, executable set of these scripts that you can run on your system without having to install any dependencies. All these commands do is output their names, but this should be enough to give you a general idea of how a real build system like this will work at runtime. Just make sure to initialize a new project with npm and add these scripts to the &lt;code&gt;package.json&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"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;"prebuild"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"run-s -n check:* &amp;amp;&amp;amp; run-p -n --aggregate-output test:*"&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;"run-s transpile css"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"transpile"&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 transpile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"css"&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 css"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"postbuild"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"run-s -n generate deploy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"check:types"&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 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;"check:lint"&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 eslint"&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:e2e"&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 e2e"&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:unit"&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 unit"&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:snap"&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 snap"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"generate"&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 generate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deploy"&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 deploy"&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 following is the output on my Windows 10 machine. By default, npm prints each running command before executing it. You can hide these npm logs using the &lt;code&gt;-s&lt;/code&gt; or &lt;code&gt;--silent&lt;/code&gt; flag to ignore some of the spam that may be output.&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;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 prebuild
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; run-s &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; check:&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; run-p &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;--aggregate-output&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nb"&gt;test&lt;/span&gt;:&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 check:types C:&lt;span class="se"&gt;\W&lt;/span&gt;orkspace&lt;span class="se"&gt;\P&lt;/span&gt;rojects&lt;span class="se"&gt;\p&lt;/span&gt;roject&lt;span class="se"&gt;\p&lt;/span&gt;ackage.json
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;tsc

tsc

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 check:lint C:&lt;span class="se"&gt;\W&lt;/span&gt;orkspace&lt;span class="se"&gt;\P&lt;/span&gt;rojects&lt;span class="se"&gt;\p&lt;/span&gt;roject&lt;span class="se"&gt;\p&lt;/span&gt;ackage.json
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;eslint

eslint

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 &lt;span class="nb"&gt;test&lt;/span&gt;:e2e C:&lt;span class="se"&gt;\W&lt;/span&gt;orkspace&lt;span class="se"&gt;\P&lt;/span&gt;rojects&lt;span class="se"&gt;\p&lt;/span&gt;roject&lt;span class="se"&gt;\p&lt;/span&gt;ackage.json
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;e2e

e2e

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 &lt;span class="nb"&gt;test&lt;/span&gt;:snap C:&lt;span class="se"&gt;\W&lt;/span&gt;orkspace&lt;span class="se"&gt;\P&lt;/span&gt;rojects&lt;span class="se"&gt;\p&lt;/span&gt;roject&lt;span class="se"&gt;\p&lt;/span&gt;ackage.json
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;snap

snap

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 &lt;span class="nb"&gt;test&lt;/span&gt;:unit C:&lt;span class="se"&gt;\W&lt;/span&gt;orkspace&lt;span class="se"&gt;\P&lt;/span&gt;rojects&lt;span class="se"&gt;\p&lt;/span&gt;roject&lt;span class="se"&gt;\p&lt;/span&gt;ackage.json
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;unit

unit

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 build
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; run-s &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; transpile css

build

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 transpile C:&lt;span class="se"&gt;\W&lt;/span&gt;orkspace&lt;span class="se"&gt;\P&lt;/span&gt;rojects&lt;span class="se"&gt;\p&lt;/span&gt;roject&lt;span class="se"&gt;\p&lt;/span&gt;ackage.json
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;transpile

transpile

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 css C:&lt;span class="se"&gt;\W&lt;/span&gt;orkspace&lt;span class="se"&gt;\P&lt;/span&gt;rojects&lt;span class="se"&gt;\p&lt;/span&gt;roject&lt;span class="se"&gt;\p&lt;/span&gt;ackage.json
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;css

css

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 postbuild
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; run-s &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; generate deploy

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 generate C:&lt;span class="se"&gt;\W&lt;/span&gt;orkspace&lt;span class="se"&gt;\P&lt;/span&gt;rojects&lt;span class="se"&gt;\p&lt;/span&gt;roject&lt;span class="se"&gt;\p&lt;/span&gt;ackage.json
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;generate

generate

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; project@0.1.0 deploy C:&lt;span class="se"&gt;\W&lt;/span&gt;orkspace&lt;span class="se"&gt;\P&lt;/span&gt;rojects&lt;span class="se"&gt;\p&lt;/span&gt;roject&lt;span class="se"&gt;\p&lt;/span&gt;ackage.json
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;deploy

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is just one way of doing things. You can go crazy with this kind of stuff, it’s literally a bunch of terminal commands! But for anything more complicated I resort to (and recommend) task runners, bundlers, and toolsets. They allow a lot more flexibility, options, and plugins, and can integrate much better with tools that don’t have CLIs.&lt;/p&gt;

&lt;p&gt;You’ve reached the end! What a journey, amirite? You can find more articles on my &lt;a href="https://iamnabil.netlify.app/blog" rel="noopener noreferrer"&gt;personal blog&lt;/a&gt;. Thanks for reading!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia4.giphy.com%2Fmedia%2FwM4dxCgSptsVWMwFZm%2Fgiphy.gif%3Fcid%3Decf05e47nmaruvnrinj59h1xabp6wtj5ehe83ddx2847nffy%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia4.giphy.com%2Fmedia%2FwM4dxCgSptsVWMwFZm%2Fgiphy.gif%3Fcid%3Decf05e47nmaruvnrinj59h1xabp6wtj5ehe83ddx2847nffy%26rid%3Dgiphy.gif%26ct%3Dg" alt="amiright&amp;lt;br&amp;gt;
gif" width="500" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>I Struggled Without a Mentor, These Tips Helped Me Learn to Code</title>
      <dc:creator>Nabil Tharwat</dc:creator>
      <pubDate>Sun, 09 May 2021 22:45:06 +0000</pubDate>
      <link>https://dev.to/kl13nt/things-that-helped-me-learn-to-code-40je</link>
      <guid>https://dev.to/kl13nt/things-that-helped-me-learn-to-code-40je</guid>
      <description>&lt;p&gt;Learning to code is not a straight path, these tips helped me get better at it. Hopefully by the end of this article you'd have enough of a foundation to require minimal &lt;em&gt;bounce&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Photo by &lt;a href="https://unsplash.com/@cadop?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Mathew Schwartz&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/speed?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks to my friend Omar Abdelaziz for helping out with this article. It means a lot.&lt;/em&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Stick to a single road
&lt;/h2&gt;

&lt;p&gt;You may be tempted to learn every single tool out there, and while it may be possible, is it really worth it? You usually need a single tool and nothing more to get a job done. Learn what you need. Look at the market and stay up to date with its trends. Stick to a roadmap until you need another one. &lt;/p&gt;

&lt;h2&gt;
  
  
  Watch less, build more
&lt;/h2&gt;

&lt;p&gt;Tutorials are fun and dandy until you stop watching them. They give you a feeling of confidence because you're following and succeeding in that. But is following all you need? Will you use tutorials when you're assigned tasks in a real world scenario?&lt;/p&gt;

&lt;p&gt;A serious lot of developers have contacted me about this issue. They follow a lot of tutorials, but fail to even get started on their own. Don't get me wrong, tutorials are good, but too much of anything is bad.&lt;/p&gt;

&lt;p&gt;Focus on building projects on your own. If you're going through a tutorial, build the same project on your own after finishing the tutorial. This time though, don't even look at the tutorial.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/aNqEFrYVnsS52/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/aNqEFrYVnsS52/giphy.gif" alt="Cat slamming on keyboard"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  You need less than you think. (AKA Avoid over-engineering)
&lt;/h2&gt;

&lt;p&gt;Most of the time, you'll most likely think you need a hundred tools to get a job done. This is often a mislead view and is amplified by your lack of knowledge and confidence. &lt;/p&gt;

&lt;p&gt;For example, you may be tempted to use the most complicated tools you know, when instead you could build the same thing with much simpler tools. Over-engineering is bad, avoid it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Build problem solving &amp;amp; debugging skills
&lt;/h2&gt;

&lt;p&gt;Solving problems is the core of computer science and so it's an essential tool to have up your sleeve. It helps you break down complex problems into tiny easy tasks and solve them efficiently bit by bit. Debugging skills help developers pinpoint various types of errors and bugs around an application. They'd make your life much easier. Trust me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't be afraid to make mistakes, and ask questions
&lt;/h2&gt;

&lt;p&gt;Mistakes help us learn, and if you're starting out you'll need to make lots of them. Making mistakes means you're pushing your knowledge boundaries. Pushing your boundaries is a sign of growth. Questions are essential to your growth. Don't be afraid to ask "dumb" questions. They're probably beneficial to you, even if they're "dumb" to more experienced others. &lt;/p&gt;

&lt;h2&gt;
  
  
  Take notes, blog, and teach others
&lt;/h2&gt;

&lt;p&gt;Writing is essential. Whether you're writing notes for yourself, blogging online for others, or teaching  those who seek your help, writing is essential and beneficial. When you're publishing these notes and blog posts you not only help others, but help yourself by deepening your knowledge and receiving feedback.   &lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid FOMO
&lt;/h2&gt;

&lt;p&gt;Fear of missing out (FOMO) is a social anxiety stemming from the belief that others might be having fun while the person experiencing the anxiety is not present. It is characterized by a desire to stay continually connected with what others are doing. &lt;/p&gt;

&lt;p&gt;Learn to deal with it, live with it, and control it. Avoid chasing every shiny new tech. Doing so will save you a ton of time and headache. Chances are very few companies are going to adopt this new tech. And if many do, their systems that already use other tools will be too much of a cost to replace just to use this new tech. Have the confidence to choose what to learn. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o6gb3kkXfLvdKEZs4/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o6gb3kkXfLvdKEZs4/giphy.gif" alt="Let Me In Conan Obrien GIF"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't leave the basics behind
&lt;/h2&gt;

&lt;p&gt;If you've been going through courses/tutorials back-to-back, chances are you've missed a bunch of basics on the way. Go back and learn them thoroughly. You'll thank me later. &lt;/p&gt;

&lt;h2&gt;
  
  
  Be kind to yourself
&lt;/h2&gt;

&lt;p&gt;We're not born with knowledge. You were not born knowing how to code, and neither were your peers. Building foundations takes time and effort. Don't give up, don't push yourself too much, and enjoy the journey. Burnout is real.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't let coding take over other aspects of your life
&lt;/h2&gt;

&lt;p&gt;Coding can be fun and tempting, but sitting all day doing nothing but that is a complete waste of time and energy. Go out, keep in touch with friends, play music, learn to do other things aside from coding. You may as well create content around coding, just don't sink in too deep into coding. &lt;/p&gt;

&lt;h2&gt;
  
  
  Stop waiting for perfect opportunities
&lt;/h2&gt;

&lt;p&gt;If you've built projects, gone through courses, and prepared yourself for the job, you're probably "ready". Stop waiting for the "perfect opportunity". If you are, you're already missing out. Start going out of your comfort zone. Start applying to companies. Do your best, and show it off. It's a good learning experience as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start interacting with the community
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/6G1BhuIWyVEhG/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/6G1BhuIWyVEhG/giphy.gif" alt="Monsters Purple and Brown chewing gum"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Coding is not a singular act nor a one-man effort. It's a community, and you're part of it, like it or not. You may refrain from contributing to it, but why do that when you can instead contribute back to the community that helped you get started? Start interacting with the community already! Here are ways you can do that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow developers blogging about all sorts of things on &lt;a href="https://dev.to"&gt;DEVCommunity&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Stay up to date with everything by visiting &lt;a href="https://news.ycombinator.com/news"&gt;HackerNews&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Follow industry/community leaders on &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Join developer communities online! &lt;a href="https://valarium.netlify.app/"&gt;Valarium&lt;/a&gt; is a discord community I started a couple years back. It's mostly in Arabic but everyone's welcome!&lt;/li&gt;
&lt;li&gt;Join Reddit developer communities! They're rich of content and joy!&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;These tips helped me personally, and I had to bounce around perhaps too much because I didn't know them at the time. Now you don't have to! &lt;/p&gt;

&lt;p&gt;Thanks for reading! You can follow me on &lt;a href="https://twitter.com/kl13nt"&gt;Twitter&lt;/a&gt;, or read more of my content here or on my &lt;a href="https://iamnabil.netlify.app/blog"&gt;blog&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>discuss</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>What's your biggest struggle with Regular Expressions?</title>
      <dc:creator>Nabil Tharwat</dc:creator>
      <pubDate>Wed, 05 May 2021 07:07:37 +0000</pubDate>
      <link>https://dev.to/kl13nt/what-s-your-biggest-struggle-with-regular-expressions-53m5</link>
      <guid>https://dev.to/kl13nt/what-s-your-biggest-struggle-with-regular-expressions-53m5</guid>
      <description>&lt;p&gt;There seems to be a shared struggle when it comes to Regular Expressions. Some suffer readability, some think it's completely useless, others find it difficult to learn. What do you think? What are struggles you face with Regular Expressions? &lt;/p&gt;

&lt;p&gt;For those with no problems with it, what would you give as advice? What helped you grasp them?&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>discuss</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Software Entropy And How To Prevent It</title>
      <dc:creator>Nabil Tharwat</dc:creator>
      <pubDate>Tue, 13 Apr 2021 01:01:19 +0000</pubDate>
      <link>https://dev.to/kl13nt/software-entropy-and-how-to-prevent-it-117m</link>
      <guid>https://dev.to/kl13nt/software-entropy-and-how-to-prevent-it-117m</guid>
      <description>&lt;p&gt;Software decays. Unlike the general belief that code doesn't just "rot away", which makes sense, but software has its own type of decay, known as "software entropy" or "software rot".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://iamnabil.netlify.app/blog/2020-10-31-software-entropy"&gt;هذه المقالة متوفرة باللغة العربية ⁦🇸🇦⁩&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Software Entropy
&lt;/h2&gt;

&lt;p&gt;Software entropy is the process of gradually decreasing the quality of source code until developers can't contribute to it any more. Code becomes obsolete and difficult to maintain, just like anything else. &lt;/p&gt;

&lt;p&gt;This happens due to a number of contributing factors mostly related to the psychology and culture of the developers working on the project. &lt;/p&gt;

&lt;p&gt;Question remains; how does it decay and how can we prevent it?&lt;/p&gt;

&lt;h2&gt;
  
  
  Broken Windows
&lt;/h2&gt;

&lt;p&gt;To understand how software rots we need to take a look at the Broken Windows theorem. The Broken Windows theorem is a theorem in crime science which states that crime is the result of disorder found in human societies.&lt;/p&gt;

&lt;p&gt;Given a car left on a street for weeks, passers-bys won't care about it. It'll remain as is. Until a window is broken. In the original experiment, they left a car on a street untouched for weeks. But when they broke a window, the car was dismantled in &lt;em&gt;hours&lt;/em&gt;.  &lt;/p&gt;

&lt;p&gt;By the same rule, a broken window in a building left unfixed will be followed with general disorder. Which is why NYC started cracking down on the tiniest things, in order to prevent broken windows. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;According to a 2001 study of crime trends in New York City by Kelling and William Sousa, rates of both petty and serious crime fell significantly after the aforementioned policies were implemented. Furthermore, crime continued to decline for the following ten years. Such declines suggested that policies based on the Broken Windows Theory were effective.&lt;/p&gt;

&lt;p&gt;— Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Broken Windows in Software
&lt;/h2&gt;

&lt;p&gt;Wrong management decisions that developers have to live with, bad designs, or poor code are all examples of broken windows. &lt;/p&gt;

&lt;p&gt;Delaying fixing these broken windows to later times will only contribute more to software entropy. We all know that there won't 'another time' or 'later' because you'll be all too busy with new features or critical bugs that will leave even more broken windows.&lt;/p&gt;

&lt;p&gt;Failing to fix those windows as soon as possible will leave you in the mentality that "all code is trash, I'll just get this over with". This mentality will greatly accelerate the entropy. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to Avoid Software Entropy (or Minimize It)
&lt;/h2&gt;

&lt;p&gt;Given all of this, one must simply avoid breaking windows. If you want your codebase to last then you must fix all windows as soon as they're found. Introduce the concept of refactoring to your boss. Temporarily disable features. Label others as "unstable". &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not leave a broken window in your production code&lt;/strong&gt;. This will keep the mentality of care and attention to detail among the developers working on the code, and will eventually lead to easier feature addition, maintenance, and testing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You don’t want to be the first one to make a mess.&lt;/p&gt;

&lt;p&gt;— The Pragmatic Programmer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you liked this article don't forget to love this post! If you found any issues with this article or have questions don't hesitate to comment them! Thanks for reading! You can follow me on &lt;a href="https://twitter.com/kl13nt"&gt;Twitter&lt;/a&gt;, or read more of my content here or on my personal &lt;a href="https://iamnabil.netlify.app/blog"&gt;blog&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>software</category>
      <category>development</category>
      <category>maintenance</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Leaking and Non-Leaking Arrow Functions in JavaScript</title>
      <dc:creator>Nabil Tharwat</dc:creator>
      <pubDate>Sat, 03 Apr 2021 07:51:20 +0000</pubDate>
      <link>https://dev.to/kl13nt/leaking-and-non-leaking-arrow-functions-4g9d</link>
      <guid>https://dev.to/kl13nt/leaking-and-non-leaking-arrow-functions-4g9d</guid>
      <description>&lt;p&gt;When writing arrow functions that shouldn't return any value you may be tempted to return an &lt;code&gt;||&lt;/code&gt; operation such as:&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="cm"&gt;/* Leaking Arrow Function */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrowThatShouldntReturn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;someOtherFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may work if &lt;code&gt;someOtherFunction&lt;/code&gt; returns a falsy value, but won't work for truthy values.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Void Operator
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;void&lt;/code&gt; unary operator evaluates the given &lt;em&gt;expression&lt;/em&gt; and then returns &lt;em&gt;undefined&lt;/em&gt;. You'll see this operator used all over the React codebase to create non-leaking arrow functions! &lt;/p&gt;

&lt;p&gt;To use it we can define our functions as:&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="cm"&gt;/* Non-leaking Arrow Function */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrowThatShouldntReturn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;someOtherFunction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// returns undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or when we don't wish to do anything yet:&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="cm"&gt;/* Non-leaking Arrow Function */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrowThatShouldntReturn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// returns undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first method will evaluate &lt;code&gt;someOtherFunction()&lt;/code&gt; and return undefined regardless of the returned value. The second method is equivalent to &lt;code&gt;void undefined&lt;/code&gt; which evaluates &lt;code&gt;undefined&lt;/code&gt; and returns &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Are there other use cases? Yes. &lt;/p&gt;

&lt;h2&gt;
  
  
  Before ES6
&lt;/h2&gt;

&lt;p&gt;In old times you used to define variables using &lt;code&gt;var&lt;/code&gt;. This immediately adds the variable you're declaring to the global object. It also pretty much didn't have restrictions, so you could just &lt;code&gt;var undefined = true&lt;/code&gt; and it'd work. This is one of the reasons &lt;code&gt;void 0&lt;/code&gt; used to be the preferred method. There's even an ESLint rule for it! It's not necessary in strict environments though.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTML
&lt;/h2&gt;

&lt;p&gt;You probably also met the void operator in anchor tags! Ever met this bad boy?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"javascript:void(0)"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yup, that's it. We used it to pretty much create links that preventDefault.&lt;/p&gt;

&lt;h2&gt;
  
  
  IIFE
&lt;/h2&gt;

&lt;p&gt;You can use it with IIFEs too!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})();&lt;/span&gt; &lt;span class="c1"&gt;// returns true&lt;/span&gt;

&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}();&lt;/span&gt; &lt;span class="c1"&gt;// returns undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;If you liked this article don't forget to love this post! If you found any issues with this article or have questions don't hesitate to comment them! Thanks for reading! You can follow me on &lt;a href="https://twitter.com/kl13nt"&gt;Twitter&lt;/a&gt;, or read more of my content here or on my personal &lt;a href="https://iamnabil.netlify.app/blog"&gt;blog&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>arrows</category>
      <category>functional</category>
    </item>
    <item>
      <title>Deep Dive Beyond Operator Overloading in JavaScript</title>
      <dc:creator>Nabil Tharwat</dc:creator>
      <pubDate>Fri, 02 Apr 2021 17:59:10 +0000</pubDate>
      <link>https://dev.to/kl13nt/deep-dive-beyond-operator-overloading-in-javascript-2a48</link>
      <guid>https://dev.to/kl13nt/deep-dive-beyond-operator-overloading-in-javascript-2a48</guid>
      <description>&lt;p&gt;This is a deep dive into the inner workings of JavaScript engines and how they handle arithmetic operations on primitive and complex objects. We'll go through ordinary and exotic objects, the standard semantics, references, abstract operations, internal methods, and finally how to implement objects that benefit from arithmetic operators.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you haven't read my previous articles make sure to! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  AdditiveExpressions
&lt;/h2&gt;

&lt;p&gt;Before we start, let me note that JavaScript doesn't support operator overloading in the general sense like C++ does for example, but it provides deep workings that allow us to define special methods that are used in arithmetic operations, like Java's &lt;code&gt;toString&lt;/code&gt;!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's start with this simple arithmetic addition &lt;code&gt;AdditiveExpression : AdditiveExpression + MultiplicativeExpression&lt;/code&gt;. The standard defines the steps for an addition operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Let lref be the result of evaluating AdditiveExpression.
2.  Let lval be ? GetValue(lref).
3.  Let rref be the result of evaluating MultiplicativeExpression.
4.  Let rval be ? GetValue(rref).
5.  Let lprim be ? ToPrimitive(lval).
6.  Let rprim be ? ToPrimitive(rval).
7.  If Type(lprim) is String or Type(rprim) is String, then
  a.  Let lstr be ? ToString(lprim).
  b.  Let rstr be ? ToString(rprim).
  c.  Return the string-concatenation of lstr and rstr.
8.  Let lnum be ? ToNumeric(lprim).
9.  Let rnum be ? ToNumeric(rprim).
10.  If Type(lnum) is different from Type(rnum), throw a TypeError exception.
11.  Let T be Type(lnum).
12.  Return T::add(lnum, rnum).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty daunting right? Let's dumb it down! &lt;/p&gt;

&lt;h2&gt;
  
  
  Semantics
&lt;/h2&gt;

&lt;p&gt;The standard defines any additive operation as the result of two operands, &lt;code&gt;l&lt;/code&gt; and &lt;code&gt;r&lt;/code&gt;, being &lt;code&gt;left&lt;/code&gt;, and &lt;code&gt;right&lt;/code&gt; respectively. It also attaches other semantic descriptors like &lt;code&gt;ref&lt;/code&gt;, &lt;code&gt;val&lt;/code&gt;, &lt;code&gt;prim&lt;/code&gt;, &lt;code&gt;str&lt;/code&gt;, and &lt;code&gt;num&lt;/code&gt; to refer to &lt;code&gt;Reference&lt;/code&gt;, &lt;code&gt;Value&lt;/code&gt;, &lt;code&gt;Primitive&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt;, and &lt;code&gt;Numeric&lt;/code&gt; values respectively. &lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript Engine References
&lt;/h2&gt;

&lt;p&gt;The standard operates using &lt;code&gt;References&lt;/code&gt;. References are special objects/variables that reference other variables in memory. This is to save resources so instead of copying a variable every time the engine needs it, it can just reference it, which is more memory and performance efficient. This &lt;code&gt;Reference&lt;/code&gt; type can be &lt;em&gt;dereferenced&lt;/em&gt; to get the actual value by using the &lt;code&gt;GetValue(V)&lt;/code&gt; method. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;GetValue(V)&lt;/code&gt; method itself has an algorithm of its own. I've dumbed it down without going too deep as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. If V is not a reference, return it.
2. If V is invalid reference (as in using a variable that doesn't exist), throw ReferenceError.
3. Else return value.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exotic and Ordinary Objects
&lt;/h2&gt;

&lt;p&gt;In JavaScript, an exotic object is an object that contains behaviour that goes above and beyond the language itself. These objects require internal methods that are enclosed in double square brackets &lt;code&gt;[[ ]]&lt;/code&gt;. Think Array, Proxy, Arguments, and Module for example. The JavaScript engine does a lot of magic using internal methods to work with those objects. You cannot completely replicate this magic using just JavaScript.&lt;/p&gt;

&lt;p&gt;Ordinary objects are normal objects that you can build using JavaScript code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Primitives and Abstract Operations
&lt;/h2&gt;

&lt;p&gt;Primitives in JavaScript are the most basic values that can be represented in the engine directly. This includes booleans, strings, numbers, and others. The standard defines primitive helpers called Abstract Operations. These helper functions allow the engine to directly manipulate values such as add two numbers, subtract, and others. Each primitive type has its own set of helpers.&lt;/p&gt;

&lt;p&gt;Now that we have a basic understanding of how things in the EcmaScript world work let's dive into addition.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Let lref be the result of evaluating AdditiveExpression.
2.  Let lval be ? GetValue(lref).
3.  Let rref be the result of evaluating MultiplicativeExpression.
4.  Let rval be ? GetValue(rref).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Up until the forth step all we do is just &lt;em&gt;dereference&lt;/em&gt; the references we have. Now we have two values, &lt;code&gt;lval&lt;/code&gt; and &lt;code&gt;rval&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;5.  Let lprim be ? ToPrimitive(lval).
6.  Let rprim be ? ToPrimitive(rval).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We now turn these values into primitives so we can operate on them easily on the engine level. The abstract operation &lt;code&gt;ToPrimitive&lt;/code&gt; converts its input argument to a non-Object type. It has a somewhat long algorithm. &lt;/p&gt;

&lt;h2&gt;
  
  
  ToPrimitive and @@toPrimitive
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ToPrimitive&lt;/code&gt; takes two parameters, the value you wish to turn into a primitive, and a &lt;em&gt;Hint&lt;/em&gt; &lt;code&gt;PreferredType&lt;/code&gt;. This &lt;em&gt;Hint&lt;/em&gt; helps &lt;code&gt;ToPrimitive&lt;/code&gt; determine the Target type. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When ToPrimitive is called with no hint, then it generally behaves as if the hint were Number. However, objects may over-ride this behaviour by defining a @@toPrimitive method. Of the objects defined in this specification only Date objects (see 20.4.4.45) and Symbol objects (see19.4.3.5) over-ride the default ToPrimitive behaviour. Date objects treat no hint as if the hint were String.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Meaning that if Hint is not present the function falls back to "number" for all objects except &lt;code&gt;Date&lt;/code&gt;, which defines &lt;code&gt;Hint&lt;/code&gt; as "string". This is one of the reasons Date is an exotic object. Date also defines more internal methods to help with serializing it to JSON.&lt;/p&gt;

&lt;p&gt;Ignoring unimportant steps, the &lt;code&gt;ToPrimitive&lt;/code&gt; algorithm is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2. If Type(input) is Object, then
  d.  Let exoticToPrim be ? GetMethod(input, @@toPrimitive).
  e.  If exoticToPrim is not undefined, then
    i.  Let result be ? Call(exoticToPrim, input, « hint »).
    ii.  If Type(result) is not Object, return result.
    iii. Else throw a TypeError exception.
  f.  If hint is "default", set hint to "number".
  g.  Return ? OrdinaryToPrimitive(input, hint).
3.  Return input
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key here is &lt;code&gt;@@toPrimitive&lt;/code&gt; at 2.d. Remember what we said about Ordinary and Exotic objects? &lt;code&gt;@@ToPrimitive&lt;/code&gt; is an internal method defined only on some exotic objects that control how the object is turned into a primitive. If this method is defined on the object we're working with (Date and Symbol), it'll be called and the result will be returned. Otherwise we'll resort to &lt;code&gt;OrdinaryToPrimitive&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  OrdinaryToPrimitive
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;OrdinaryToPrimtive&lt;/code&gt; bears the responsibility of turning ordinary objects into primitives. We're getting close now! It does the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;3.  If hint is "string", then
  a.  Let methodNames be « "toString", "valueOf" ».
4.  Else,
  a.  Let methodNames be « "valueOf", "toString" ».
5.  For each name in methodNames in List order, do
  a.  Let method be ? Get(O, name).
  b.  If IsCallable(method) is true, then
    i.  Let result be ? Call(method, O).
    ii.  If Type(result) is not Object, return result.
6.  Throw a TypeError exception.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We define a list of method names to call in order. This list can either be &lt;code&gt;[toString, valueOf]&lt;/code&gt; if the hint is "string" (as in string concatenation), or &lt;code&gt;[valueOf, toString]&lt;/code&gt; if hint is "number" (as in number addition). We then execute this list and return the value of whichever method we find first, in the same order.&lt;/p&gt;

&lt;p&gt;We've now called &lt;code&gt;ToPrimitive&lt;/code&gt; on both operands and have two primitives to add together. The algorithm for &lt;code&gt;AdditiveExpression&lt;/code&gt; continues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7.  If Type(lprim) is String or Type(rprim) is String, then 
  a.  Let lstr be ? ToString(lprim).
  b.  Let rstr be ? ToString(rprim).
  c.  Return the string-concatenation of lstr and rstr.
8.  Let lnum be ? ToNumeric(lprim).
9.  Let rnum be ? ToNumeric(rprim).
10.  If Type(lnum) is different from Type(rnum), throw a TypeError exception.
11.  Let T be Type(lnum).
12.  Return T::add(lnum, rnum)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We see that if any of the primitives is a string then we convert both of them to strings and concatenate them. Otherwise we convert them to numbers and use the Abstract Operations defined on Number primitives, specifically &lt;code&gt;add(lnum, rnum)&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now we have a pretty good understanding of how addition works! But we're talking about operator overloading! Remember what I said about &lt;code&gt;OrdinaryToPrimitive&lt;/code&gt;? &lt;code&gt;OrdinaryToPrimitive&lt;/code&gt; looks for toString and valueOf on objects depending on the operation. Which means we can just define them on our custom objects and use arithmetic operators with them!&lt;/p&gt;

&lt;h2&gt;
  
  
  Operator Overloading Custom Objects
&lt;/h2&gt;

&lt;p&gt;Let's start by defining an object &lt;code&gt;A&lt;/code&gt; that doesn't implement these methods:&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;A&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;5&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 we try to do arithmetic operations on this object we'll get strings all the time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;// [object Object]5&lt;/span&gt;
&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;// NaN&lt;/span&gt;
&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;// NaN&lt;/span&gt;
&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;// NaN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's implement these methods on this object:&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;A&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="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;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;String&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;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;Arithmetic operations should now work flawlessly!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;// 10&lt;/span&gt;
&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;// 25&lt;/span&gt;
&lt;span class="nx"&gt;A&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now we can not only just define some methods to use operator overload on our objects, but we also deeply understand how JavaScript engines do it!&lt;/p&gt;

&lt;p&gt;If you liked this article don't forget to love this post! If you found any issues with this article or have questions don't hesitate to comment them! Thanks for reading! You can follow me on &lt;a href="https://twitter.com/kl13nt"&gt;Twitter&lt;/a&gt;, or read more of my content here or on my personal &lt;a href="https://iamnabil.netlify.app/blog"&gt;blog&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>operations</category>
      <category>overloading</category>
      <category>standard</category>
    </item>
    <item>
      <title>How I Get Things Done as a Student-Developer, and How You Can Too</title>
      <dc:creator>Nabil Tharwat</dc:creator>
      <pubDate>Mon, 15 Mar 2021 06:28:47 +0000</pubDate>
      <link>https://dev.to/kl13nt/how-i-get-things-done-as-a-student-developer-and-how-you-can-too-581d</link>
      <guid>https://dev.to/kl13nt/how-i-get-things-done-as-a-student-developer-and-how-you-can-too-581d</guid>
      <description>&lt;p&gt;Being productive as a student and a developer is a hard task. Hopefully by the end of this you'll be a little bit more productive. I'll be sharing my experience with time auditing, goal setting, instant gratification, negative influences, and managing a to-do list. &lt;/p&gt;

&lt;p&gt;Don't forget to share your time management habits and how you plan your time in the comments! 👀&lt;/p&gt;

&lt;h2&gt;
  
  
  What I used to do
&lt;/h2&gt;

&lt;p&gt;What I used to do in the past, which failed miserably, is setting up a strict schedule based on hours, a "from-to" type of schedule. I eventually ran out of time before I could finish the tasks at hand, and would always be frustrated with having to update and maintain it. It was a lot of effort and led to less productivity.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before you dive into applying any time-management methodology, give yourself time to try it out. There are no silver bullets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Time auditing
&lt;/h2&gt;

&lt;p&gt;How we spend time is often overlooked. How can you improve your productivity if you don't know how you spend your time in the first place? Research is the foundation. Tracking your habits can give you an idea of what you need to work on and improve, and can guarantee better productivity.&lt;/p&gt;

&lt;p&gt;One of the very first steps is to measure exactly how you spend your time. How long transportation takes, studying, being outside, playing video games, scrolling through Instagram, meals, and even breaks.&lt;/p&gt;

&lt;p&gt;To track your time-spending habits a simple notebook can do. There are a number of free and premium time-tracking tools out there that all do a great job. Do it for a few days, then check how you spend time and decide how you can improve.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Never categorise what you do as &lt;em&gt;unimportant&lt;/em&gt; during the first few days. Add everything to your audit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Fear as a friend
&lt;/h2&gt;

&lt;p&gt;How many times have you procrastinated but eventually got things done because of fear? Fear of failing a course, fear of ruining a relationship, fear of missing out, etc. There's always something we're afraid of that pushes us to being more productive. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The reason why we're not as productive as we wish to be is because we fail to act; which is the result of one’s complacency in the current moment. One must leverage &lt;em&gt;fear&lt;/em&gt; by ensuring that the stakes are too high for one to stay &lt;em&gt;perpetually complacent&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fear, in itself, is a natural, powerful, and primitive human emotion. It alerts us to the presence of danger or the threat of harm, whether that danger is physical or psychological. If we exploit our fear of the future and use it to our advantage we'll have a solid foundation. &lt;/p&gt;

&lt;p&gt;This is what I had in mind, and is what I did. I listed the things that I was most afraid of in the future. Things like finding a job, my social anxiety when meeting new people, etc. I then set goals based on these fears and my dreams. These goals gave me purpose, a way to measure my progress, and had high-enough stakes to keep me on track.&lt;/p&gt;

&lt;h2&gt;
  
  
  Avoid instant gratification
&lt;/h2&gt;

&lt;p&gt;Instant gratification is the desire to experience pleasure or fulfilment without delay or deferment. Basically, it's when you want it; and you want it now.&lt;/p&gt;

&lt;p&gt;Ever woke up and went straight to your phone? Do you check your phone every few minutes at work? Do you keep your phone in sight when sitting with friends or in a meeting? Stop.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Engagement with our cell phones releases dopamine. That's why when you get a text, it feels good. It's why we count the likes. It's highly addictive.&lt;/p&gt;

&lt;p&gt;&lt;cite&gt;— Simon Sinek&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With instant gratification on board, we look beyond what we truly &lt;em&gt;want&lt;/em&gt;. We choose &lt;em&gt;not&lt;/em&gt; to do the things that help us reach long-term goals — such as job satisfaction or relationships — because they're long-term. They're boring, they take time, and we're &lt;em&gt;impatient&lt;/em&gt;. We're &lt;em&gt;reactive&lt;/em&gt;. Which is a terrible combination.&lt;/p&gt;

&lt;p&gt;This is why we need short-term milestones. Goals can span years, but milestones are short-lived, and grant us enough satisfaction in the present moment that helps us avoid unhealthy addictive behaviour. &lt;/p&gt;

&lt;p&gt;If you wait till the end of a season of your favourite TV series just to binge through the whole thing at once, stop doing that. Watch every episode when it comes out, and wait for new episodes. Work on yourself and develop your skills to reach job fulfilment. Insignificant changes add up. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Learn the art of being patient, you'll thank yourself later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The classic: creating a to-do list
&lt;/h2&gt;

&lt;p&gt;A to-do list will allow you to feel accomplished by showing you the tasks you completed, and a time-audit will tell you how long each task took. This combination will allow incremental, consistent improvement. &lt;/p&gt;

&lt;p&gt;Now here are some hacks I use around my own to-do list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Place the most boring tasks first, the most important second, and the most fun after.&lt;/strong&gt; This will help you reach that "ah, finally, something fun" after a long day of boring stuff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use atomic tasks.&lt;/strong&gt; Atomic tasks are tasks that take less than a few minutes to complete. For you, they may be shorter, or longer. We can usually keep ourselves focused for 30 minutes tops. Split long tasks into atomic tasks — you'll feel more accomplished.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Order related tasks together.&lt;/strong&gt; This helps you remain focused.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't abandon tasks.&lt;/strong&gt; If you couldn't finish everything today, don't feel bad! Just move it to the next day.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get help.&lt;/strong&gt; More hands on the same tasks means less time. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid train cars.&lt;/strong&gt; Leave a buffer time between tasks. You may want a bathroom break, a quick snack, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep your mind busy with only 1 task.&lt;/strong&gt; This helps you focus, and eliminates half-work and overthinking. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less is more&lt;/strong&gt; The more time you spend on unimportant tasks, the less you spend on the things that truly matter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make a food schedule.&lt;/strong&gt; This will help you overview how much time will be needed to buy ingredients and prepare your daily meals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't go back to completed tasks.&lt;/strong&gt; Avoid perfectionism. A task done is a task done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The 15 minute rule.&lt;/strong&gt; Have 15 minutes of break at least once for every 2 hours of work.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;One of the very worst uses of time is to do something very well that need not be done at all.&lt;/p&gt;

&lt;p&gt;&lt;cite&gt;— Brian Tracy, Eat That Frog&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Discipline
&lt;/h2&gt;

&lt;p&gt;Discipline is the difference between the greats and the average. Take more responsibility of yourself. Set a morning routine. Plan ahead, and stick to plans. &lt;strong&gt;Hold &lt;em&gt;yourself&lt;/em&gt; accountable&lt;/strong&gt;. And tell no one about it. The only way people should know about your progress is through results. Show discipline. Show results. Never break your discipline.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Discipline is saying "No" when those around you choose to be average. Life doesn't give you what you &lt;strong&gt;want&lt;/strong&gt;, it gives you what you &lt;strong&gt;deserve&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;cite&gt;— Chris Ross&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Choose a suitable routine
&lt;/h2&gt;

&lt;p&gt;My morning routine consists of waking up at 05:00 or earlier, taking a quick shower and meditating. I prepare my breakfast, and enjoy it in the calmness of the early morning — it's really calm then. I then check my to-do list for any left-overs from last night, fix it up and sort my day's tasks, and decide what I want to eat during that day. And with that, my day starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  It's finally the weekend
&lt;/h2&gt;

&lt;p&gt;The weekend is a whole different matter. No to-do lists, no auditing. Discipline is tiring, remaining focused all the time is tiring. The weekend helps you balance that. Remain faithful to your goals and your discipline, but breaks are necessary to avoid overwork and burnout. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Avoid the cult of productivity.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't let your extremely-productive self take control, and don't let your extremely-procrastinating self take control either. &lt;em&gt;Burnout&lt;/em&gt; is a thing that you want to avoid &lt;strong&gt;at all costs&lt;/strong&gt;. Accept that it's &lt;em&gt;more terrifying to fail than it is to succeed&lt;/em&gt;, and take control of your life.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final notes
&lt;/h2&gt;

&lt;p&gt;I just want to say that there will always be a challenge. Life will never be a straight line. There will always be a mountain to climb. You'll fall. You'll get bashed in the face with the world's cruellest hammer. And just like you worked hard, you'll fall hard.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’ve never understood that concept, having something to fall back on. If I’m going to fall, I don’t want to fall back on anything, except my faith. I want to fall… forward. At least that way I’ll see what I’m about to hit.&lt;/p&gt;

&lt;p&gt;&lt;cite&gt;— Denzel Washington&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thanks for reading! You can follow me on &lt;a href="https://twitter.com/kl13nt"&gt;Twitter&lt;/a&gt;, or read more of my content here or on my &lt;a href="https://iamnabil.netlify.app/blog"&gt;blog&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>career</category>
      <category>lifestyle</category>
      <category>healthydebate</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Protecting Website Copyrighted Content</title>
      <dc:creator>Nabil Tharwat</dc:creator>
      <pubDate>Tue, 09 Mar 2021 03:30:22 +0000</pubDate>
      <link>https://dev.to/kl13nt/how-to-protect-website-copyrighted-content-pck</link>
      <guid>https://dev.to/kl13nt/how-to-protect-website-copyrighted-content-pck</guid>
      <description>&lt;p&gt;Protecting your website's copyrighted content is tricky. Let's see how it's done! 👀&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover by &lt;a href="https://unsplash.com/@jeremythomasphoto?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Jeremy Thomas&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/space?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;. This article is available in Arabic on my &lt;a href="https://iamnabil.netlify.app/tutorials/2021-03-08-drm-website-content-protection"&gt;blog&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Bottom line is no matter how many scripts you load, events you prevent, authentication layers you add, users will always be able to redistribute your content online. Our goal is to reduce the number of users who can achieve this to a percentage we can handle manually. &lt;/p&gt;

&lt;p&gt;In this article, I'll be talking about &lt;em&gt;DRM&lt;/em&gt; and &lt;em&gt;Forensic Watermarking&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Digital Rights Management (DRM)
&lt;/h1&gt;

&lt;p&gt;DRM tools are a set of access control technologies for restricting the use of proprietary hardware and copyrighted work. The set of tools we'll look at today relate only to the web development side of it. &lt;/p&gt;

&lt;p&gt;DRM encryption is the encryption of content such as videos and images to prevent others from using it. This is two-way encryption. Given a key, you can decrypt the contents of said content. &lt;/p&gt;

&lt;p&gt;The usual flow is you begin by registering a user, verifying their identity using some payment method, and then granting them access to the encrypted content and the key for that content, thus granting them a license to access that content. The browser then proceeds to decrypt the content on the user's machine to output a valid representation that can be displayed on a webpage. &lt;/p&gt;

&lt;p&gt;Currently, the &lt;em&gt;Encrypted Media Extensions API&lt;/em&gt; handles that. For it to work you need to have a browser that supports the EME API, a packaging service to encrypt your content, a DRM key generation service, and a &lt;em&gt;Content Decryption Module&lt;/em&gt; (CDM) for client-side decryption. The EME API allows you to interact and define CDMs for your application.&lt;/p&gt;

&lt;p&gt;This procedure is used by Netflix, Spotify, and others. But there's a twist. Each browser supports a specific DRM service. So you need to make a copy of the original content for each service the browsers that you support can work with. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In general, Widevine is supported by Firefox, Chrome, and Opera, PlayReady is supported by IE/Edge, and FairPlay is supported by Safari.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's another twist! Once a user has access to your DRM content, they'll be able to redistribute it! Recall that DRM decryption takes place on the user' machine, and so with the proper software they'll be able to output a simple decrypted file to redistribute. This is where Forensic Watermarking comes into the picture! &lt;/p&gt;

&lt;h1&gt;
  
  
  Forensic Watermarking
&lt;/h1&gt;

&lt;p&gt;Watermarking is the process of adding some information to media. Things like logos, source distributor, etc. But how can something like this benefit us in preventing the redistribution of our content? &lt;/p&gt;

&lt;p&gt;Forensic Watermarking is the process of embedding special hidden information about a user in the media itself. Most forensic  techniques use footprints left on media to predict the history of the media. &lt;/p&gt;

&lt;p&gt;This can be used to detect the user who redistributed a video on the web. Think of it like inspecting a website. You can inspect the media to check the username of the user who redistributed that media, and then decide what to do. This includes legal action.&lt;/p&gt;

&lt;p&gt;But there's another twist. Media degrades after operating on it a few times. This can damage the embedded information over time. Users can just record their screen in the case of video, their system's audio output in the case of audio, etc. You won't be able to detect that. &lt;/p&gt;

&lt;p&gt;The point of all of this is to reduce the ability of a user to redistribute the content, and this &lt;em&gt;will&lt;/em&gt; successfully reduce the percentage of users who have the hardware and software to accomplish this, limiting the number of users to a handful you can manually deal with. &lt;/p&gt;

&lt;p&gt;This is more of a forensics thing, and I'm a frontend developer. Hopefully I made it clear enough! If you spot any errors please point it out! 👀&lt;/p&gt;

&lt;p&gt;Thanks for reading! You can follow me on &lt;a href="https://twitter.com/kl13nt"&gt;Twitter&lt;/a&gt;, or read more of my content here or on my &lt;a href="https://iamnabil.netlify.app/blog"&gt;blog&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://w3c.github.io/encrypted-media"&gt;W3C Encrypted Media Extensions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/pallycon/how-netflix-protects-contents-part-1-a40508ed0001"&gt;How Netflix Protect Their Content&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Encrypted_Media_Extensions_API"&gt;Encrypted Media Extensions API MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Plugins/Flash_to_HTML5/Video/DRM_and_authentication"&gt;DRM and Authentication MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Digital_rights_management"&gt;DRM (Wikipedia)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>drm</category>
    </item>
  </channel>
</rss>
