<?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: Nate Clark</title>
    <description>The latest articles on DEV Community by Nate Clark (@n8io).</description>
    <link>https://dev.to/n8io</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%2F330757%2F5a4eefb7-968a-4337-855a-1c2759813d19.png</url>
      <title>DEV Community: Nate Clark</title>
      <link>https://dev.to/n8io</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/n8io"/>
    <language>en</language>
    <item>
      <title>Parting is Such Sweet Sorrow</title>
      <dc:creator>Nate Clark</dc:creator>
      <pubDate>Thu, 01 Apr 2021 13:03:08 +0000</pubDate>
      <link>https://dev.to/n8io/parting-is-such-sweet-sorrow-59po</link>
      <guid>https://dev.to/n8io/parting-is-such-sweet-sorrow-59po</guid>
      <description>&lt;p&gt;This week I gave notice to my work family at &lt;a href="https://www.codingzeal.com"&gt;ZEAL&lt;/a&gt; 😢. I am of equal parts deeply indebted, saddened, and excited to be moving on to another chapter of my career. What a great run these past three short years have been.&lt;/p&gt;

&lt;p&gt;Today I reflect on all the clients I have worked with. The vast diversity of work, team compositions, and seemingly impossible projects. And to this day I can't believe I was part of a team that successfully brought to market a &lt;a href="https://www.beckman.com/air-particle-counters/met-one-3400-plus"&gt;clean room toaster&lt;/a&gt;. We've helped countless teams achieve their (sometimes lofty) goals all while making the journey pleasurable for everyone involved. That is what you can expect from ZEAL. It is our signature move. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MNl0-JvS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/471tlgy549n6pc7k63mg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MNl0-JvS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/471tlgy549n6pc7k63mg.gif" alt="Signature move"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I look back at all the good times we had and only now realize how precious they really were. The balloon animal workshop (this post's header image), the team competitions, the jet boat, the dinner murder mystery to name a few. The unconditional excitement from &lt;a href="https://www.linkedin.com/in/treveryarrish"&gt;Trever&lt;/a&gt; every standup. The inescapable joy of &lt;a href="https://www.linkedin.com/in/adamcuppy"&gt;Adam&lt;/a&gt;. The countless swag and care packages. The always on point Dad jokes, the welcomed trolling, and knowing everyone was there to help each other. Not only to be better at our trade, but to become better people. &lt;/p&gt;

&lt;p&gt;I will miss all of that dearly when I power down my company laptop that one last time. Thank you all for an awesome ride.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kgKDJrLI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5txgrtqg44lqcbmfie3a.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kgKDJrLI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5txgrtqg44lqcbmfie3a.gif" alt="Signing off"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sincerely, &lt;br&gt;
— Nate&lt;/p&gt;

&lt;p&gt;PS. If you're looking for a great place to work, &lt;a href="https://www.codingzeal.com/hiring"&gt;ZEAL is hiring&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>career</category>
      <category>hiring</category>
      <category>resume</category>
      <category>culture</category>
    </item>
    <item>
      <title>Cave Drawings: Emojis and Commit Messages</title>
      <dc:creator>Nate Clark</dc:creator>
      <pubDate>Tue, 06 Oct 2020 17:22:33 +0000</pubDate>
      <link>https://dev.to/n8io/cave-drawings-emojis-and-commit-messages-39ig</link>
      <guid>https://dev.to/n8io/cave-drawings-emojis-and-commit-messages-39ig</guid>
      <description>&lt;p&gt;Years ago a friend of mine refused to use emojis in text messages because, in his words, &lt;em&gt;"emojis relegate us to being cavemen"&lt;/em&gt;. Like any good friend I respectfully disagreed and sent the next several text messages composed entirely of emojis. He was not amused. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/eJLXXjN1ZGS4g/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/eJLXXjN1ZGS4g/source.gif" alt="Caveman speaking with the caption, "&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🖼️ A Picture is Worth a Thousand Words
&lt;/h2&gt;

&lt;p&gt;The oldest forms of recorded history that we've discovered are some &lt;a href="https://simple.wikipedia.org/wiki/Cave_painting" rel="noopener noreferrer"&gt;cave drawings from ~30,000 BC&lt;/a&gt;. To this day they we can observe an ancient buffalo hunt. I like to imagine some hunters huddled around the fire, enjoying the spoils of their hunt, and bragging to each other about how epic the day was. &lt;/p&gt;

&lt;p&gt;The drawings provided a medium for them to share their experience with others without having to retell it.&lt;/p&gt;

&lt;p&gt;In comparison, the &lt;a href="https://en.wikipedia.org/wiki/List_of_languages_by_first_written_accounts" rel="noopener noreferrer"&gt;oldest examples of written language&lt;/a&gt; were found to be from ~25,000 years later. &lt;/p&gt;

&lt;p&gt;Let that soak in for a second. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pictographs were the de facto method of recording history for 25,000 years.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📩 Commit Clarity
&lt;/h2&gt;

&lt;p&gt;This got my developer brain thinking...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why can't we use emojis to convey meaning in our commit messages?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To my anti-emoji friend's point, emojis are indeed modern day cave drawings. They illustrate a common meaning without the overhead of having the reader parse written language. I mean it's been baked into our DNA for millennia. Don't believe me? Science says we &lt;a href="https://www.emailaudience.com/research-picture-worth-1000-words-marketing" rel="noopener noreferrer"&gt;recognize pictures much faster than words&lt;/a&gt;. So why not embrace the shorthand?&lt;/p&gt;

&lt;h2&gt;
  
  
  🚚 Emoji Commits
&lt;/h2&gt;

&lt;p&gt;Thankfully, I am not the the first person to come to this conclusion. An awesome open source developer by the name of &lt;a href="https://carloscuesta.me" rel="noopener noreferrer"&gt;Carlos Cuesta&lt;/a&gt; put together a &lt;a href="https://gitmoji.carloscuesta.me" rel="noopener noreferrer"&gt;cli tool and visual guide&lt;/a&gt; to help match up your commit subject to an emoji. I use his guide almost daily.&lt;/p&gt;

&lt;h3&gt;
  
  
  🏹 An Example: The Hunt
&lt;/h3&gt;

&lt;p&gt;If those cavemen were to write their cave drawing commits today they may have looked like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9r8s6uy3xmjffb4toszo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9r8s6uy3xmjffb4toszo.gif" alt="Commit messages as if cavemen authored them to describe their buffalo hunt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look at those beautiful emojis 💖. Here we're showing the implicit meaning of each emoji for easy comparison. Over time you'll gain a familiarity with them, especially if you use them consistently (&lt;a href="https://gitmoji.carloscuesta.me" rel="noopener noreferrer"&gt;see guide&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  😤 The Haters
&lt;/h3&gt;

&lt;p&gt;You will run into developers and/or team leads that don't see value in it and/or consider &lt;a href="https://chris.beams.io/posts/git-commit/#seven-rules" rel="noopener noreferrer"&gt;commit subjects&lt;/a&gt; to be holy ground.&lt;/p&gt;

&lt;p&gt;To those people I ask the following questions... &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do you agree that a well-formed commit subject concisely defines the work included in a given change set?&lt;/li&gt;
&lt;li&gt;If so, can you provide a more concise way of illustrating intent? &lt;/li&gt;
&lt;li&gt;If so, is it better than a one character emoji?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you get a solid answer to #3, I would love to hear about it. Until then, I am promoting emojis 💯.&lt;/p&gt;

&lt;p&gt;Most brownfield projects are change resistant too, but it doesn't mean your commit history has to be a wall of text at the yawn festival. Do yourself a favor and throw some emojis in there. A little happiness can go a long way.&lt;/p&gt;

&lt;h2&gt;
  
  
  📘 The Wrap Up
&lt;/h2&gt;

&lt;p&gt;In my opinion, emojis and commit messages are like peanut butter and jelly. They don't have to go together but when they do, oh man are they delicious 😋. &lt;/p&gt;

&lt;p&gt;Every coworker I've persuaded to try emoji style commits has found value in them after taking them for a spin. Personally I really enjoy putting emojis on my commits. Not only do they add clarity to commit history, they make me smile every time. &lt;/p&gt;




&lt;p&gt;Am I wrong? Agree with me? Got questions? Drop me a line in the comments, leave me a big squishy ♥️ and/or a glitter pooping 🦄.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Today's post was brought to you by VSCode's "move line up/down" shortcut:&lt;/em&gt; Option + Up/Down Arrow&lt;/p&gt;




</description>
      <category>git</category>
      <category>github</category>
      <category>optimization</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Debug as Code</title>
      <dc:creator>Nate Clark</dc:creator>
      <pubDate>Fri, 25 Sep 2020 13:43:56 +0000</pubDate>
      <link>https://dev.to/n8io/debug-as-code-15mn</link>
      <guid>https://dev.to/n8io/debug-as-code-15mn</guid>
      <description>&lt;p&gt;Long have the days been using &lt;code&gt;console.log&lt;/code&gt; to debug JavaScript code. Local or production, front or back end, it just works. In this post I will try to persuade you to try a different approach to debug logging that your future self will be proud of.&lt;/p&gt;

&lt;p&gt;Don't get me wrong, I love me some &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/log" rel="noopener noreferrer"&gt;console.log&lt;/a&gt;. There is something elegant about its simplicity and portability. Drop it in the browser console or your Node backend and you've got instant insight into the runtime state of your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;While helpful for debugging, &lt;code&gt;console.log&lt;/code&gt; statements are noisy.&lt;/p&gt;

&lt;p&gt;Almost every JS project I've worked on in recent years has had some sort of linting rule that disallows &lt;code&gt;console.log&lt;/code&gt; statements to be checked into the code base. In general, that is a good practice because displaying any non-critical messages in production will bloat logging and introduce a butt-ton of useless noise 🔊.&lt;/p&gt;

&lt;p&gt;For example, here is a small console excerpt from &lt;em&gt;ESPN.com&lt;/em&gt; 🤮:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6qr9hd55jnrx479tat0f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6qr9hd55jnrx479tat0f.png" alt="A screen shot of console output with rampant debug messaging from ESPN.com"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I can almost hear the developer's crying and log service budgets overflowing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The lesson here being that you should avoid committing &lt;code&gt;console.log&lt;/code&gt; statements to your code base.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔴 What about breakpoints?
&lt;/h2&gt;

&lt;p&gt;At this point you might be thinking..&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Couldn't we open up the production code in &lt;a href="https://developers.google.com/web/tools/chrome-devtools" rel="noopener noreferrer"&gt;Dev Tools&lt;/a&gt; and drop a breakpoint in there?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kinda but not really. Production code is almost always mangled and minified. In my experience there is a 50/50 chance that &lt;a href="https://www.html5rocks.com/en/tutorials/developertools/sourcemaps" rel="noopener noreferrer"&gt;source maps&lt;/a&gt; of the original code are available.&lt;/p&gt;

&lt;p&gt;Let's say for a moment you're lucky and you have source maps. You place a breakpoint exactly where you &lt;em&gt;think&lt;/em&gt; a bug originates. More often than not it's only the tip of the iceberg. So then you dive deeper and place another breakpoint. Rinsing and repeating until you find the source of the bug. All the while you are tripping over your own breakpoints, accidentally stepping into &lt;em&gt;jQuery&lt;/em&gt;'s internals, and losing context along the way.&lt;/p&gt;

&lt;p&gt;Keep in mind, breakpoints can only be used in the browser. Backend code is inaccessible in this way. So even if this completely solved the problem for the client it's only half the equation.&lt;/p&gt;

&lt;p&gt;There has to be a better way that works on both client &lt;em&gt;and server&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Enter the &lt;a href="https://www.npmjs.com/package/debug" rel="noopener noreferrer"&gt;debug&lt;/a&gt; logging package.&lt;/p&gt;

&lt;h3&gt;
  
  
  👼 Debugging with &lt;code&gt;debug&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A few years back I stumbled upon &lt;code&gt;debug&lt;/code&gt; by &lt;a href="https://sindresorhus.com/about" rel="noopener noreferrer"&gt;Sindre Sorhus&lt;/a&gt; (a.k.a the Man of a Thousand npm packages).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;debug&lt;/code&gt; library is not your typical logging package. It does not display, record, track, or ship any logs. It is a &lt;a href="https://dev.to/praneshpsg239/noop-in-javascript-478h"&gt;noop&lt;/a&gt; by default. Only when you enable it via an environment variable does it produce anything.&lt;/p&gt;

&lt;h4&gt;
  
  
  ⛺ Setup
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;debug&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;debug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apollo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// an arbitrary namespace&lt;/span&gt;

&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;✅ We're cleared for launch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// log something&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe to your surprise, the above code &lt;strong&gt;will not log anything&lt;/strong&gt;. As I mentioned before, we have to turn on &lt;code&gt;debug&lt;/code&gt; logging first. &lt;/p&gt;

&lt;p&gt;This is done differently depending on your environment.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the server: &lt;code&gt;export DEBUG=apollo&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the browser: &lt;code&gt;localStorage.debug = 'apollo'&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;For simplicity we can assume logging is enabled for the rest of this post.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  👾 Namespacing
&lt;/h4&gt;

&lt;p&gt;Continuing with our code above we add another log instance with a different namespace.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;debug&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;debug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apollo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logLaunch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apollo:launch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;✅ We're cleared for launch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;logLaunch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`⏳ T-minus 10 seconds`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ...waits 10 seconds&lt;/span&gt;
&lt;span class="nf"&gt;logLaunch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🚀 We have lift-off&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That in turn yields the following log messages:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu5jo5w1w2hsyckis9ho2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu5jo5w1w2hsyckis9ho2.png" alt="The rendered log messages from the preceding code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right away you'll notice we get some nice information here.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Namespaces are colored uniquely to make them easier to differentiate&lt;/li&gt;
&lt;li&gt;Each statement is suffixed by the elapsed time between log messages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For what it's worth, you can log objects like &lt;code&gt;console.log&lt;/code&gt; 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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;📨 Form values&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;...but wait there's more&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  🧮 Wildcard Filtering
&lt;/h4&gt;

&lt;p&gt;Remember the environment variable we set to enable logging? The value of that variable can be a wildcard string. &lt;/p&gt;

&lt;p&gt;Let me explain with a few examples.&lt;/p&gt;

&lt;p&gt;Assuming in the browser we set &lt;code&gt;localStorage.debug&lt;/code&gt; to the one of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;apollo&lt;/code&gt; - only log the &lt;code&gt;apollo&lt;/code&gt; namespace&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;apollo:*&lt;/code&gt; - log any namespace starting with &lt;code&gt;apollo:&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;apollo:*,-*launch*&lt;/code&gt; - log any namespace starting with &lt;code&gt;apollo:&lt;/code&gt;, excluding any namespaces that contain &lt;code&gt;launch&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This proves quite powerful. &lt;/p&gt;

&lt;h4&gt;
  
  
  💼 A real use case
&lt;/h4&gt;

&lt;p&gt;Imagine you are creating a new React &lt;code&gt;AirScrubber&lt;/code&gt; component. Internal to that component you namespace a log instance &lt;code&gt;apollo:air-scrubber&lt;/code&gt;. Then as you develop the component you add &lt;code&gt;debug&lt;/code&gt; messages throughout. These act as a sort of &lt;a href="https://www.cliffsnotes.com" rel="noopener noreferrer"&gt;CliffNotes&lt;/a&gt; for your component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apollo:air-scrubber&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logInit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apollo:air-scrubber:init&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logScrub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apollo:air-scrubber:scrub&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;logInit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🗂️ Air scrubber initializing...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="c1"&gt;// Do initialization work...&lt;/span&gt;
  &lt;span class="nf"&gt;logInit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;👍 Air scrubber initialized&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isAirQualityLow&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="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scrub&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;logScrub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🧽 Scrubbing air...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Do scrub work&lt;/span&gt;
  &lt;span class="nf"&gt;logScrub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🏁 Air scrubbed.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AirScrubber&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;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isAirQualityLow&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🚬 Air quality is low. Starting to scrub...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;scrub&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AirScrubber&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fast forward to the future... 💥 a user discovers there's an &lt;code&gt;AirScrubber&lt;/code&gt; bug in production.&lt;/p&gt;

&lt;p&gt;Don't panic. We have a way to triage that component quickly and precisely. &lt;/p&gt;

&lt;p&gt;Here's how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your Dev Tools console&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the following&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;debug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apollo:air-scrubber*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interact with the component and now you'll see all the detailed debug logs you wrote during local development &lt;em&gt;without having to rely on source maps, breakpoints, or even our old friend &lt;code&gt;console.log&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Receive high fives from your peers and future self&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  💻 What about server side?
&lt;/h4&gt;

&lt;p&gt;Much like in Dev Tools, we're going to set the &lt;code&gt;DEBUG&lt;/code&gt; environment variable on the server to whatever granularity we choose to enabled debug logging. Once we've done that we  have to restart the app to pickup the new value and tail the output. &lt;/p&gt;

&lt;p&gt;The debug messages will output the same look and feel we saw on the client.&lt;/p&gt;

&lt;h3&gt;
  
  
  📘 Summary
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;console.log&lt;/code&gt;...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Produces all the log messages - all the time&lt;/li&gt;
&lt;li&gt;Is noisy and covers up potential issues&lt;/li&gt;
&lt;li&gt;Should not be committed to code base&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using &lt;code&gt;debug&lt;/code&gt;...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allows developers to bake in logging without having to worry about bloat in production&lt;/li&gt;
&lt;li&gt;Allows for conditional verbosity (log only what you want)&lt;/li&gt;
&lt;li&gt;Provides logging granularity to complex systems via namespacing&lt;/li&gt;
&lt;li&gt;Displays log messaging with higher readability&lt;/li&gt;
&lt;li&gt;Allows us to debug the same way we do in local development&lt;/li&gt;
&lt;li&gt;Should be committed to code base&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  👷‍♂️ Take Action
&lt;/h3&gt;

&lt;p&gt;Next time you find yourself writing &lt;code&gt;console.log&lt;/code&gt;, take a moment to consider the value of the messaging.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Will this message help me debug in the future?&lt;/li&gt;
&lt;li&gt;Will this help a new hire understand the system in the future?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the answer is &lt;code&gt;yes&lt;/code&gt; to either question, please consider replacing it with a &lt;code&gt;debug&lt;/code&gt; log instead. &lt;/p&gt;

&lt;p&gt;These debug messages will prove to be invaluable the next time you track down a bug.&lt;/p&gt;




&lt;p&gt;Am I wrong? Agree with me? Got questions? Drop me a line in the comments, leave me a big squishy ♥️ and/or a glitter pooping 🦄.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Today's post was brought to you by VSCode's "open focused file in explorer" shortcut:&lt;/em&gt; Command + Down Arrow&lt;/p&gt;




</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>debug</category>
      <category>logging</category>
    </item>
    <item>
      <title>Developer Dark Arts: Ralpha-sorting</title>
      <dc:creator>Nate Clark</dc:creator>
      <pubDate>Mon, 22 Jun 2020 15:40:23 +0000</pubDate>
      <link>https://dev.to/n8io/developer-dark-arts-ralpha-sorting-c0o</link>
      <guid>https://dev.to/n8io/developer-dark-arts-ralpha-sorting-c0o</guid>
      <description>&lt;p&gt;It is no secret that order helps bring consistency to complex structures. Order allows our brains to consume and &lt;em&gt;recite&lt;/em&gt; information because of some pre-established rules. In this installment of Developer Dark Arts I'll explain what ralpha-sorting is and how avoiding it might increase your velocity.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏗️ Setup
&lt;/h2&gt;

&lt;p&gt;First, let me give you a challenge to get you in the right head space.&lt;/p&gt;

&lt;p&gt;In random order, can you list out the letters of the alphabet? How long would it take? How certain would you be that you got it right the first time?&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach ①: Naive
&lt;/h3&gt;

&lt;p&gt;If you're like me, right around the fourth or fifth letter I start forgetting what letters I've already listed. &lt;/p&gt;

&lt;h3&gt;
  
  
  Approach ②: Procedural
&lt;/h3&gt;

&lt;p&gt;Ok, let's try this again but this time we write them down as we list them out. F,B,E,A,... and so on. That works sort of. As the list gets longer we find ourselves reading through the existing list to see if the next random letter was already listed before adding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach ③: Front Loading
&lt;/h3&gt;

&lt;p&gt;Let's try a modified approach. We draw out a line of 26 boxes side by side. In each box we place the next random letter, but this time we'll write the letter in the exact box it would be in if I were listing the letters out alphabetically. Using the random order from the last attempt our list would like the following.&lt;/p&gt;

&lt;p&gt;[A][B][ ][ ][E][F]...&lt;/p&gt;

&lt;p&gt;Using this method we are a little slower to place the letters in the correct box at the beginning, but as our list grows, our time to place the letter decreases. This is because the process of elimination and the fact that our minds subconsciously know the alphabet. If our next letter to add was D, with very little effort we know D goes immediately before E. No longer are we scanning our list for duplicates, we can place each subsequent letter with confidence because we're sorting prior to placement.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤮 Ralpha-sorting
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ralph&lt;/strong&gt;: &lt;em&gt;verb [slang]&lt;/em&gt; To vomit or throw up&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ralpha-sorting is term I've used to explain the opposite (or lack of) alphabetical sorting. It's a collection of words that has no rhyme or reason, as if someone vomited them into existence.&lt;/p&gt;

&lt;p&gt;From our exercise above, our first two attempts were essentially ralpha-sorted lists. Neither were particularly enjoyable or quick to accomplish.&lt;/p&gt;

&lt;p&gt;Real world ralpha-sorting...&lt;/p&gt;

&lt;p&gt;CSS...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;green&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;JSON...&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;"taco"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"🌮"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"burrito"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"🌯"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cheese"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"🧀"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"salsa"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"💃"&lt;/span&gt;&lt;span class="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;JavaScript...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;omit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;evolve&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ramda&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;thing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;you&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;no&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sort&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;things&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;🤷‍♂️&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HTML...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;data-link=&lt;/span&gt;&lt;span class="s"&gt;"external"&lt;/span&gt; &lt;span class="na"&gt;aria-label=&lt;/span&gt;&lt;span class="s"&gt;"Checkout"&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;As you can see, ralpha-sorting is everywhere. These are usually products of functionality being added over time. The typical, "just append this new thing to the end" additions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We can do better.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔠 Alpha-sorting
&lt;/h2&gt;

&lt;p&gt;What if we alpha-sorted everything? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/oWQzTz2A4fp1m/giphy-downsized-large.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/oWQzTz2A4fp1m/giphy-downsized-large.gif" alt="Sort all the things"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  💄 CSS
&lt;/h3&gt;

&lt;p&gt;There has always been and will continue to be a debate of how you should organize css selectors and props. The organizational methods I've seen are positional, visual, alphabetical, preset, or none at all. Of those, only alphabetical has proven to be consistent &lt;em&gt;and&lt;/em&gt; transferrable from project to project.&lt;/p&gt;

&lt;p&gt;In css, order and specificity matter (the "cascading" part of acronym). A prop that comes later will supersede any references of the same prop before it. &lt;/p&gt;

&lt;p&gt;So if order matters, how is it that we can sort things alphabetically? In most cases selectors can't be alpha-sorted effectively. Every css file has its own quirks in terms of how selectors are defined and trying to sort them in any way is futile. It's the wild west and I haven't found a good solution for this. For that reason let us exclude selectors from this sorting discussion. &lt;/p&gt;

&lt;p&gt;In terms of css properties, you can safely sort them alphabetically. For example, the ordering of &lt;code&gt;border-color&lt;/code&gt; and &lt;code&gt;color&lt;/code&gt; has no impact on the end result. So for reasons I've already stated, putting them in alphabetical order makes sense. There are even some linting &amp;amp; formatting tools that can do this for you automatically when you save a file.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;{}&lt;/code&gt; JSON
&lt;/h3&gt;

&lt;p&gt;Not sure there is much of a debate here. Sort your keys alphabetically and move on.&lt;/p&gt;

&lt;p&gt;Again, there is automated tooling to do this work for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  📜 JavaScript
&lt;/h3&gt;

&lt;p&gt;Imports, exports, and object props. Alpha-sort 'em all™️. Of course there are edge cases but you should shoot for this to be the standard.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;insert automated tooling footnote&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📃 HTML
&lt;/h3&gt;

&lt;p&gt;Who's writing plain ole html these days?? A lot of people, that's who. Even if you're writing React, Vue, or Angular, you should be alpha-sorting element attributes. I've seen sorting alternatives like grouping &lt;code&gt;id&lt;/code&gt; and &lt;code&gt;class&lt;/code&gt; first but the implementation varies between projects. I am not a fan of any pattern that lowers readability for the sake of subjective "importance". &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;insert automated tooling footnote&amp;gt;&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;Still not convinced? You might think I am nit picking, especially since it doesn't impact functionality. I would argue that readability and developer experience are key factors in a product's success. We've all worked with developers who have avoided working on a project because its codebase is a mess. I'm one of them. Why not lower the barrier, even if it is drop in the bucket?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Alpha-sorting is objective&lt;/li&gt;
&lt;li&gt;Its linting is enforceable (&lt;em&gt;in most cases&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Its implementation can be automated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my opinion those points are hard to argue. Why not do our part to standardize on this universal rule? Can we automate away the alpha-sorting debate?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://prettier.io/"&gt;Prettier&lt;/a&gt;'s of the world, I'm looking at you 🔭 👀.&lt;/p&gt;

&lt;p&gt;Am I wrong? Agree with me? Curious which tools I use to automate alpha-sorting? Drop me a line in the comments, leave me a big squishy ♥️ and/or a glitter pooping 🦄.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Today's post was brought to you by VSCode's "go to definition" shortcut:&lt;/em&gt; Command+Click&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>refactorit</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Developer Dark Arts: React Class Components</title>
      <dc:creator>Nate Clark</dc:creator>
      <pubDate>Mon, 15 Jun 2020 15:45:25 +0000</pubDate>
      <link>https://dev.to/n8io/developer-dark-arts-react-class-components-3g8j</link>
      <guid>https://dev.to/n8io/developer-dark-arts-react-class-components-3g8j</guid>
      <description>&lt;p&gt;As part of the ES2015 release, classes were formally introduced to native JavaScript as syntactic sugar for prototypical inheritance. Object oriented developers everywhere popped champagne and celebrated in the streets. I was not one of those developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌄 The Web Landscape
&lt;/h2&gt;

&lt;p&gt;Coincidentally, this was also the time that the JavaScript community was being introduced to React. A library that unabashedly pushed its way past existing modular library seemingly overnight. React's creators took lessons learned from Angular 1.x, introduced &lt;a href="https://reactjs.org/docs/introducing-jsx.html"&gt;jsx&lt;/a&gt;, and taught us it was OK to &lt;em&gt;JS all the things&lt;/em&gt;™️. Got JS? Html? Css? Leftover 🍕? Throw it all in there, it'll blend.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/WTdOnTQJwTHmhifwGE/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/WTdOnTQJwTHmhifwGE/giphy.gif" alt="Oh it'll blend"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🎓 Stay Classy
&lt;/h2&gt;

&lt;p&gt;Classes provided a nice cork board for React to pin their patterns to. What is the recipe for a React class component you ask? &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new file&lt;/li&gt;
&lt;li&gt;Write a class that &lt;em&gt;extends&lt;/em&gt; &lt;code&gt;React.Component&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Repeat&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Not much to it. Easy peasy one two threezy. This pattern really flattened the curve for developers learning React. Especially those coming from object oriented languages.&lt;/p&gt;

&lt;p&gt;Everyone take a moment and wave 👋 hi to their old friend Readability. As with any new framework, adoption is strongly coupled to readability. React's high readability resulted in most code samples being comprised of classes. Hello world, todo app tutorials, learning resources, Stack Overflow, coding videos; classes as far as the eye can see.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤷‍♂️ So What's the Problem
&lt;/h2&gt;

&lt;p&gt;For the most part, everything was peachy &lt;em&gt;in the beginning&lt;/em&gt;. We had well-defined class components. We had modular, testable pieces of functionality. Life was good. However we know all good things must come to an end. As your React project's codebase grows you realize you're having to write a fair amount of boilerplate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MIN_POWER_TO_TIME_TRAVEL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.21&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;MIN_SPEED_TO_TIME_TRAVEL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;DeLorean&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;gigawatts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MIN_POWER_TO_TIME_TRAVEL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.21&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MIN_SPEED_TO_TIME_TRAVEL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;componentDidUpdate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;isLightingStriking&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isLightingStriking&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;gigawatts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DeLorean&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MIN_POWER_TO_TIME_TRAVEL&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;gigawatts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;hasEnoughPower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gigawatts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;gigawatts&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;DeLorean&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MIN_POWER_TO_TIME_TRAVEL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;hasEnoughSpeed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mph&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;mph&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;DeLorean&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MIN_SPEED_TO_TIME_TRAVEL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canTimeTravel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasEnoughPower&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gigawatts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasEnoughSpeed&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mph&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;canTimeTravel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;🚙&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Great Scott!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;🔥&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;gigawatts&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;GW&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mph&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;mph&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;🚙&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;🔥&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;NOTE: I am fully aware that this component's implementation is not perfect, but it is typical.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Do you see the &lt;code&gt;class ... extends React&lt;/code&gt;, &lt;code&gt;constructor&lt;/code&gt;, &lt;code&gt;super()&lt;/code&gt;, &lt;code&gt;render()&lt;/code&gt; lines? These will be needed in every class component you write. My wrists hurt thinking about all the redundant keystrokes. If you don't think lines of code are important, try wrapping your head around a 1000+ line component file. Es no bueno 👎.&lt;/p&gt;

&lt;p&gt;Inevitably you will find yourself debugging your new shiny component because it explodes for one reason or another.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Did you forgot to add the &lt;code&gt;constructor&lt;/code&gt; method? &lt;/li&gt;
&lt;li&gt;Did you call &lt;code&gt;super()&lt;/code&gt;? &lt;/li&gt;
&lt;li&gt;Should you be using some other lifecycle method? 

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;componentDidMount&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;componentWillMount&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;componentRedundantPrefixMethod&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;...or other undocumented/unstable method? &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;How are you going to test the &lt;code&gt;hasEnoughPower&lt;/code&gt; and &lt;code&gt;hasEnoughSpeed&lt;/code&gt; methods?&lt;/li&gt;
&lt;li&gt;Wtf is &lt;code&gt;static&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Oh no, not &lt;a href="https://medium.com/javascript-in-plain-english/the-most-confusing-thing-in-javascript-the-this-keyword-3436f451fca"&gt;"this"&lt;/a&gt; again&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I realize these all are not necessarily issues with classes, but our React class components aren't as perfect as we first thought.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p0LVdPs2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6gtz5fy99eecwac18ttx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p0LVdPs2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/6gtz5fy99eecwac18ttx.png" alt="A Back to the Future meme with a text overlay that reads Where we're going, we don't need classes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🎣 Enter Hooks
&lt;/h2&gt;

&lt;p&gt;If we fast forward a few minor versions of React we get a shiny new feature called &lt;code&gt;hooks&lt;/code&gt;. One of the key benefits of hooks is that they allow us to leverage all of the component lifecycle methods &lt;strong&gt;in functional components&lt;/strong&gt;. No weird syntax or boilerplate code required.&lt;/p&gt;

&lt;p&gt;Here's the hook-ified version of our stainless steel class component...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MIN_POWER_TO_TIME_TRAVEL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.21&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;MIN_SPEED_TO_TIME_TRAVEL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;88&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;hasEnoughPower&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gigawatts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;gigawatts&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;MIN_POWER_TO_TIME_TRAVEL&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;hasEnoughSpeed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mph&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;mph&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;MIN_SPEED_TO_TIME_TRAVEL&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;DeLorean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;isLightingStriking&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mph&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;gigawatts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setGigawatts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isLightningStriking&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;setGigawatts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MIN_POWER_TO_TIME_TRAVEL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;setGigawatts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isLightingStriking&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;canTimeTravel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hasEnoughPower&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gigawatts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;hasEnoughSpeed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mph&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;canTimeTravel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;🚙&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Great Scott!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;🔥&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;gigawatts&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;GW&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mph&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;mph&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;🚙&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;🔥&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a lot going on here, especially if you haven't used hooks before. I suggest you take a few minutes to skim through &lt;a href="https://reactjs.org/docs/hooks-overview.html"&gt;React's hook documentation&lt;/a&gt; to get familiar if you aren't already.&lt;/p&gt;

&lt;p&gt;The key takeaways are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can export and test &lt;code&gt;hasEnoughPower&lt;/code&gt; and &lt;code&gt;hasEnoughSpeed&lt;/code&gt; methods &lt;em&gt;without&lt;/em&gt; adding boilerplate¹&lt;/li&gt;
&lt;li&gt;We reduced our total lines of code by ~10 (25% less)&lt;/li&gt;
&lt;li&gt;No more &lt;code&gt;this&lt;/code&gt; keyword&lt;/li&gt;
&lt;li&gt;Boilerplate, "I-only-put-this-in-because-it-won't-work-without-it" code is completely removed&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;We're back to using functional composition in a functional language&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Functional components are smaller, &lt;a href="https://twitter.com/dan_abramov/status/1055702961303642112"&gt;more so when minified&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;¹ &lt;em&gt;I know we could have exported those two methods in the class example, but in my experience this is how I've seen the majority of components implemented. Where everything is a class method and accessed by &lt;code&gt;this&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📜 What If I Am Using Typescript?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;WARNING: Strong opinions lie ahead...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This post is about increasing readability and writing less code with better test coverage by specifically avoiding the use of classes.&lt;/p&gt;

&lt;p&gt;My current opinion of Typescript is that it increases lines of code, reduces velocity, and fully embraces inheritance. It forces OOP patterns into a functional language in exchange for type checking. Hold on, I have to go write some typings... Where was I? Oh yeah, getting lost in context switching 😉.&lt;/p&gt;

&lt;p&gt;If you are stuck writing Typescript I'm sorry and I feel for you. I've been there and it was not enjoyable (for me). Stop reading this post as it might tap into the well of stress and development frustration you have tried so hard to ignore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now back to our regularly scheduled post...&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📐 Exceptions to Every Rule
&lt;/h2&gt;

&lt;p&gt;As of writing, there are still a few places that classes are a necessary evil. These are considered very niche and make up a very small subset of use cases in most projects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When extending &lt;code&gt;Error&lt;/code&gt; into &lt;a href="https://javascript.info/custom-errors"&gt;custom errors&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;When using React's &lt;code&gt;Suspense&lt;/code&gt;, classes useful for capturing errors in &lt;a href="https://reactjs.org/docs/error-boundaries.html"&gt;error boundaries&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📔 Where Does this Leave Us?
&lt;/h2&gt;

&lt;p&gt;I hope/speculate that classes will eventually be exiled to outer reaches of the JS community, a la &lt;code&gt;generators&lt;/code&gt;. Neat to show off in academia with very few real world use cases.&lt;/p&gt;

&lt;p&gt;React is already migrating that way. Don't take my word for it, take a look at their documentation. Their examples are mostly functional components with footnotes for class versions. They've even posted a formal statement that &lt;a href="https://reactjs.org/docs/composition-vs-inheritance.html"&gt;they prefer composition over inheritance&lt;/a&gt; (read: functions over classes). &lt;/p&gt;

&lt;p&gt;Disagree? Love classes? Spot on? Let me know in the comments below.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Today's post was brought to you by VSCode's "duplicate line(s) above/below" shortcut:&lt;/em&gt; Shift+Option+(UpArrow|DownArrow)&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>developer</category>
      <category>refactorit</category>
    </item>
    <item>
      <title>Developer Dark Arts: Default Exports</title>
      <dc:creator>Nate Clark</dc:creator>
      <pubDate>Mon, 08 Jun 2020 12:35:43 +0000</pubDate>
      <link>https://dev.to/n8io/developer-dark-arts-default-exports-31ia</link>
      <guid>https://dev.to/n8io/developer-dark-arts-default-exports-31ia</guid>
      <description>&lt;p&gt;So you are starting a ✨ shiny new greenfield 🌱 project. Congrats, not many of us get the opportunity to build something from the ground up.  The architecture decisions you make today will impact everyone that comes after you. Hopefully, after a little convincing, you'll choose to avoid &lt;code&gt;default&lt;/code&gt; exports.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/MCZ39lz83o5lC/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/MCZ39lz83o5lC/giphy.gif" alt="With great power comes great responsibility"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First some background...&lt;/p&gt;

&lt;h2&gt;
  
  
  The JavaScript Module
&lt;/h2&gt;

&lt;p&gt;In modern JS, you have the ability to compartmentalize functionality into separate files commonly referred to as &lt;code&gt;modules&lt;/code&gt;. Each &lt;code&gt;module&lt;/code&gt; represents a single unit of work, an entity definition, or a combination of both. Each &lt;code&gt;module&lt;/code&gt; has its own &lt;em&gt;lexical scope&lt;/em&gt; which is academia's fancy term for &lt;em&gt;variable scoping&lt;/em&gt;... which is my fancy term for the concept that &lt;em&gt;things&lt;/em&gt; inside a module are not accessible outside of said module. Things being functions, variables, objects, etc. It also keeps your things from polluting the global namespace.&lt;/p&gt;




&lt;h2&gt;
  
  
  Exporting Things
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Wait a second. If things are not accessible outside my module how is it that modules are useful?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is where the &lt;code&gt;export&lt;/code&gt; keyword comes into play. It defines a contract or sort of micro api to anyone who intends on using your module.&lt;/p&gt;

&lt;p&gt;Let's say you have authored the greatest coin flip function ever created. Rather than copy/paste it everywhere you need to flip a coin you decide to extract it into a module appropriately called &lt;code&gt;coinFlip&lt;/code&gt;. Ya know, to keep your code &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// coinFlip.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to expose &lt;code&gt;coinFlip&lt;/code&gt; to other modules you have an architectural decision to make.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1: The &lt;code&gt;default&lt;/code&gt; Export
&lt;/h3&gt;

&lt;p&gt;Those of you coming from &lt;a href="https://dev.to/iggredible/what-the-heck-are-cjs-amd-umd-and-esm-ikm"&gt;CommonJS modules&lt;/a&gt; might be familiar with the &lt;code&gt;default&lt;/code&gt; export pattern. It defines what the &lt;em&gt;default&lt;/em&gt; exported functionality is for the module.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// coinFlip.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;= default export&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This syntax exposes the &lt;code&gt;coinFlip&lt;/code&gt; function in a way that allows consumers to &lt;code&gt;import&lt;/code&gt; it via an unnamed alias.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// coinFlip.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// decisionMaker.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./coinFlip&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I say "unnamed" because the name you give imported thing is arbitrary. I could have chosen to import it with any name really. &lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// coinFlip.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// decisionMaker.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;aFunctionThatReturnsHeadsOrTails&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./coinFlip&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;= aliased import of a default export&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The local name of the imported thing is entirely up to the consumer. An important thing to note here is that there can only be one default export per module.&lt;/p&gt;

&lt;p&gt;While not immediately apparent, default exports promote large object exports.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// coinFlip.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deprecatedFunction&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="mi"&gt;42&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;randomizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;coinFlip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;deprecatedFunction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;randomizer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;= default exported object&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Seems legit right? I mean this would future proof your default export. Allowing you to add props to the object as you your module grows but it has one major downside. It isn't tree-shakeable. &lt;a href="https://en.wikipedia.org/wiki/Tree_shaking"&gt;Tree shaking&lt;/a&gt; is the process in which consumers of your module transpile and minify their code. Its goal is to remove unused code branches. &lt;/p&gt;

&lt;p&gt;Continuing with the above example, when exporting &lt;code&gt;randomizer&lt;/code&gt; it cannot be split and dead branches cannot be groomed. Its export is atomic. Consumers get &lt;code&gt;deprecatedFunction&lt;/code&gt; regardless if they are using it or not. Effectively bloating your code bundles with potentially dead code. This becomes increasingly important in the browser where file size has a major impact on load times and user experience.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE: Large object exports are a problem regardless of &lt;code&gt;default&lt;/code&gt; vs named exports. However &lt;code&gt;default&lt;/code&gt; exports are more prone to this tree shaking pitfall because it's incredibly easy to add a prop to an existing exported object. Often times it's more appealing than refactoring to a named export.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2: The Named Export
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Ok, so large object exports are bad. What if I have multiple things I need to export from my module?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is where named exports shine.&lt;/p&gt;

&lt;p&gt;Named export syntax is different than default export in that it requires you explicitly name the things you're exporting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// coinFlip.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;= named export&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This syntax exposes the &lt;code&gt;coinFlip&lt;/code&gt; function in a way that allows consumers &lt;code&gt;import&lt;/code&gt; it via a well-defined name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// coinFlip.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// decisionMaker.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./coinFlip&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike the default export syntax, you can export as many named exports as you need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// coinFlip.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;HEADS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TAILS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HEADS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TAILS&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;coinFlip&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HEADS&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TAILS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// decisionMaker.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./coinFlip&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HEADS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;It was heads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;It was tails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What if you don't like the exported name or it is named the same as another local variable? Like the default export, when importing you can alias named exports however you want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// decisionMaker.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;DiceRollResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;diceRoll&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./diceRoll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;CoinFlipResult&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./coinFlip&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Option 3: Mixed Exports
&lt;/h3&gt;

&lt;p&gt;Default and named exports are not mutually exclusive. You could have a module with a default export and named exports.&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;HEADS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;heads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TAILS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tails&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HEADS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TAILS&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;coinFlip&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HEADS&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TAILS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;coinFlip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll most often see these 🦄 unicorns while working on brownfield projects that started with default exports and later added functionality to a module. Since default exports don't allow for multiple exports they added named exports to accommodate. That said, I doubt anyone has ever intended to start a project with this export pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  Which Option Should I Choose?
&lt;/h2&gt;

&lt;p&gt;Here are a few of the pros &amp;amp; cons that I've seen&lt;/p&gt;

&lt;h3&gt;
  
  
  Default Exports
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Familiar to devs migrating from legacy CommonJS modules&lt;/li&gt;
&lt;li&gt;❌ Leaves naming up to consumers which doesn't enforce any consistent naming conventions&lt;/li&gt;
&lt;li&gt;❌ Restricted to a single exported thing per module&lt;/li&gt;
&lt;li&gt;❌ Promotes large object export anti-pattern&lt;/li&gt;
&lt;li&gt;❌ Makes tree shaking difficult or impossible in some cases&lt;/li&gt;
&lt;li&gt;❌ No editor autocomplete/auto-import support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Named Exports
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Allows for unlimited exports per module&lt;/li&gt;
&lt;li&gt;✅ Forces you to name things at time of writing, not consumption&lt;/li&gt;
&lt;li&gt;✅ Allows for easy tree shaking of unused code&lt;/li&gt;
&lt;li&gt;✅ Allows for editor autocomplete/auto-import&lt;/li&gt;
&lt;li&gt;✅ Safe find/replace refactoring&lt;/li&gt;
&lt;li&gt;❌ Forces consumers to use the exported module name (but allows aliasing)&lt;/li&gt;
&lt;li&gt;❌ If a named export is poorly named, you may run into a situation where you have to alias the import in &lt;em&gt;every&lt;/em&gt; consumer&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mixed Exports
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Familiar to devs migrating from legacy CommonJS modules&lt;/li&gt;
&lt;li&gt;✅ Allows for unlimited exports per module&lt;/li&gt;
&lt;li&gt;❌ Consumers of the module never know if they want the default export or a named export (adds guesswork)&lt;/li&gt;
&lt;li&gt;❌ Naming conventions are unclear&lt;/li&gt;
&lt;li&gt;❌ Safe find/replace refactoring is close to impossible&lt;/li&gt;
&lt;li&gt;❌ Encourages large object exports which lose the benefit of tree shaking&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  And the Winner is?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🥇 &lt;strong&gt;Named Exports&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Having navigated through and made changes to code bases from all three options, the code bases with named exports are by far the best option. There isn't any mind mapping required to import a given module or its things. There is nothing to decide when creating a new module. Simply export a named thing and go on with your day. Lastly and arguably the most important gain is readability.&lt;/p&gt;

&lt;p&gt;What do you think? What am I missing? Where am I wrong? Let me know about your experience in the comments.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Today's post was brought to you by VSCode's "command palette" shortcut:&lt;/em&gt; Command+Shift+p&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>architecture</category>
      <category>refactorit</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Developer Dark Arts: Magic Strings</title>
      <dc:creator>Nate Clark</dc:creator>
      <pubDate>Wed, 20 May 2020 12:13:42 +0000</pubDate>
      <link>https://dev.to/n8io/developer-dark-arts-magic-strings-2ihn</link>
      <guid>https://dev.to/n8io/developer-dark-arts-magic-strings-2ihn</guid>
      <description>&lt;p&gt;In this post I am going to try and explain what magic strings are, why they are bad, and how to refactor them away.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do I care?
&lt;/h2&gt;

&lt;p&gt;Throughout your journey as developer you will inevitably find yourself starting out on a new project. Most of the time it is an existing code base that you will have to sift through, maintain, and add features to. This is the best time to identify anti-patterns, in this case magic strings, and offer up some best practices. &lt;/p&gt;

&lt;h2&gt;
  
  
  What the heck is a "magic" string?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// animalType.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;rabbit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rabbit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;pigeon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pigeon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;snake&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;snake&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// tricks.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./animalType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;animalType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rabbit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Pull &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;AnimalType&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rabbit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt; out of hat`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// favorites.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./animalType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rabbit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may have seen code similar to above. Longtime developers might be able to sniff out the code smell. There are a handful of problems. All of are rooted around the &lt;em&gt;magic&lt;/em&gt; string &lt;code&gt;"rabbit"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;❌ We're using a string to access props on the &lt;code&gt;AnimalType&lt;/code&gt; object in &lt;em&gt;some&lt;/em&gt; of the places&lt;br&gt;
❌ Re-typing the same string multiple times is error prone&lt;br&gt;
❌ Find &amp;amp; replacing &lt;code&gt;rabbit&lt;/code&gt; is error prone because of string vs dot notation uses&lt;br&gt;
❌ Modern editors' autocompletion results are polluted with string values&lt;/p&gt;

&lt;p&gt;What qualifies this as a "magic" string you ask? It's magic because of the string value &lt;code&gt;"rabbit"&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Let me explain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A magic string is a string (or number) whose value is seemingly derived out of thin air and is lacking any extra information to understand its origin. Its value is arbitrary. As arbitrary as a &lt;em&gt;rabbit&lt;/em&gt; being pulled from a magician's hat.&lt;/p&gt;

&lt;p&gt;-- me just now&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Why is this bad though?
&lt;/h2&gt;

&lt;p&gt;There are some pitfalls to writing your coding like this. &lt;/p&gt;

&lt;p&gt;Let's say for a moment that our dev manager went to a conference recently and brought back some new patterns for your team to implement. One of which is that we upper case all of our type values so they are easier to identify when reading code. &lt;/p&gt;

&lt;p&gt;In this case we would update our code to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// animalType.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;RABBIT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RABBIT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;PIGEON&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PIGEON&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;SNAKE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SNAKE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// tricks.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./animalType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;animalType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RABBIT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Pull &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;AnimalType&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;RABBIT&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt; out of hat`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// favorites.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./animalType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RABBIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we update the &lt;code&gt;"rabbit"&lt;/code&gt; value to &lt;code&gt;"RABBIT"&lt;/code&gt; in a bunch of places. In a real world scenario the &lt;code&gt;"rabbit"&lt;/code&gt; string would have to be updated everywhere it is referenced. &lt;em&gt;Every single reference in every file&lt;/em&gt; that uses &lt;code&gt;AnimalType&lt;/code&gt;. We'd also have to do this for &lt;code&gt;"pigeon"&lt;/code&gt; and &lt;code&gt;"snake"&lt;/code&gt;. Imagine if their values were more common terms like &lt;code&gt;"name"&lt;/code&gt; or &lt;code&gt;"type"&lt;/code&gt;. Good luck find/replacing those. Super gross 🤮.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can we improve this?
&lt;/h2&gt;

&lt;p&gt;In a perfect world the string &lt;code&gt;"RABBIT"&lt;/code&gt; would be defined once. &lt;/p&gt;

&lt;p&gt;Let me show you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// animalType.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RABBIT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RABBIT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PIGEON&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PIGEON&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SNAKE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SNAKE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;RABBIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;PIGEON&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;SNAKE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// tricks.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./animalType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;animalType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RABBIT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Pull &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;AnimalType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RABBIT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; out of hat`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// favorites.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./animalType&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;AnimalType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;RABBIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why is this better?
&lt;/h3&gt;

&lt;p&gt;✅ We've defined our string values in one place with names that are informational&lt;br&gt;
✅ Everywhere you see the &lt;code&gt;RABBIT&lt;/code&gt; variable you know that its actual value is an implementation detail. You only care that you're using the appropriate &lt;code&gt;AnimalType.&amp;lt;type&amp;gt;&lt;/code&gt;.&lt;br&gt;
✅ The string value for &lt;code&gt;RABBIT&lt;/code&gt; is defined once. Need to make a change to its value? Update that single line of code. No more find/replace nightmares.&lt;br&gt;
✅ Modern editors autocomplete &lt;code&gt;AnimalType&lt;/code&gt; without polluting the general results&lt;/p&gt;

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

&lt;p&gt;Hopefully I've done a decent job explaining why magic strings are ill-advised and how you can eliminate some of the issues they cause. Follow these guidelines and the you of tomorrow will thank you. Code readability and ease of maintenance for the win.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Today's post was brought to you by VSCode's "remove dead imports and sort" shortcut:&lt;/em&gt; Option+Shift+o&lt;/p&gt;

&lt;p&gt;Originally posted on &lt;a href="https://www.codingzeal.com/post/developer-dark-arts-magic-strings"&gt;ZEAL's blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>developer</category>
      <category>refactorit</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
