<?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: Alexandru-Dan Pop</title>
    <description>The latest articles on DEV Community by Alexandru-Dan Pop (@alexandrudanpop).</description>
    <link>https://dev.to/alexandrudanpop</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%2F358777%2Fc8c73bce-b48b-4e72-9712-5ec8081e7cb7.jpg</url>
      <title>DEV Community: Alexandru-Dan Pop</title>
      <link>https://dev.to/alexandrudanpop</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alexandrudanpop"/>
    <language>en</language>
    <item>
      <title>Releasing features with confidence as a software developer</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Wed, 09 Aug 2023 07:07:06 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/releasing-features-with-confidence-as-a-software-developer-49l3</link>
      <guid>https://dev.to/alexandrudanpop/releasing-features-with-confidence-as-a-software-developer-49l3</guid>
      <description>&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Unit Tests&lt;/li&gt;
&lt;li&gt;CI/CD Pipelines&lt;/li&gt;
&lt;li&gt;Feature Flags&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a software developer, there's this awesome rush when you see your code bring new features to life. It's like watching your digital creations come alive!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F194uzf4p4p71hyoj1uge.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F194uzf4p4p71hyoj1uge.jpeg" alt="it's alive meme" width="293" height="172"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, this excitement is often accompanied by the challenge of ensuring a smooth release that doesn't disrupt the user experience or introduce new bugs. &lt;/p&gt;

&lt;p&gt;In this post, we'll dive into the art of releasing features with confidence, exploring not only the basics but also when to use feature flags and A/B tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automated tests and CI/CD pipelines
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Unit Tests &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Before we embark on our journey of releasing features, it's essential to emphasize the importance of unit tests. &lt;/p&gt;

&lt;p&gt;Preferably written using Test-Driven Development (TDD), &lt;strong&gt;unit tests&lt;/strong&gt; serve as the bedrock of your codebase, ensuring that individual components of your application function as intended.&lt;/p&gt;

&lt;p&gt;With TDD (writing tests before the actual code), you're compelled to think deeply about the code you write and potential edge cases, resulting in more robust and reliable code.&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD Pipelines &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Continuous Integration and Continuous Deployment (CI/CD) pipelines automate the process of building, testing, and deploying your code.&lt;/p&gt;

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

&lt;p&gt;Like described in the video above (and with a few twists from my side), the ideal CI/CD pipeline for critical applications should include: &lt;br&gt;
1) Source code integration step with &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;installing dependencies, build or compiling the code&lt;/li&gt;
&lt;li&gt;running quality checks (for example SonarQube, linting, etc)&lt;/li&gt;
&lt;li&gt;running unit tests (quality of the unit tests can be checked with mutation testing)&lt;/li&gt;
&lt;li&gt;check and enforce code coverage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2) Deploy to test environment&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;running integration tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3) Deploy to production&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;observability&lt;/li&gt;
&lt;li&gt;alerts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more critical systems or advanced use cases, a &lt;em&gt;canary deployment&lt;/em&gt; strategy can be implemented. This means a gradual roll-out while traffic is gradually shifted from the old deployment to the new one.&lt;/p&gt;
&lt;h2&gt;
  
  
  Feature Flags and A/B Tests
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Feature Flags &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Feature flags (FF), also known as feature toggles or feature switches, are a technique that allows you to enable or disable certain features within your application without deploying new code.&lt;/p&gt;

&lt;p&gt;There are many types of flags, but the most common would be to just turn a toggle on or off in a certain environment. &lt;/p&gt;

&lt;p&gt;Example of a FF: Google_Login (dev - enabled, stage - enabled, prod - disabled). The power here is that we can turn the feature flag off in case we discover a bug with the Google Login, so we don't need to do a rollback or even worse a hotfix. We just disable the flag in production, push a fix then re-enable it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Managing Feature Flags&lt;/strong&gt;&lt;br&gt;
It's important to have a system (external or internally built) to easily manage feature flags. While FFs provide flexibility, it's essential to strike a balance. &lt;/p&gt;

&lt;p&gt;Keeping the number of active flags to a minimum reduces complexity and avoids potential confusion among developers. Just as you regularly refactor your codebase, it's important to remove old feature flags both from your code and your flag management system.&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;h3&gt;
  
  
  A/B Tests &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;A/B testing, or split testing, involves comparing two versions of a feature or webpage to determine which one performs better. By dividing your users into two groups (A and B) and exposing them to different versions of a feature, you can gather empirical data to make informed decisions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How A/B Testing Works&lt;/strong&gt;: A/B testing allows you to release a new feature or design change to a subset of your users while keeping the original version for another group. By comparing user behavior and engagement metrics, you can objectively measure the impact of the change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Primary &amp;amp; Secondary Metrics&lt;/strong&gt;: When setting up an A/B test, it's essential to define primary and secondary metrics. Primary metrics directly measure the success of the feature, while secondary metrics provide additional insights. Analyzing both types of metrics helps you make well-rounded decisions.&lt;/p&gt;

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

&lt;p&gt;Example: We observe that only 2% of the traffic in our website results in a user signing for our newsletter. We do some UX research and come up with an updated design of the landing page, and we try it out in a A/B test. Our current page (the control group) and the variation are both served to our customers. During a 2 week period we observe the new page results in 4% of the traffic subscribing to thew newsletter. Succes!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clean-Up After A/B Tests&lt;/strong&gt;: Just as with FFs, A/B test clean-up is crucial. Once you've collected enough data and made your decision, be sure to remove the code related to the alternative version, and also archive the test in the A/B test management system. &lt;/p&gt;

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

&lt;p&gt;Releasing features with confidence requires a delicate balance of foundational practices and advanced strategies. Automated tests instill thoughtfulness in your code, while CI/CD pipelines ensure consistent and reliable deployments. However, the real magic happens when you embrace feature flags and A/B tests.&lt;/p&gt;

&lt;p&gt;And it will also make you look cool, imagine you just discussed with the Product Manager whether to release that new stuff you worked on last 2 weeks, and he tells you to release it. You switch the feature toggle on, and there it is, one minute later.&lt;/p&gt;

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

&lt;p&gt;So while feature flags empower you to release and iterate on features with flexibility and control, A/B tests provide the empirical data needed to make informed decisions about the usefulness of the changes you are making in the software. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>cloud</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Ubuntu 20.04 - how to make it perfect for development &amp; productivity</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Mon, 05 Apr 2021 14:57:45 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/ubuntu-20-04-how-to-make-it-perfect-for-development-productivity-1jk5</link>
      <guid>https://dev.to/alexandrudanpop/ubuntu-20-04-how-to-make-it-perfect-for-development-productivity-1jk5</guid>
      <description>&lt;p&gt;Since I recently configured my laptop to dual boot into Ubuntu 20.04, I wanted to share my experience and what I think you can do to make your use of this system as pleasant as possible.&lt;/p&gt;

&lt;p&gt;I'm very impressed by how stable this system is and how customizable it is &amp;amp; quite frankly I think it makes an awesome dev environment.&lt;/p&gt;

&lt;p&gt;This article assumes that you already configured your system to run Linux (Ubuntu 20.04) - and describes what customizations I did that I think are cool.  If you haven't installed Ubuntu 20.04 yet, a simple google search will get you all info needed on how to create a bootable USB with Ubuntu, how to shrink your current Windows partition &amp;amp; finally configure BIOS to boot &amp;amp; install Linux.&lt;/p&gt;

&lt;p&gt;Also, please note that this article is just scratching the surface of the configuration options of Ubuntu.&lt;/p&gt;

&lt;h2&gt;
  
  
  MacOS BigSur theme
&lt;/h2&gt;

&lt;p&gt;Since I've used an M1 Mac with BigSur for a while I got very used to the "BigSur theme" and the good thing is you can replicate this on Ubuntu.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Add the universe apt repo:
&lt;code&gt;sudo apt-add-repository universe&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install gnome tweeks: &lt;code&gt;sudo apt install gnome-tweak-tool&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install gnome shell extensions: &lt;code&gt;sudo apt install gnome-shell-extensions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Download the WhiteSur Gtk Theme from &lt;a href="https://www.gnome-look.org/p/1403328/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. I downloaded both the simple dark &amp;amp; light ones.&lt;/li&gt;
&lt;li&gt;In your home folder create a &lt;code&gt;.themes&lt;/code&gt; folder if it doesn't exist and unzip the downloaded folders there.&lt;/li&gt;
&lt;li&gt;Download and unzip the WhiteSur icon theme from &lt;a href="https://www.pling.com/p/1405756/" rel="noopener noreferrer"&gt;here&lt;/a&gt; and put it in your home directory in a &lt;code&gt;.icons&lt;/code&gt; folder&lt;/li&gt;
&lt;li&gt;Once you do this you open &lt;code&gt;Tweaks&lt;/code&gt; app and configure the themes and icons: 
&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%2Fuploads%2Farticles%2Fky5y70ttz71dpn14j8go.png" alt="tweaks app customizations"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note you can also install &amp;amp; configure MacOS fonts, but I like the Ubuntu ones so I kept those. &lt;/p&gt;

&lt;p&gt;One additional thing I did was install a BigSur wallpaper image, that you can easily find on google, and now the apps you open on your new Ubuntu installation will look like this, and I personally think it's pretty nice:&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%2Fuploads%2Farticles%2Ffwl0w2n94tgxm5jio2o5.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%2Fuploads%2Farticles%2Ffwl0w2n94tgxm5jio2o5.png" alt="tweaked ubuntu"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Dash to dock
&lt;/h2&gt;

&lt;p&gt;One more thing I consider it's nice to do is to configure &lt;strong&gt;Dash to dock&lt;/strong&gt; - this can give you also a dock experience similar to macOS. &lt;/p&gt;

&lt;p&gt;To do this: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to Gnome Extensions and install &lt;a href="https://extensions.gnome.org/extension/307/dash-to-dock/" rel="noopener noreferrer"&gt;dash to dock&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Go to the &lt;code&gt;Tweaks&lt;/code&gt; app again in the Extensions section - &lt;code&gt;Dash to dock&lt;/code&gt; should be enabled or enable it if it's not - and disable &lt;code&gt;Ubuntu dock&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You should see the Dash to dock now - right-click on the 9 little dots icon - and click on &lt;code&gt;Dash to dock settings&lt;/code&gt;. From here you can configure the position on screen - Bottom, the sizes of the icons (for me it's 32px), and in the Appearance tab - the Opacity and other small things. 
&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%2Fuploads%2Farticles%2Fluwri4sro7i0rdaxgjxl.png" alt="dash to dock config"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You should probably log out &amp;amp; log in again to make sure the settings are applied.&lt;/p&gt;

&lt;p&gt;The steps above are courtesy of this video, but using the WhiteSur theme, and with simplified steps. &lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ZerCpEihkE8"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h2&gt;
  
  
  Install Albert
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Albert&lt;/strong&gt; is a spotlight-like search tool (launcher) for Linux. Even though Ubuntu already comes with a pretty nice search functionality out of the box - pressing the Super/Windows key, I still like using Albert more. &lt;/p&gt;

&lt;p&gt;You can read more about it and how to install it from &lt;a href="https://albertlauncher.github.io/installing/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;After you install it, make sure to go to &lt;code&gt;Startup Applications&lt;/code&gt; app and configure it to run on startup. The command to launch it should be &lt;code&gt;/usr/bin/albert&lt;/code&gt;. You can start Albert, and from the Settings screen configure your desired hotkey to open it and the Theme (I choose Spotlight Dark).&lt;/p&gt;
&lt;h2&gt;
  
  
  Install Tilix terminal
&lt;/h2&gt;

&lt;p&gt;I like Tilix better than the default terminal, I like how customizable it is, and the split panel feature. I configure it so &lt;code&gt;ctrl+t&lt;/code&gt; adds a new split terminal and &lt;code&gt;ctrl+w&lt;/code&gt; closes a panel. You can install Tilix from the &lt;code&gt;Ubuntu Software&lt;/code&gt; app.&lt;br&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%2Fuploads%2Farticles%2Ftfqgvlne4vqmj78798ct.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%2Fuploads%2Farticles%2Ftfqgvlne4vqmj78798ct.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also installed &lt;code&gt;fish shell&lt;/code&gt; and use it as the default shell. I think fish is a much nicer shell, especially for the autosuggestions. You can check it out &lt;a href="https://www.vultr.com/docs/installing-fish-shell-on-ubuntu" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Brave browser
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Brave&lt;/strong&gt; is my default browser for a few months. It's exactly like &lt;strong&gt;Google Chrome&lt;/strong&gt; (Chromium-based), so you can use all extensions &amp;amp; features you have on Chrome, but unlike Chrome - it's not a tracking machine. &lt;/p&gt;

&lt;p&gt;It supports ad-blocking and tracker-blocking out of the box. &lt;/p&gt;

&lt;p&gt;You can set it to use &lt;strong&gt;DuckDuckGo&lt;/strong&gt; as the default search engine, and probably have a much better web surfing experience since you don't see all those ads and trackers don't make the websites you visit slow.  &lt;/p&gt;

&lt;p&gt;You can add Brave from the &lt;code&gt;Ubuntu Software&lt;/code&gt; app.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dev &amp;amp; productivity tools
&lt;/h2&gt;

&lt;p&gt;I won't insist too much on this aspect, as it's pretty obvious that the best tools for development work great on this distro, and are pretty easy to install. I use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VSCode&lt;/li&gt;
&lt;li&gt;Notepad++ &lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Postman&lt;/li&gt;
&lt;li&gt;Homebrew&lt;/li&gt;
&lt;li&gt;Nodejs, yarn, etc. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From my previous experience of trying out the &lt;strong&gt;M1 Mac&lt;/strong&gt;, and trying all sorts of workarounds for simple stuff, I can say everything has been a breeze on Linux. 😊 &lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/alexandrudanpop" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuploads%2Fuser%2Fprofile_image%2F358777%2Fc8c73bce-b48b-4e72-9712-5ec8081e7cb7.jpg" alt="alexandrudanpop"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/alexandrudanpop/the-m1-mac-is-it-worth-it-for-devs-3fi5" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;The M1 Mac - Is it worth it for devs?&lt;/h2&gt;
      &lt;h3&gt;Alexandru-Dan Pop ・ Mar 1 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;I also like using Spotify that works great here &amp;amp; &lt;strong&gt;Notion&lt;/strong&gt; for note-taking &amp;amp; personal task management.&lt;/p&gt;

&lt;p&gt;I use &lt;a href="https://meldmerge.org/" rel="noopener noreferrer"&gt;Melde&lt;/a&gt; as a 3-way merge tool for git - that is also pretty easy to configure - see below:&lt;/p&gt;

&lt;p&gt;If I do a &lt;code&gt;cd ~ &amp;amp;&amp;amp; cat .gitconfig&lt;/code&gt; - will only copy here the merge tool config:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

[merge]
    tool = meld
[mergetool "meld"]
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
"$MERGED"
    keepBackup = false


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

&lt;/div&gt;

&lt;p&gt;Then when you have a git conflict, you can use: &lt;code&gt;git mergetool&lt;/code&gt; to fix it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Make it faster
&lt;/h2&gt;

&lt;p&gt;Linux systems are extremely memory-efficient, I sometimes look at the OS especially without having many things running and I marvel at how little memory it uses compared to Windows or macOS. But some application startup times are not the best, but for this, you can use &lt;code&gt;preload&lt;/code&gt;, at the cost of some additional RAM.&lt;/p&gt;

&lt;p&gt;To improve startup times for different applications:&lt;br&gt;
&lt;code&gt;sudo apt install preload&lt;/code&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Consider trying Ubuntu or some other Linux distro if you are a developer. You will not regret it!&lt;/p&gt;

&lt;p&gt;You might even see that your 3y old laptop/mac doesn't need an upgrade, just because of how memory efficient &amp;amp; well-optimized Linux is.&lt;/p&gt;

&lt;p&gt;Thanks for reading, if you enjoy this article chances are you will also like what I post on &lt;a href="https://twitter.com/alexandrudanpop" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The M1 Mac - Is it worth it for devs?</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Mon, 01 Mar 2021 11:04:07 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/the-m1-mac-is-it-worth-it-for-devs-3fi5</link>
      <guid>https://dev.to/alexandrudanpop/the-m1-mac-is-it-worth-it-for-devs-3fi5</guid>
      <description>&lt;p&gt;I can say I was very impressed by the &lt;a href="https://tech.ssut.me/apple-m1-chip-benchmarks-focused-on-the-real-world-programming/" rel="noopener noreferrer"&gt;benchmarks results&lt;/a&gt; given by those machines, so I decided to try one out. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TLDR&lt;/strong&gt; - I didn't choose the M1 Mac Mini as a mainly daily driver - yet - until docker will be fully supported. I'll use it for frontend workflows that involve running a bunch of the node.js tasks + mock APIs + continuously running tests in the background.&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I choose the M1 Mac Mini with 16GB RAM
&lt;/h2&gt;

&lt;p&gt;I wanted to use it with - 2 big monitors (M1 MacBooks support only one external display - although there are workarounds). I don't like staring into small laptop screens, so for using both my monitors and also having more ports I have chosen the Mac Mini instead of the MacBooks.&lt;/p&gt;

&lt;p&gt;Also, I am working remotely and already have a Dell XPS 15 laptop. So buying an M1 laptop didn't make sense - since I can use my laptop when I need portability.&lt;/p&gt;

&lt;p&gt;I went for 16GB of RAM because some of my development workflows require running multiple docker containers locally, and we all know how much memory docker consumes. Also, I noticed that the 16 GB model barely uses less than ~7-8GB RAM but I'll get to that later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Impressions
&lt;/h2&gt;

&lt;p&gt;A lot of my development work implies running &lt;code&gt;VSCode&lt;/code&gt; and &lt;code&gt;node.js&lt;/code&gt; locally for frontend workflows.&lt;/p&gt;

&lt;p&gt;Running the native arm &lt;code&gt;node.js&lt;/code&gt; on this machine is extremely performant. Can say for some frontend builds I was getting ~60% speed increases from my 2y old Dell XPS 15.&lt;/p&gt;

&lt;p&gt;With a local frontend workflow (build and running unit tests), lots of Chrome tabs open, docker running a few containers, VSCode, Spotify, and other programs running in the background I haven't seen it use more than '~12,5GB' of RAM. It never used the full '16GB' RAM. But it does use SSD swap, so that's interesting.&lt;/p&gt;

&lt;p&gt;I did see that with very little use - like a few Chrome tabs + other background apps that run by default it will quickly consume the "standard" 8GB of RAM.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveats
&lt;/h2&gt;

&lt;p&gt;I spent countless hours getting around some issues like for a Gatsby project I could not make the 'sharp' module work. When I finally managed to do that, BigSur had an update and after that, the arm version of &lt;code&gt;node.js&lt;/code&gt; didn't work anymore. 🙀&lt;/p&gt;

&lt;p&gt;I also tried &lt;code&gt;docker&lt;/code&gt; and certain images that work on my Windows 10 laptop or on an Intel MacBook. Around half of them don't work on the M1 with &lt;a href="https://docs.docker.com/docker-for-mac/apple-m1/" rel="noopener noreferrer"&gt;docker for M1 preview&lt;/a&gt;. With some tweaks, I managed to run some of them, but others without luck.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things to consider
&lt;/h2&gt;

&lt;p&gt;Before considering this as your main machine check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://isapplesiliconready.com/" rel="noopener noreferrer"&gt;Is Apple silicon ready website&lt;/a&gt; to browse if the software you use is compatible yet or can run through Rosetta 2&lt;/li&gt;
&lt;li&gt;consider issues like &lt;a href="https://www.macrumors.com/2021/02/03/macos-big-sur-external-display-issues/" rel="noopener noreferrer"&gt;USB-C connected monitors&lt;/a&gt; not working from time to time (mine hiccups sometimes and have to unplug/plug the cable)&lt;/li&gt;
&lt;li&gt;consider Bluetooth issues - those seem to be partly fixed, but I still experienced some smaller issues when you need to manually connect the devices&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/docker/for-mac/issues?q=is%3Aissue+is%3Aopen+label%3Aarea%2Fm1" rel="noopener noreferrer"&gt;docker issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;no E-GPU support&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cultofmac.com/715395/boot-camp-not-supported-arm-macs/" rel="noopener noreferrer"&gt;Boot Camp no longer works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;some users reported &lt;a href="https://www.pcworld.idg.com.au/article/686484/m1-mac-users-reporting-excessive-ssd-wear-tear/" rel="noopener noreferrer"&gt;accelerated SSD tear&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also recommend you to watch some of &lt;a href="https://www.youtube.com/c/AlexanderZiskind/videos" rel="noopener noreferrer"&gt;Alexander Ziskind's Youtube videos&lt;/a&gt; around the M1 Macs. He is comparing them to Intel Macs or laptops and trying out various programming tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  Personal conclusions
&lt;/h2&gt;

&lt;p&gt;My impression is that if you have moderately big projects to work on - with a lot of dependencies &amp;amp; especially if you need to use &lt;code&gt;docker&lt;/code&gt; - you will run into various issues that you need to fix. Some of those fixes will be easier as the community posts issues and fixes on &lt;code&gt;Github&lt;/code&gt;. But for some other issues, you will just need to wait for fixes and use an &lt;code&gt;x86&lt;/code&gt; machine in the meantime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overall, I consider it a good price for a performant machine.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you do mostly &lt;em&gt;web development&lt;/em&gt; or &lt;em&gt;web design&lt;/em&gt; and don't rely on things like &lt;code&gt;docker&lt;/code&gt; or if you can use a mock API to mock your backend dependencies - I think this system makes a lot of sense.&lt;/p&gt;

&lt;p&gt;If you are just learning programming, an &lt;code&gt;M1 Mac Mini&lt;/code&gt; is a good machine considering the costs - you could even go for the cheapest M1 Mac mini. ✌️&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;p&gt;If you are patient and already have a good computer, you could probably wait around 3-6 months to see if more stable versions of the software you use pop up. Although seeing how fast the trend of fixing issues is - I think a lot of the current problems will be fixed soon.&lt;/p&gt;

&lt;p&gt;If you are using Windows, I also have an article for setting things up for development and making a Windows machine more pleasant for development.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/alexandrudanpop" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuploads%2Fuser%2Fprofile_image%2F358777%2Fc8c73bce-b48b-4e72-9712-5ec8081e7cb7.jpg" alt="alexandrudanpop"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/alexandrudanpop/modern-windows-10-dev-setup-1lnl" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Modern Windows 10 development setup&lt;/h2&gt;
      &lt;h3&gt;Alexandru-Dan Pop ・ Oct 25 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;And, if you want to embrace Linux but like the MacOs BigSur look &amp;amp; feel, I wrote an article how to tweak Ubuntu to look like BigSur &amp;amp; configure some extra stuff to make it more pleasant:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/alexandrudanpop" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuploads%2Fuser%2Fprofile_image%2F358777%2Fc8c73bce-b48b-4e72-9712-5ec8081e7cb7.jpg" alt="alexandrudanpop"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/alexandrudanpop/ubuntu-20-04-how-to-make-it-perfect-for-development-productivity-1jk5" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Ubuntu 20.04 - how to make it perfect for development &amp;amp; productivity&lt;/h2&gt;
      &lt;h3&gt;Alexandru-Dan Pop ・ Apr 5 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Creating a Calculator app with React and TDD</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Sun, 14 Feb 2021 16:06:58 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/creating-a-calculator-app-with-react-and-tdd-277</link>
      <guid>https://dev.to/alexandrudanpop/creating-a-calculator-app-with-react-and-tdd-277</guid>
      <description>&lt;p&gt;Let us build a simple web-app calculator with a &lt;strong&gt;test-first&lt;/strong&gt; approach and &lt;strong&gt;React&lt;/strong&gt;! &lt;/p&gt;

&lt;p&gt;I highly suggest you follow this exercise if you are already familiar with React, and want to also step up your testing game. 🌟&lt;/p&gt;

&lt;p&gt;We will approach building a simple app, with only the basic calculation functions - but most importantly - we will follow a &lt;strong&gt;Test Driven Developmnet&lt;/strong&gt; approach. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Test-driven development (TDD) is a development technique where you must first write a test that fails before you write new functional code. TDD is being quickly adopted by agile software developers for development of application source code and is even being adopted by Agile DBAs for database development. (&lt;a href="http://agiledata.org/essays/tdd.html" rel="noopener noreferrer"&gt;agiledata.org&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp45fhum8l0z62t067iwy.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp45fhum8l0z62t067iwy.jpg" alt="TDD diagram" width="380" height="732"&gt;&lt;/a&gt;&lt;br&gt;
Image stolen from &lt;a href="http://agiledata.org/essays/tdd.html" rel="noopener noreferrer"&gt;agiledata.org&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;We want a quick setup that provides us with testing already configured for us so we are picking good old &lt;code&gt;create-react-app&lt;/code&gt; for this. We will also choose the &lt;code&gt;TypeScript&lt;/code&gt; template. So open a terminal and run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-react-app calculator --template typescript&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cd calculator&lt;/code&gt;&lt;br&gt;
Open an editor. I'll use VS Code:&lt;br&gt;
&lt;code&gt;code .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Have two terminal windows open:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one to run &lt;code&gt;npm start&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;one to run &lt;code&gt;npm run test&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Let's start coding
&lt;/h2&gt;

&lt;p&gt;Start coding you say? Funny. I thought we were doing TDD. Of course, we want to create a failing test first. But where do we start?&lt;/p&gt;

&lt;p&gt;Go to &lt;code&gt;App.test.tsx&lt;/code&gt;, delete the existing test and write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;renders calculator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;render&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;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;calculatorElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/calculator/i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;calculatorElement&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you go, our terminal that runs the tests should output:&lt;br&gt;
&lt;code&gt;Tests: 1 failed, 1 total&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Our test just naively checks that we have somewhere in our app the text &lt;strong&gt;calculator&lt;/strong&gt; rendered.&lt;/p&gt;

&lt;p&gt;So we will create a &lt;code&gt;Calculator.tsx&lt;/code&gt; file with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&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;Calculator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The test still fails. Well.. We are not yet rendering our &lt;code&gt;Calculator&lt;/code&gt; component. Let's fix that. Go to 'App.tsx':&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&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;react&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App.css&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="nx"&gt;Calculator&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;./Calculator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="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;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;App&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;main&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;Calculator&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="sr"&gt;/main&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅&lt;code&gt;Tests:       1 passed, 1 total&lt;/code&gt; - great we passed our first test. Now what? &lt;/p&gt;

&lt;p&gt;Do we build the code for the calculator? &lt;br&gt;
❌ Of course not, we write another failing test, now in 'Calculator.test.tsx', to show the calculator numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@testing-library/react&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="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="s2"&gt;react&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="nx"&gt;Calculator&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;./Calculator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;Calculator /&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;shows numbers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())).&lt;/span&gt;&lt;span class="nf"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And in &lt;code&gt;Calculator.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gi"&gt;+ const numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+ const Calculator = () =&amp;gt; {
+   return (
+     &amp;lt;div className="calculator"&amp;gt;
&lt;/span&gt;      &amp;lt;h1&amp;gt;Calculator&amp;lt;/h1&amp;gt;
&lt;span class="gi"&gt;+       {numbers.map((n) =&amp;gt; (
+         &amp;lt;button key={n}&amp;gt;{n.toString()}&amp;lt;/button&amp;gt;
+       ))}
+     &amp;lt;/div&amp;gt;
+   );
+ };
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;export default Calculator;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alright, at this point, if we look at the app we have something like:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0q4lqz0f3ciiwebkra3e.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0q4lqz0f3ciiwebkra3e.PNG" alt="Initial app with number buttons" width="594" height="161"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Render rows of numbers
&lt;/h2&gt;

&lt;p&gt;We want to show our numbers in rows:&lt;br&gt;
Row 1: [7, 8, 9]&lt;br&gt;
Row 2: [4, 5, 6]&lt;br&gt;
Row 3: [1, 2, 3]&lt;br&gt;
Row 4: [0]&lt;/p&gt;

&lt;p&gt;Hmm.. how do we test that? So in 'Calculator.test.tsx', we could have a new test like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;shows 4 rows&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAllByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&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;Alright, now that we have the failing test, to pass it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&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;Calculator&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="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;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculator&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;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&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;div&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="p"&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="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="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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's also check our app:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmof1b3fqil5q66555w0i.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmof1b3fqil5q66555w0i.PNG" alt="in progress calculator application" width="251" height="218"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Show calculator operators
&lt;/h2&gt;

&lt;p&gt;Test to show operators:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;shows calculation operators&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;calcOperators&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;×&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;÷&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="nx"&gt;calcOperators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;operator&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;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())).&lt;/span&gt;&lt;span class="nf"&gt;toBeInTheDocument&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;Pass the test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;const rows = [[7, 8, 9], [4, 5, 6], [1, 2, 3], [0]];
&lt;/span&gt;&lt;span class="gi"&gt;+ const calcOperators = ["+", "-", "×", "÷"];
&lt;/span&gt;&lt;span class="p"&gt;const Calculator = () =&amp;gt; {
&lt;/span&gt;  return (
    &amp;lt;div className="calculator"&amp;gt;
      &amp;lt;h1&amp;gt;Calculator&amp;lt;/h1&amp;gt;
      &amp;lt;div role="grid"&amp;gt;
        {rows.map((row) =&amp;gt; {
          return (
            &amp;lt;div key={row.toString()} role="row"&amp;gt;
              {row.map((n) =&amp;gt; (
                &amp;lt;button key={n}&amp;gt;{n.toString()}&amp;lt;/button&amp;gt;
              ))}
            &amp;lt;/div&amp;gt;
          );
        })}
&lt;span class="gi"&gt;+       {calcOperators.map((c) =&amp;gt; (
+         &amp;lt;button key={c}&amp;gt;{c.toString()}&amp;lt;/button&amp;gt;
+       ))}
&lt;/span&gt;      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;export default Calculator;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! It looks terrible 😅. Don't worry, we will fix the styles later.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frpwjyz8hbqfmopm0sw6f.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frpwjyz8hbqfmopm0sw6f.PNG" alt="in progress calculator application" width="253" height="280"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Show an equal sign &amp;amp; clear sign:
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;renders equal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;equalSign&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;equalSign&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;renders clear sign&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, 2 tests are failing. To fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Fragment&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;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;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&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;calcOperators&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;×&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;÷&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;equalSign&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;=&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;clear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&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;Calculator&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="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;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculator&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;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&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;div&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="o"&gt;&amp;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;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="p"&gt;))}&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;equalSign&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&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;/div&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;/Fragment&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;span class="nx"&gt;calcOperators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&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="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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Show an input for values to be calculated
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;renders an input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&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;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByPlaceholderText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We always want this input to be disabled, so we will also add a test for that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;renders an input disabled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&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;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByPlaceholderText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeDisabled&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;Implement the input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gi"&gt;+ import { Fragment, useState } from "react";
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;const rows = [[7, 8, 9], [4, 5, 6], [1, 2, 3], [0]];
const calcOperators = ["+", "-", "×", "÷"];
const equalSign = "=";
const clear = "C";
const Calculator = () =&amp;gt; {
&lt;/span&gt;&lt;span class="gi"&gt;+  const [value, setValue] = useState("");
&lt;/span&gt;  return (
    &amp;lt;div className="calculator"&amp;gt;
      &amp;lt;h1&amp;gt;Calculator&amp;lt;/h1&amp;gt;
&lt;span class="gi"&gt;+     &amp;lt;input
+      type="text"
+      defaultValue={value}
+      placeholder="calculate"
+      disabled
+     /&amp;gt;
&lt;/span&gt;      &amp;lt;div role="grid"&amp;gt;
        {rows.map((row, i) =&amp;gt; {
          return (
            &amp;lt;Fragment key={row.toString()}&amp;gt;
              &amp;lt;div role="row"&amp;gt;
                {i === 3 &amp;amp;&amp;amp; &amp;lt;button&amp;gt;{clear}&amp;lt;/button&amp;gt;}
                {row.map((n) =&amp;gt; (
                  &amp;lt;button key={n}&amp;gt;{n}&amp;lt;/button&amp;gt;
                ))}
                {i === 3 &amp;amp;&amp;amp; &amp;lt;button&amp;gt;{equalSign}&amp;lt;/button&amp;gt;}
              &amp;lt;/div&amp;gt;
            &amp;lt;/Fragment&amp;gt;
          );
        })}
        {calcOperators.map((c) =&amp;gt; (
          &amp;lt;button key={c}&amp;gt;{c.toString()}&amp;lt;/button&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;export default Calculator;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fq923yccsi35exayrqite.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fq923yccsi35exayrqite.PNG" alt="calculator app with input" width="265" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Make it display the user's inputs
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;displays users inputs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&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;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&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;plus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;two&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByPlaceholderText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// @ts-ignore&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1+2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;displays multiple users inputs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&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;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&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;three&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3&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;five&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5&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;divide&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;÷&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;mul&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;×&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;minus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;three&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mul&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;two&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;minus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;five&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByPlaceholderText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// @ts-ignore&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3×2-1÷5&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;Pass the tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;               &amp;lt;div role="row"&amp;gt;
                 {i === 3 &amp;amp;&amp;amp; &amp;lt;button&amp;gt;{clear}&amp;lt;/button&amp;gt;}
                 {row.map((n) =&amp;gt; (
&lt;span class="gd"&gt;-                  &amp;lt;button key={n}&amp;gt;{n}&amp;lt;/button&amp;gt;
&lt;/span&gt;&lt;span class="gi"&gt;+                  &amp;lt;button
+                    onClick={() =&amp;gt; setValue(value.concat(n.toString()))}        
+                    key={n}
+                  &amp;gt;
+                    {n}
+                  &amp;lt;/button&amp;gt;
&lt;/span&gt;                 ))}
                 {i === 3 &amp;amp;&amp;amp; &amp;lt;button&amp;gt;{equalSign}&amp;lt;/button&amp;gt;}
               &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;         {calcOperators.map((c) =&amp;gt; (
&lt;span class="gd"&gt;-          &amp;lt;button key={c}&amp;gt;{c.toString()}&amp;lt;/button&amp;gt;
&lt;/span&gt;&lt;span class="gi"&gt;+          &amp;lt;button onClick={() =&amp;gt; setValue(value.concat(c))} key={c}&amp;gt;
+            {c.toString()}
+          &amp;lt;/button&amp;gt;
&lt;/span&gt;         ))}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Can it calculate?
&lt;/h2&gt;

&lt;p&gt;Alright, so up until now we just wrote some tests to check if our calculator displays the right stuff, but let us write some tests for it to actually calculate something:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculate based on users inputs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&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;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&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;plus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;+&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;equal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;two&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;equal&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByPlaceholderText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="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;HTMLElement&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculate based on multiple users inputs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&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;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&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;three&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3&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;five&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5&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;divide&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;÷&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;mul&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;×&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;minus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&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;equal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;three&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mul&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;two&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;minus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;divide&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;five&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;equal&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByPlaceholderText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="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;HTMLElement&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5.8&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;Notice in our second test we also check that the operations are executed in the correct order:&lt;br&gt;
&lt;code&gt;3*2-1÷5 = 6-0.2 = 5.8&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And, let us make this pass. At this stage, we can use the unsafe &lt;code&gt;eval&lt;/code&gt; function, which we will refactor later. Remember, we only need to pass the tests. We can always write a test to propose why our current implementation is not ok.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;const rows = [[7, 8, 9], [4, 5, 6], [1, 2, 3], [0]];
&lt;/span&gt; const calcOperators = ["+", "-", "×", "÷"];
 const equalSign = "=";
 const clear = "C";
&lt;span class="gi"&gt;+
+const calculateExpression = (expression: string) =&amp;gt; {
+  const mulRegex = /×/g;
+  const divRegex = /÷/g;
+
+  const toEvaluate = expression.replace(mulRegex, "*").replace(divRegex, "/");
+
+  // todo - refactor eval later
+  const result = eval(toEvaluate);
+  return result;
+};
+
&lt;/span&gt; const Calculator = () =&amp;gt; {
   const [value, setValue] = useState("");
&lt;span class="gi"&gt;+
+  const calculate = () =&amp;gt; {
+    const results = calculateExpression(value);
+    setValue(results);
+  };
+
&lt;/span&gt;   return (
     &amp;lt;div className="calculator"&amp;gt;
       &amp;lt;h1&amp;gt;Calculator&amp;lt;/h1&amp;gt;
&lt;span class="p"&gt;@@ -29,7 +47,7 @@&lt;/span&gt; const Calculator = () =&amp;gt; {
                     {n}
                   &amp;lt;/button&amp;gt;
                 ))}
&lt;span class="gd"&gt;-                {i === 3 &amp;amp;&amp;amp; &amp;lt;button&amp;gt;{equalSign}&amp;lt;/button&amp;gt;}
&lt;/span&gt;&lt;span class="gi"&gt;+                {i === 3 &amp;amp;&amp;amp; &amp;lt;button onClick={calculate}&amp;gt;{equalSign}&amp;lt;/button&amp;gt;}
&lt;/span&gt;               &amp;lt;/div&amp;gt;
             &amp;lt;/Fragment&amp;gt;
           );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Can use clear button
&lt;/h2&gt;

&lt;p&gt;The test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;can clear results&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;render&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;Calculator&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&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;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&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;plus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;+&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;clear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;one&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;two&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;fireEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clear&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByPlaceholderText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="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;HTMLElement&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;const Calculator = () =&amp;gt; {
&lt;/span&gt;     setValue(results);
   };
&lt;span class="gi"&gt;+ 
+  const clearValue = () =&amp;gt; setValue("");
+
&lt;/span&gt;   return (
     &amp;lt;div className="calculator"&amp;gt;
       &amp;lt;h1&amp;gt;Calculator&amp;lt;/h1&amp;gt;
&lt;span class="p"&gt;@@ -38,7 +40,7 @@&lt;/span&gt; const Calculator = () =&amp;gt; {
           return (
             &amp;lt;Fragment key={row.toString()}&amp;gt;
               &amp;lt;div role="row"&amp;gt;
&lt;span class="gd"&gt;-                {i === 3 &amp;amp;&amp;amp; &amp;lt;button&amp;gt;{clear}&amp;lt;/button&amp;gt;}
&lt;/span&gt;&lt;span class="gi"&gt;+                {i === 3 &amp;amp;&amp;amp; &amp;lt;button onClick={clearValue}&amp;gt;{clear}&amp;lt;/button&amp;gt;}
&lt;/span&gt;                 {row.map((n) =&amp;gt; (
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Back to calculating stuff
&lt;/h2&gt;

&lt;p&gt;Alright, so at this point, we maybe want to test more scenarios for the calculate function. So I think it makes more sense to write those tests directly on the &lt;code&gt;calculateExpression&lt;/code&gt; function. &lt;/p&gt;

&lt;p&gt;So we will export it and write some extra tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculateExpression&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;correctly computes for 2 numbers with +&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1+1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10+10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;11+345&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;356&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;correctly substracts 2 numbers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;11-12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;correctly multiples 2 numbers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1×1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10×0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;11×-12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;132&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;correctly divides 2 numbers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1÷1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10÷2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;144÷12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;division by 0 returns 0 and logs exception&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorSpy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spyOn&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1÷0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorSpy&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledTimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="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;Our tests still pass, except for the one with the division by 0. That's good. Let's fix that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-const calculateExpression = (expression: string) =&amp;gt; {
&lt;/span&gt;&lt;span class="gi"&gt;+export const calculateExpression = (expression: string) =&amp;gt; {
&lt;/span&gt;   const mulRegex = /×/g;
   const divRegex = /÷/g;
&lt;span class="gi"&gt;+  const divideByZero = /\/0/g;
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;   const toEvaluate = expression.replace(mulRegex, "*").replace(divRegex, "/");
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-  // todo - refactor eval later
-  const result = eval(toEvaluate);
-  return result;
&lt;/span&gt;&lt;span class="gi"&gt;+  try {
+    if (divideByZero.test(toEvaluate)) {
+      throw new Error("Can not divide by 0!");
+    }
+
+    // todo - refactor eval later
+    const result = eval(toEvaluate);
+
+    return result;
+  } catch (err) {
+    console.error(err);
+    return undefined;
+  }
&lt;/span&gt; };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, more tests for some extra cases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;handles multiple operations&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1÷1×2×2+3×22&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;handles trailing operator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1÷1×2×2+3×22+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;handles empty expression&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Watercooler 🌊
&lt;/h2&gt;

&lt;p&gt;Alright, if you made it until here, congrats! 🙌 You are learning how to write code in a TDD way. &lt;/p&gt;

&lt;p&gt;Please notice, at this point, the mentality is to add tests and see what tests fail. Maybe some will pass, some will fail, but we want to make sure we have a test-first approach and we are careful with the quality of the tests. If our tests are good, and they all pass, the app will perform well.&lt;/p&gt;

&lt;p&gt;So let us fix the 2 failing tests we have now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt; const clear = "C";
&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gi"&gt;+const getLastChar = (str: string) =&amp;gt; (str.length ? str[str.length - 1] : "");
+const isNumber = (str: string) =&amp;gt; !isNaN(Number(str));
+
&lt;/span&gt; export const calculateExpression = (expression: string) =&amp;gt; {
&lt;span class="gi"&gt;+  if (!expression || expression.length === 0) {
+    return;
+  }
+
&lt;/span&gt;   const mulRegex = /×/g;
   const divRegex = /÷/g;
   const divideByZero = /\/0/g;
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gd"&gt;-  const toEvaluate = expression.replace(mulRegex, "*").replace(divRegex, "/");
&lt;/span&gt;&lt;span class="gi"&gt;+  let toEvaluate = expression.replace(mulRegex, "*").replace(divRegex, "/");
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;   try {
     if (divideByZero.test(toEvaluate)) {
       throw new Error("Can not divide by 0!");
     }
&lt;span class="gi"&gt;+ 
+    const lastCharaterIsNumber = isNumber(getLastChar(toEvaluate));
+
+    if (!lastCharaterIsNumber) {
+      toEvaluate = toEvaluate.slice(0, -1);
+    }
+
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Get rid of eval
&lt;/h2&gt;

&lt;p&gt;Remember when we said we will change eval to something else. Yes, we want to avoid it as our linter and our common sense dictates we should not use it. &lt;/p&gt;

&lt;p&gt;Luckily there is a package that does exactly what we want. Pass a string as an expression and safely evaluate it:&lt;br&gt;
&lt;code&gt;yarn add mathjs @types/mathjs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gi"&gt;+import { evaluate } from "mathjs";
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="gd"&gt;-    // todo - refactor eval later
-    const result = eval(toEvaluate);
&lt;/span&gt;&lt;span class="gi"&gt;+    const result = evaluate(toEvaluate);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What... our tests still pass? Cool!&lt;/p&gt;

&lt;h2&gt;
  
  
  Style the app
&lt;/h2&gt;

&lt;p&gt;But the app is really ugly.. Let's fix that. &lt;/p&gt;

&lt;p&gt;First, let us declare some variables in the &lt;code&gt;index.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--theme-color-dark-10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#006ba1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--theme-color-dark-20&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#005a87&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--theme-color-background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fed800&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;In the body we will just add the background color and leave the rest of the styles as they are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt; body {
&lt;span class="gi"&gt;+  background-color: var(--theme-color-background);
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will need to add a bit more structure to our &lt;code&gt;Calculator.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Fragment&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="s2"&gt;react&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;evaluate&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;mathjs&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./Calculator.css&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;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&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;calcOperators&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;+&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;×&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;÷&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;equalSign&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;=&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;clear&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&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;getLastChar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;:&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;isNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&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;calculateExpression&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mulRegex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/×/g&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;divRegex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/÷/g&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;divideByZero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;0/g&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;toEvaluate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mulRegex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;divRegex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&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;divideByZero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toEvaluate&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Can not divide by 0!&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;lastCharaterIsNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;isNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getLastChar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toEvaluate&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;lastCharaterIsNumber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;toEvaluate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;toEvaluate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;toEvaluate&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;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;Calculator&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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;calculate&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculateExpression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&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;clearValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="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;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculator&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;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&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;input&lt;/span&gt;
        &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;defaultValue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculate&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;disabled&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;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculator-buttons-container&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;div&lt;/span&gt; &lt;span class="nx"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="o"&gt;&amp;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;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;clearValue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;                  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;
                      &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                      &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()))}&lt;/span&gt;
                    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                  &lt;span class="p"&gt;))}&lt;/span&gt;
                  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;equalSign&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&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;/div&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;/Fragment&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="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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calculator-operators&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;calcOperators&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;))}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="p"&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="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="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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will also add a &lt;code&gt;Calculator.css&lt;/code&gt; file, with:&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;.calculator&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--theme-color-dark-20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.calculator&lt;/span&gt; &lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;13rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.4rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3rem&lt;/span&gt; &lt;span class="m"&gt;0.3rem&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt; &lt;span class="m"&gt;0.3rem&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;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--theme-color-dark-20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="m"&gt;-7px&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--theme-color-dark-10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.calculator&lt;/span&gt; &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3.5rem&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;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--theme-color-dark-20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.calculator-buttons-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.calculator-operators&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&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;Looks better.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fal6a8t88aa8dbqg82yra.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fal6a8t88aa8dbqg82yra.png" alt="styled calculator" width="403" height="530"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;I want to stop here - still, the app has some bugs and things that can be fixed. &lt;/p&gt;

&lt;p&gt;If you are up for it, &lt;em&gt;fix them in a TDD style&lt;/em&gt; 🔥.&lt;/p&gt;

&lt;p&gt;Here's the &lt;a href="https://github.com/alexandrudanpop/tdd-calculator" rel="noopener noreferrer"&gt;repo&lt;/a&gt; for this coding exercise.&lt;/p&gt;

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

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



&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Microfrontends explained</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Sun, 17 Jan 2021 14:53:49 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/microfrontends-explained-22i1</link>
      <guid>https://dev.to/alexandrudanpop/microfrontends-explained-22i1</guid>
      <description>&lt;p&gt;I'm addressing this topic because I get a feel that &lt;strong&gt;Microfrontends&lt;/strong&gt; are no longer just a buzzword, they are being adopted rapidly in large web applications.&lt;/p&gt;

&lt;p&gt;Microfrontends might be the next big thing in frontend development.&lt;/p&gt;

&lt;p&gt;Let me tell you why!&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Microfrontends?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Microfrontends&lt;/strong&gt; is a software architecture pattern for frontend code. It is influenced by the backend &lt;strong&gt;microservices&lt;/strong&gt; architecture pattern.&lt;/p&gt;

&lt;p&gt;To understand microfrontends and why do we need them, we first need to know a bit about microservices.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Microservice architecture – a variant of the service-oriented architecture (SOA) structural style – arranges an application as a collection of loosely coupled services. In a microservices architecture, services are fine-grained and the protocols are lightweight. (&lt;a href="https://en.wikipedia.org/wiki/Microservices" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An example - if we would have a &lt;strong&gt;Webshop&lt;/strong&gt; microservice backend, in which each service is owned by a team, we could have the following microservices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Products&lt;/li&gt;
&lt;li&gt;Products catalog (management)&lt;/li&gt;
&lt;li&gt;Reporting&lt;/li&gt;
&lt;li&gt;Customer&lt;/li&gt;
&lt;li&gt;Orders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; This is a simplified view of a microservices architecture &amp;amp; in a real-world application we could have tens or hundreds of microservices.&lt;/p&gt;

&lt;p&gt;In the frontend world, for an application like this - we could have:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fro0thnkwyc8sigv9cydn.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fro0thnkwyc8sigv9cydn.PNG" alt="Webshop Microfrontend" width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice a few things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;each microfrontend can be built with different technologies&lt;/li&gt;
&lt;li&gt;each microfrontend can be owned by a team&lt;/li&gt;
&lt;li&gt;each microfrontend can depend on only one microservice&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;What advantages does this bring? Well, quite a few. &lt;/p&gt;

&lt;p&gt;Remember that time you joined a dev team on an old project and the frontend was still built with XSLT &amp;amp; jQuery? A re-write was not even considered and you had to use those old technologies to add new features and fix bugs. &lt;/p&gt;

&lt;p&gt;Even if you could convince the stakeholders to do a re-write, and you have a new codebase for 1-3 years. What makes you think in 10 years it won't be perceived as XSLT &amp;amp; jQuery are today?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Microfrontends&lt;/strong&gt; promise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;smaller, more maintainable codebases&lt;/li&gt;
&lt;li&gt;each microfrontend can be written with different technologies - this removes as much as possible external dependencies&lt;/li&gt;
&lt;li&gt;each microfrontend can be handled by a different team - reduce cross-team dependencies&lt;/li&gt;
&lt;li&gt;we can update/upgrade or delete microfrontends whenever we think it is needed &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a business a commitment needs to be taken - we will constantly be replacing old micro/services/frontends with new ones. So we will continuously evolve our codebases.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Example:&lt;br&gt;
We could delete an &lt;strong&gt;old framewok.X.js&lt;/strong&gt; microfrontend and completely swap it with the new one written in &lt;strong&gt;framewok.Y.js&lt;/strong&gt;. This reduces the risk of an entire app rewrite. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Different approaches
&lt;/h2&gt;

&lt;p&gt;There are different approaches to build microfrontends.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1 - One microfrontend for each microservice 🤖
&lt;/h3&gt;

&lt;p&gt;This option is fine when the microservices architecture is based on features. We can have a feature microservice - for example for checkout, then we also build a checkout microfrontend. The advantage here is that each microfrontend needs to know exactly about one single backend API.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2 - Web components 🌟
&lt;/h3&gt;

&lt;p&gt;Those days, a lot of UI frameworks provide support for web components (Svelte being pretty good in this area).&lt;/p&gt;

&lt;p&gt;We can have a legacy UI and constantly swapping old code with new Web components. Each new web component can be a microfrontend written in Svelte, Vue, vanilla JS, or whatever you prefer. &lt;/p&gt;

&lt;p&gt;The code for each web component can be hosted on a different server, so individual deployment can be done easily without affecting the rest of the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 3 - using a Microfrontend tool 🛠️
&lt;/h3&gt;

&lt;p&gt;You can use a tool like &lt;a href="https://single-spa.js.org/" rel="noopener noreferrer"&gt;single-spa&lt;/a&gt; to achieve the wire up of different microfrontends. &lt;/p&gt;

&lt;p&gt;This approach fits best for building new microfrontend applications. If you decide to use &lt;strong&gt;single-spa&lt;/strong&gt; make sure you read thoroughly their docs and look at their &lt;a href="https://single-spa.js.org/docs/recommended-setup/" rel="noopener noreferrer"&gt;recommendations&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 4 - Module federation ⚙️
&lt;/h3&gt;

&lt;p&gt;This is a Webpack 5 feature that achieves:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Multiple separate builds should form a single application. These separate builds should not have dependencies between each other, so they can be developed and deployed individually. (&lt;a href="https://webpack.js.org/concepts/module-federation/" rel="noopener noreferrer"&gt;webpack&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As Webpack Module Federation seems quite stable, this option looks the most exciting at least for projects that use Webpack. Module federation allows for modules sharing so things like loading the same version of React or Angular twice can be avoided with proper config. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: you can also combine those options to achieve the architecture that you need. For example, you can use &lt;code&gt;single-spa&lt;/code&gt; with &lt;code&gt;module federation&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can I afford microfrontends?
&lt;/h2&gt;

&lt;p&gt;Microfrontends are certainly not for every use case.&lt;/p&gt;

&lt;p&gt;Micro/frontends/services tackle the problem of software rewrite and software scalability. Independent deployments are also very important for micro/frontends/services.&lt;/p&gt;

&lt;p&gt;It also relies on the fact that the company has a big dev team, so in this case, it's much easier if not all devs work on a single codebase, stepping on each other's toes all day. Instead, those devs will be split up in teams, each working on a set of a few or maybe only one micro/frontends/service.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problems with microfrontends
&lt;/h2&gt;

&lt;p&gt;Obviously, there is nothing without a set of disadvantages, so let's look into what are the drawbacks of microfrontends:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;hard to test the entire codebase locally when there are many micro/frontends/service&lt;/li&gt;
&lt;li&gt;very strict interfaces need to be designed upfront&lt;/li&gt;
&lt;li&gt;more codebases to maintain, upgrade &amp;amp; address security risks&lt;/li&gt;
&lt;li&gt;performance cost on the end-user, having to download the applications code for each microfrontend&lt;/li&gt;
&lt;li&gt;the communication between microfrontends can get very complex&lt;/li&gt;
&lt;li&gt;the infrastructure &amp;amp; deployment will probably get more complex as well&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  More Resources
&lt;/h2&gt;

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

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

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;I hope this article makes microfrontends and what they represent more clear to you, thank you for reading!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Top resources to learn Angular in 2021</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Sun, 03 Jan 2021 16:51:19 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/top-resources-to-learn-angular-in-2021-1f27</link>
      <guid>https://dev.to/alexandrudanpop/top-resources-to-learn-angular-in-2021-1f27</guid>
      <description>&lt;p&gt;Angular is a very in-demand framework in 2021, with a similar programming model based on components as React or Vue. &lt;/p&gt;

&lt;p&gt;It bakes in other concepts like dependency injection, routing, HTTP client based on observables, 2-way data binding &amp;amp; a strong CLI tooling.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Angular can surely be a strong tool under your belt, so for this reason I will go into how you can quickly learn it and be productive with it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  No one reads the docs
&lt;/h2&gt;

&lt;p&gt;Oh well, I am the first to say that I rarely find everything I need to learn a new tool in the docs. Lots of times I need to read other blog posts, watch some videos, and go through stack overflow for some advanced topics. &lt;/p&gt;

&lt;p&gt;But with &lt;strong&gt;Angular&lt;/strong&gt; I managed to learn mostly from their &lt;a href="https://angular.io/docs" rel="noopener noreferrer"&gt;docs&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;You can spend a few hours to study the docs, and they will get you started &amp;amp; understanding: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using the CLI&lt;/li&gt;
&lt;li&gt;Components&lt;/li&gt;
&lt;li&gt;Templates&lt;/li&gt;
&lt;li&gt;Directives&lt;/li&gt;
&lt;li&gt;Dependency injection &lt;/li&gt;
&lt;li&gt;Angular Modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the core concepts are understood, you can proceed with building some sample applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample applications
&lt;/h2&gt;

&lt;p&gt;The Angular website will teach you this too. &lt;br&gt;
You can check out how to build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://angular.io/start" rel="noopener noreferrer"&gt;Store app&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/tutorial" rel="noopener noreferrer"&gt;Tour of heroes app&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another small app you can start building is a &lt;em&gt;Currency Converter&lt;/em&gt;, and you can follow this tutorial:&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/j8OGOfKatBw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding styles guide
&lt;/h2&gt;

&lt;p&gt;The nicest thing in Angular is that being an opinionated framework - it has best practices and the coding styles are &lt;a href="https://angular.io/guide/styleguide#angular-coding-style-guide" rel="noopener noreferrer"&gt;documented&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;I think it's nice for once to work with a framework with opinionated:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;naming conventions&lt;/li&gt;
&lt;li&gt;folder structure&lt;/li&gt;
&lt;li&gt;modules structure&lt;/li&gt;
&lt;li&gt;and much more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This leaves teams with more time to build and less time to dispute those topics.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to set up Angular projects
&lt;/h2&gt;

&lt;p&gt;There are two main ways to setup Angular projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Angular CLI&lt;/li&gt;
&lt;li&gt;Nx&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;a href="https://cli.angular.io/" rel="noopener noreferrer"&gt;Angular CLI&lt;/a&gt; is more than capable of generating the boilerplate of Angular applications. You can also have multiple projects or apps in it using the &lt;a href="https://angular.io/guide/file-structure" rel="noopener noreferrer"&gt;Angular Workspaces&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://nx.dev/angular" rel="noopener noreferrer"&gt;Nx&lt;/a&gt; you will get more of a monorepo experience, and it will configure the testing tools for Angular a bit differently - using &lt;em&gt;Jest&lt;/em&gt; and &lt;em&gt;Cypress&lt;/em&gt; instead of &lt;em&gt;Karma&lt;/em&gt; and &lt;em&gt;Jasmine&lt;/em&gt;. Linting, code formatting, and some other nice things are also configured when using Nx.&lt;/p&gt;

&lt;h2&gt;
  
  
  What other libs should I use
&lt;/h2&gt;

&lt;p&gt;When using &lt;em&gt;Angular&lt;/em&gt;, there are a lot of libraries for pretty much anything you need to do in a UI. There are of course very popular UI kits like &lt;a href="https://material.angular.io/" rel="noopener noreferrer"&gt;Angular Material&lt;/a&gt; or &lt;a href="https://ng-bootstrap.github.io/#/home" rel="noopener noreferrer"&gt;ng-Bootstrap&lt;/a&gt; and many others. &lt;/p&gt;

&lt;p&gt;For a comprehensive list of libraries, you can further explore &lt;a href="https://angular.io/resources?category=development" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  I want to learn more
&lt;/h2&gt;

&lt;p&gt;There are many resources out there to learn Angular, but I can only recommend the ones that I looked at. If you can afford Pluralsight (or you can also look at their free trial option) - you can check out their Angular courses - there are plenty of them. Would start with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://app.pluralsight.com/library/courses/angular-2-getting-started-update/table-of-contents" rel="noopener noreferrer"&gt;Angular: Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://app.pluralsight.com/library/courses/angular-component-communication/table-of-contents" rel="noopener noreferrer"&gt;Angular Component Communication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Angular&lt;/strong&gt; is a powerful framework, that many companies use especially in the enterprise space, and can be very beneficial to learn.&lt;/p&gt;

&lt;p&gt;Thanks for reading and hope this content helps you get started with Angular! 🥳&lt;/p&gt;

&lt;p&gt;What resources did you use to learn Angular?&lt;/p&gt;

&lt;p&gt;If you like this article chances are you will also enjoy what I post on &lt;a href="https://twitter.com/alexandrudanpop" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Configuring Next.js with Typescript, Tailwind CSS, ESLint, and Jest</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Sat, 05 Dec 2020 13:28:51 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/configuring-next-js-with-typescript-tailwind-css-eslint-jest-46ob</link>
      <guid>https://dev.to/alexandrudanpop/configuring-next-js-with-typescript-tailwind-css-eslint-jest-46ob</guid>
      <description>&lt;p&gt;&lt;strong&gt;Next.js&lt;/strong&gt; might be the best way to set up a new React project in 2020 &amp;amp; 2021. I don't even know if it's worth to appraise it even more, but yeah the Next.js team did a great job!&lt;/p&gt;

&lt;p&gt;It just stands out with all the needed features to build bulletproof web applications: hybrid approach with SSR, SSG, ISR, hosting can be done on the &lt;strong&gt;Vercel&lt;/strong&gt; platform on a serverless runtime. Static assets are where they belong, hosted in a CDN edge network for fast delivery. 🏃🏃🏃&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So let's configure Next with our favorite tools: Typescript &amp;amp; Tailwind CSS, and we'll use ESLint for lining and Jest to write tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Setup Next.js with TS
&lt;/h2&gt;

&lt;p&gt;Go to a terminal and run (replace &lt;em&gt;next-ts-tailwind&lt;/em&gt; with your desired app name):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;npx create-next-app next-ts-tailwind&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cd next-ts-tailwind&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;tsconfig.json&lt;/code&gt; file:
&lt;code&gt;touch tsconfig.json&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"allowJs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"alwaysStrict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"forceConsistentCasingInFileNames"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"isolatedModules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"jsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"preserve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES2020"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esnext"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"noEmit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"noFallthroughCasesInSwitch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"noUnusedLocals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"noUnusedParameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"resolveJsonModule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"skipLibCheck"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esnext"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"exclude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"node_modules"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"include"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"**/*.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"**/*.tsx"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add TS dependencies&lt;br&gt;
&lt;code&gt;yarn add --dev typescript @types/react @types/node&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to /pages/index.js and change it to index.tsx&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run &lt;code&gt;yarn dev&lt;/code&gt; - all good and running on &lt;code&gt;http://localhost:3000/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up Tailwind CSS
&lt;/h2&gt;

&lt;p&gt;The Tailwind team already put together an &lt;a href="https://tailwindcss.com/docs/guides/nextjs" rel="noopener noreferrer"&gt;excellent tutorial&lt;/a&gt; to set this up with Next.js, but there are just a few changes needed for it to work with TS files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;yarn add tailwindcss postcss autoprefixer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;yarn add tailwindcss@npm:@tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;npx tailwindcss init -p&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to &lt;code&gt;tailwind.config.js&lt;/code&gt; and change &lt;code&gt;purge: [],&lt;/code&gt; with:&lt;br&gt;
&lt;code&gt;purge: ["./components/**/*.{js,ts,jsx,tsx}", "./pages/**/*.{js,ts,jsx,tsx}"],&lt;/code&gt;&lt;br&gt;
This makes sure that when we build for production &lt;strong&gt;only&lt;/strong&gt; the classes that we use from the tailwind framework will remain in the final production css file. It's called &lt;em&gt;tree shaking&lt;/em&gt; if you need a more fancy term to impress your grandma. 👵&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Include tailwind at the top of your ./styles/global.css file&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Go to your &lt;code&gt;pages/_app.js&lt;/code&gt; (that you should rename to _app.tsx) component and make sure it looks like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../styles/globals.css&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="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppProps&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;next/app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyApp&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="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;AppProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To test tailwind is working go to &lt;code&gt;index.tsx&lt;/code&gt; and change it to:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Head&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;next/head&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="nx"&gt;styles&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;../styles/Home.module.css&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Create Next App&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;link&lt;/span&gt; &lt;span class="na"&gt;rel&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"icon"&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/favicon.ico"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg-yellow-100 border-l-4 border-yellow-500 text-yellow-700 p-4"&lt;/span&gt;
        &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;
      &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"font-bold"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Be Warned&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;You are using Tailwind CSS!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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;Running the app with &lt;code&gt;yarn dev&lt;/code&gt; you should see: &lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F18gjgdj3xvyhq95pzfr7.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F18gjgdj3xvyhq95pzfr7.PNG" alt="tailwind example" width="466" height="283"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up ESLint
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;yarn add --dev eslint&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npx eslint --init&lt;/code&gt; and answer with the following:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6yt7uoumpylp3e7cl8nk.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6yt7uoumpylp3e7cl8nk.PNG" alt="initialize ESLint" width="800" height="199"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to &lt;code&gt;package.json&lt;/code&gt; and in the scripts section, add:&lt;br&gt;
&lt;code&gt;"lint": "eslint ."&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now, if you try &lt;code&gt;yarn lint&lt;/code&gt;, you will see a bunch of errors. Go to &lt;code&gt;eslintrc.json&lt;/code&gt; and modify it to:&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;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"browser"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"es2021"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"jest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"extends"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"eslint:recommended"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"plugin:react/recommended"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"plugin:@typescript-eslint/recommended"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parser"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@typescript-eslint/parser"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"settings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"detect"&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Automatically&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;detect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;react&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;version&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"parserOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ecmaFeatures"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"jsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ecmaVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sourceType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"module"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"@typescript-eslint"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"react/react-in-jsx-scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"off"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"@typescript-eslint/explicit-module-boundary-types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"off"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that I also disabled the &lt;code&gt;explicit-module-boundary-types&lt;/code&gt; because I like TS to do its job and infer the return types for me, but you can remove that if you like to always add return types to your functions. There will be other lint warnings that you will probably not like and turn off, that's totally fine.&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;yarn lint&lt;/code&gt; now should result in no warnings and errors. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that you should probably use the &lt;a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint" rel="noopener noreferrer"&gt;ESLint VSCode extension&lt;/a&gt; if you use VSCode. This way you can see errors and fix them as they pop-up while you code. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Adding Jest
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;yarn add --dev babel-jest jest @types/jest @types/babel-generator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;in &lt;code&gt;package.json&lt;/code&gt; scripts section - add &lt;code&gt;"test": "jest --watch"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;create a &lt;code&gt;.babelrc&lt;/code&gt; file in the root and add in it:
&lt;/li&gt;
&lt;/ul&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;"presets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"next/babel"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Create a &lt;code&gt;jest.config.js&lt;/code&gt; with:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;setupFilesAfterEnv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;rootDir&amp;gt;/jest.setup.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;testPathIgnorePatterns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;rootDir&amp;gt;/.next/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;rootDir&amp;gt;/node_modules/&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;ul&gt;
&lt;li&gt;And a &lt;code&gt;jest.setup.ts&lt;/code&gt; with:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@testing-library/jest-dom&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;Next, let's add the &lt;strong&gt;React testing&lt;/strong&gt; packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;yarn add --dev @testing-library/react @testing-library/dom @testing-library/jest-dom @testing-library/user-event&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create in the components folder a file &lt;code&gt;SomeComp.test.tsx&lt;/code&gt; with:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@testing-library/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;function&lt;/span&gt; &lt;span class="nf"&gt;SomeComp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SomeComp&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;renders Hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getByText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SomeComp&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;yarn test&lt;/code&gt;:&lt;br&gt;
 PASS  components/SomeComp.test.tsx&lt;br&gt;
  SomeComp&lt;br&gt;
    √ renders Hello (24 ms)&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;If you got this far congrats - you have a Next.js app configured with TS, Tailwind CSS, ESLint, and the testing is set up with Jest and RTL. 🥳&lt;/p&gt;

&lt;p&gt;If you got stuck or prefer to see the working solution directly you can check it out on &lt;a href="https://github.com/alexandrudanpop/nextjs-ts-tailwind-eslint-jest" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I post more cool content on &lt;a href="https://twitter.com/alexandrudanpop" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; 🔥🔥.&lt;/p&gt;

</description>
      <category>react</category>
      <category>css</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>FE Jargon you should know - SSG,  SSR,  CSR,  VDOM</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Fri, 27 Nov 2020 11:16:08 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/fe-jargon-you-should-know-ssg-ssr-csr-vdom-22b0</link>
      <guid>https://dev.to/alexandrudanpop/fe-jargon-you-should-know-ssg-ssr-csr-vdom-22b0</guid>
      <description>&lt;p&gt;If you have heard lately talks about &lt;strong&gt;SSG, SSR, CSR, VDOM&lt;/strong&gt; - and you were like: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What the heck is that? 🤔 &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then this article is for you and aims to be a &lt;em&gt;mini dictionary&lt;/em&gt; for modern frontend terminology and jargon.&lt;/p&gt;

&lt;p&gt;Please leave a 🧡 &amp;amp; 🦄 if you enjoy this article &amp;amp; follow me on &lt;a href="https://twitter.com/alexandrudanpop" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; where I post more cool content.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSR
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Client side rendering&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The general way of building frontend applications those days is writing them using libraries like &lt;strong&gt;React, Angular, Vue, or Svelte&lt;/strong&gt; and then building them in a javascript bundle. This bundle is referenced in our single HTML file. CSR (client-side rendering) is rendering our markup in the browser. If that sounds complicated, look at the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fht4ffj3rdmj9a22x6rz3.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fht4ffj3rdmj9a22x6rz3.PNG" alt="CSR flow" width="800" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  This image represents two stages:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Dotted gray line represents the deployment of our FE code to a server. As you can see the deploy step generates an HTML file and a bundle.js file.&lt;/li&gt;
&lt;li&gt;Dashed green line represents how a browser gets to paint our app: 

&lt;ol&gt;
&lt;li&gt;Browser - STEP 1 - The browser requests the HTML file&lt;/li&gt;
&lt;li&gt;Browser - STEP 2 - The browser requests the JS file&lt;/li&gt;
&lt;li&gt;Browser - STEP 3 - Perform Client-side rendering (CSR)&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;✅ As an advantage - &lt;strong&gt;CSR is the most straight-forward way to build a SPA&lt;/strong&gt; (single page app). So it's the easiest and fastest way for developers.&lt;/p&gt;

&lt;p&gt;❗ The main disadvantage of this approach is that after &lt;em&gt;Step 1&lt;/em&gt;, we cannot show anything to the user. &lt;strong&gt;We need to wait until JS is downloaded, parsed &amp;amp; executed (&lt;em&gt;Step 3&lt;/em&gt;), and only then our users can see the app.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SSG
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Static site generation&lt;/strong&gt; - this is when you are pre-rendering a website with a framework or library that is producing static HTML pages. &lt;/p&gt;

&lt;p&gt;For example, you could be writing a React application, but you want its output to be static HTML pages. This might be because you enjoy React, but you also want the performance of pre-rendered content. Something like a blog, a presentation website, or an e-shop. &lt;/p&gt;

&lt;p&gt;If the content doesn't change often, it makes sense to render at build time, instead of loading all the javascript in the browser and only then building the HTML that the user will interact with.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa5bsiornhtwefefakmdb.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa5bsiornhtwefefakmdb.PNG" alt="SSG flow" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Comparing to CSR -&amp;gt; you can see we have lots of HTML files resulting from our build step. We also have HTML available to render in the browser in Step 2.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Additionally, SSG sites can be hydrated after the initial page is loaded. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok, if that sounded weird, that just means after the initial HTML page is loaded, it can also load the CSR library so when the user navigates to the next page, it happens instantly, rendered on the client, without other network calls.&lt;/p&gt;

&lt;p&gt;✅ SSG sites will create the &lt;strong&gt;most performant web apps&lt;/strong&gt; provided the hosting is also good.&lt;/p&gt;

&lt;p&gt;❗ Content needs to be fetched always at build time. This means we need to build &amp;amp; deploy every time the content changes. This is &lt;strong&gt;not feasible for highly dynamic content&lt;/strong&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  SSR
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Server-side rendering&lt;/strong&gt;&lt;br&gt;
Server-side rendering is a pretty old technique. Any application that renders HTML on the server can be called an SSR app. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foyveukr28dfjv8hc4u73.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foyveukr28dfjv8hc4u73.PNG" alt="SSR flow" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  But this looks like the SSG pic...
&lt;/h3&gt;

&lt;p&gt;Hmm.. kind of, but here you can see we actually don't treat our server just like a dumb provider of static content, instead we are actually doing something useful with it. We are generating the HTML every time our user needs it. This is slower than SSG because the server needs to compute the HTML.&lt;/p&gt;

&lt;p&gt;The generic &lt;em&gt;code that runs on a server&lt;/em&gt; in this picture could be a &lt;em&gt;Node.js Express App or Ruby or Python&lt;/em&gt;. &lt;strong&gt;The thing that we achieve with this approach is the dynamic control of our content, headers &amp;amp; meta tags (that can serve for SEO)&lt;/strong&gt;. And a plus can also be the performance. We don't stress our app consumers downloading a bunch of JS and only then rendering HTML (CSR), we give it straight away. The caveat is that we need to account for the fact that our server needs to be performant doing the generation &amp;amp; also support the load we throw at it. &lt;/p&gt;

&lt;p&gt;✅ SSR sites provide us the most flexibility in terms of what we want to display to users despite fast content changes &amp;amp; how we optimize our response headers &amp;amp; meta tags for SEO.&lt;/p&gt;

&lt;p&gt;❗ Extra complexity due to the server-side code &amp;amp; we need to scale our server in case we receive more load. SSR and SSG don't have this problem, they can be thrown on a good CDN and that just scales to any load.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;SSR, SSG, CSR - can be combined.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Modern frameworks like &lt;strong&gt;Next.js (for React)&lt;/strong&gt; or &lt;strong&gt;NuxtJS (for Vue)&lt;/strong&gt; allow us to write applications that can serve multiple purposes and we can combine those techniques with it.&lt;/p&gt;
&lt;h2&gt;
  
  
  VDOM
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Virtual DOM&lt;/strong&gt;&lt;br&gt;
The Virtual DOM is an in-memory representation of our UI elements. Frameworks like React, Angular &amp;amp; Vue use a Virtual DOM to &lt;strong&gt;not paint&lt;/strong&gt; in the real DOM the same thing multiple times. Because the real Browser DOM is slow to paint things, those frameworks use a VDOM as an optimization to keep track and only re-paint the things that are necessary.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Next article
&lt;/h2&gt;

&lt;p&gt;The next post will be more about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Micro-frontends&lt;/li&gt;
&lt;li&gt;Building &amp;amp; bundling related topics - CodeSplitting, Transpiling, Tree shaking &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For &lt;strong&gt;React&lt;/strong&gt; specific things to know - I  wrote about it in-depth in &lt;a href="https://blog.alexandrudanpop.dev/posts/react-js-top-things-to-know-3onj/" rel="noopener noreferrer"&gt;my other article.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For a description of more general concepts - you should also read the very nice &lt;a href="https://css-tricks.com/web-nerd-terminology-explained/" rel="noopener noreferrer"&gt;Web Nerd Terminology&lt;/a&gt; blog post on CSS tricks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Hope those explanations help - please leave a 🧡 &amp;amp; 🦄 to support the effort of creating this article. More cool content on &lt;a href="https://twitter.com/alexandrudanpop" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; 🔥🔥.&lt;/p&gt;

&lt;h3&gt;
  
  
  👇 Comment below 👇
&lt;/h3&gt;

&lt;p&gt;Do you use SSR, SSG, CSR, or all of them?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>React.js - Top things to know</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Sun, 08 Nov 2020 18:26:08 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/react-js-top-things-to-know-3onj</link>
      <guid>https://dev.to/alexandrudanpop/react-js-top-things-to-know-3onj</guid>
      <description>&lt;p&gt;&lt;strong&gt;React&lt;/strong&gt; is eating up the web development world - being the defacto library for modern user interfaces, so learning it can bring many advantages. &lt;/p&gt;

&lt;p&gt;In this article, you will be introduced to all things you need to know in order to be a successful React dev. This is not meant to be an in-depth tutorial, but instead an introduction to all needed concepts. You will find extra resources linked here, that can help you get in-depth knowledge of certain topics.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before starting
&lt;/h3&gt;

&lt;p&gt;It is often advised to get HTML, CSS, and JS experience before starting to build applications with a framework like React. So it is best if you study those, before reading this article. Also, would help a lot if you leave a 🧡 &amp;amp; 🦄 if you enjoy this article. &lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  Modern JS features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;spread syntax&lt;/li&gt;
&lt;li&gt;class syntax&lt;/li&gt;
&lt;li&gt;arrow functions&lt;/li&gt;
&lt;li&gt;template strings&lt;/li&gt;
&lt;li&gt;async/await&lt;/li&gt;
&lt;li&gt;ES modules
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/NCwa_xi0Uuc"&gt;
&lt;/iframe&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Modern JS development environment
&lt;/h2&gt;

&lt;p&gt;The target environment for React code is browsers (most of the time, we can also write mobile apps or render apps on the server). Since browsers can't understand all the latest JS features that I just mentioned earlier - we need a bundler and a code compiler - more info ahead. We also need a package manager for downloading all the libraries we want to use - including React, React-DOM, Router, etc.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Note you don't need to understand those very in-depth if you are just starting out, but it makes sense that you have an idea about each of them&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Node.js - our development environment is a &lt;em&gt;Node.js&lt;/em&gt; environment. Our tools - like Webpack or Babel, or Create React App - are Node.js programs. We use Node.js to start our dev environment, build for production, run tests etc.
&lt;/li&gt;
&lt;li&gt;npm (or yarn) - package management - use to install everything we need in our dev environment (React, Router, Babel, Webpack, etc)&lt;/li&gt;
&lt;li&gt;ESLint - watch our code for common programming errors or bad practices - a good linter config will save you of many coding errors and bugs. A lint config will throw errors or warnings when you do something that breaks lint rules (ex not using React hooks correctly)&lt;/li&gt;
&lt;li&gt;Babel compiler - converts modern JS to code that browsers can understand&lt;/li&gt;
&lt;li&gt;Webpack - takes all our code modules (all our files and dependencies) - and spits out a single (or multiple) JS files the browser can understand. We can use different plugins in Webpack to achieve different things (minify the code, bundle and optimize CSS, etc) &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Structure your UIs into reusable components
&lt;/h2&gt;

&lt;p&gt;The most important thing in React development is the concept of components. We will have lots of components that &lt;em&gt;compose&lt;/em&gt; our UI. Here is a simple example of the Dev.to interface broken down into components:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fduo1pyj7n53ifd11vszr.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fduo1pyj7n53ifd11vszr.PNG" alt="Dev.to React components" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Larger chunks of the UI will be composed of many smaller pieces. I didn't break down all the pieces from the LeftPane for example. You can look at it and imagine it contains an Avatar component, that also contains a Picture, Header &amp;amp; Text components. Below is a side navigation component, and so on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn to use React Hooks
&lt;/h2&gt;

&lt;p&gt;React hooks are the modern way of writing React applications. There are a few hooks that you will need in all React applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;useState or useReducer&lt;/li&gt;
&lt;li&gt;useEffect - make sure you understand this one as it's not trivial at first&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Routing
&lt;/h2&gt;

&lt;p&gt;Unless you are building some very small app, you will realize you need to render multiple pages in your app. That's when routing comes in.&lt;/p&gt;

&lt;p&gt;Routing works by rendering a specific set of React components under a route:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;'/' - render HomePage component&lt;/li&gt;
&lt;li&gt;'/about' - render AboutPage component&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Routing can become more complex when we accept in our routes: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URI parameters 
Ex: &lt;code&gt;/employee/{employeeID}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Query parameters
Ex: &lt;code&gt;/employee?{employeeID=1}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Learn ways to manage global state
&lt;/h2&gt;

&lt;p&gt;Global or application level state is a piece of data that is necessary to be stored &lt;em&gt;globally&lt;/em&gt; so it's accessible to multiple components. &lt;/p&gt;

&lt;p&gt;Some examples of global state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;who is the currently logged in user and what are her/his rights &lt;/li&gt;
&lt;li&gt;the currently selected theme &lt;/li&gt;
&lt;li&gt;the currently selected language/locale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Context Api + useReducer hook &lt;/li&gt;
&lt;li&gt;Redux&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Generally, you should avoid global state as much as possible, and prefer using local component state.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/alexandrudanpop" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F358777%2Fc8c73bce-b48b-4e72-9712-5ec8081e7cb7.jpg" alt="alexandrudanpop"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/alexandrudanpop/why-react-projects-still-use-redux-in-2020-395p" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Why React projects still use Redux&lt;/h2&gt;
      &lt;h3&gt;Alexandru-Dan Pop ・ Aug 8 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Interacting with HTTP services
&lt;/h2&gt;

&lt;p&gt;Now that we know how to split UIs into components, do routing and state management, the &lt;em&gt;next step&lt;/em&gt; is managing to get data from APIs in our application. &lt;/p&gt;

&lt;p&gt;A basic understanding of HTTP and Web APIs is important. You will interact with APIs using the &lt;code&gt;fetch API&lt;/code&gt; or using a library like &lt;code&gt;axios&lt;/code&gt;, so please learn how to use one of those two.&lt;/p&gt;

&lt;p&gt;I wrote about popular Web APIs and how to interact with HTTP APIs:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/alexandrudanpop" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F358777%2Fc8c73bce-b48b-4e72-9712-5ec8081e7cb7.jpg" alt="alexandrudanpop"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/alexandrudanpop/popular-web-apis-you-should-know-about-2blc" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Popular web APIs you should know about&lt;/h2&gt;
      &lt;h3&gt;Alexandru-Dan Pop ・ Jul 22 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#api&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#productivity&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#machinelearning&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;br&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/alexandrudanpop" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F358777%2Fc8c73bce-b48b-4e72-9712-5ec8081e7cb7.jpg" alt="alexandrudanpop"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/alexandrudanpop/correctly-handling-async-await-in-react-components-4h74" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Correctly handling async/await in React components&lt;/h2&gt;
      &lt;h3&gt;Alexandru-Dan Pop ・ Apr 5 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Component libraries
&lt;/h2&gt;

&lt;p&gt;You probably don't always want to build all the components for a complex UI from scratch - so it's useful to know about pre-build component libraries. Using those can speed up development as you don't need to code basic UI components like buttons, dropdowns, tables, etc from scratch.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Material UI&lt;/li&gt;
&lt;li&gt;Reactstrap&lt;/li&gt;
&lt;li&gt;Semantic UI&lt;/li&gt;
&lt;li&gt;Chakra&lt;/li&gt;
&lt;li&gt;Ant Design&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You definitely don't need to be familiar with all of them - just know they are there, and you can reach them when you need them.&lt;/p&gt;

&lt;h2&gt;
  
  
  You are all set!
&lt;/h2&gt;

&lt;p&gt;Alright! If you made it until this point, gathered info about all the previous topics, and got an understanding of each of them - you are all good! &lt;/p&gt;

&lt;p&gt;Next, we will talk more about some more &lt;strong&gt;advanced&lt;/strong&gt; stuff that are also very interesting for React devs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced - React toolchains when and why?
&lt;/h2&gt;

&lt;p&gt;In the post above I address when you should use react toolchains like Create React App, or Next.js, or Gatsby. &lt;/p&gt;

&lt;p&gt;This is interesting when you can actually make those decisions, or help others make those decisions because picking the correct one of those three will be crucial to the success of your project:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/alexandrudanpop" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F358777%2Fc8c73bce-b48b-4e72-9712-5ec8081e7cb7.jpg" alt="alexandrudanpop"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/alexandrudanpop/react-applications-when-to-pick-gatsby-or-next-js-or-create-react-app-50l1" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;When to pick Gatsby, Next.Js or Create React App&lt;/h2&gt;
      &lt;h3&gt;Alexandru-Dan Pop ・ Jul 13 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Advanced - Deployment models
&lt;/h2&gt;

&lt;p&gt;Since in most cases our react apps production build will result in static assets, we can deploy using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A CDN&lt;/li&gt;
&lt;li&gt;A web server&lt;/li&gt;
&lt;li&gt;Containers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When to choose one or the other might depend on different factors. &lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced - Typescript
&lt;/h2&gt;

&lt;p&gt;Typescript is becoming more and more popular in the &lt;strong&gt;React&lt;/strong&gt; ecosystem. I wrote an article around it:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/alexandrudanpop" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F358777%2Fc8c73bce-b48b-4e72-9712-5ec8081e7cb7.jpg" alt="alexandrudanpop"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/alexandrudanpop/the-react-typescript-path-2020-1hjo" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;The React Typescript path - 2020&lt;/h2&gt;
      &lt;h3&gt;Alexandru-Dan Pop ・ Sep 10 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#typescript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Advanced - React patterns
&lt;/h2&gt;

&lt;p&gt;Using patterns can make our code more modular, easier to extend and reason about, but also more testable.&lt;/p&gt;

&lt;p&gt;Some of them are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/alexandrudanpop/react-pattern-render-props-5e75"&gt;Render props&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/docs/higher-order-components.html" rel="noopener noreferrer"&gt;HOC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.logrocket.com/the-complete-guide-to-building-headless-interface-components-in-react/" rel="noopener noreferrer"&gt;Headless Components&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Headless Components&lt;/em&gt; are probably the most popular pattern right now, as it's really nice to write the business logic of our apps in custom hooks, leaving our component code clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced - Testing
&lt;/h2&gt;

&lt;p&gt;Testing is a big thing when it comes to building resilient UI applications. If we use all those nice tools to build apps that can be modularized in independent components - why not also make sure those modules/components will always work as we intend them to? &lt;/p&gt;

&lt;p&gt;You will need to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basics of Jest&lt;/li&gt;
&lt;li&gt;How to use - React testing library&lt;/li&gt;
&lt;li&gt;How to use Cypress&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use this &lt;a href="https://testingreact.katifrantz.com/" rel="noopener noreferrer"&gt;free course&lt;/a&gt; to learn using Jest &amp;amp; React testing library to test React apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced - styling approaches
&lt;/h2&gt;

&lt;p&gt;As with many other things in the &lt;strong&gt;React&lt;/strong&gt; ecosystem, &lt;em&gt;styling&lt;/em&gt; has its flavors - and can be kept as simple as using a normal CSS stylesheet or using more complex approaches like CSS in JS. &lt;/p&gt;

&lt;p&gt;Styling can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;Inline&lt;/li&gt;
&lt;li&gt;CSS modules&lt;/li&gt;
&lt;li&gt;SASS (modules)&lt;/li&gt;
&lt;li&gt;CSS in JS&lt;/li&gt;
&lt;li&gt;Atomic CSS (TailwindCSS - for example)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Different applications will have different styling needs. If all styles are from scratch - something like CSS in JS or Atomic CSS might make the most sense. &lt;/p&gt;

&lt;p&gt;Some applications might require minimal custom styling as they are built on top of a CSS framework like Bootstrap 4 or Material UI. In that case, CSS modules or SASS might be your choice. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Learning React &amp;amp; working with the Web is a never-ending journey, so keep learning, keep exploring!&lt;/p&gt;

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

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



&lt;/p&gt;

&lt;p&gt;Leave a 🧡 &amp;amp; 🦄 if you like this article, also check out my &lt;a href="https://twitter.com/alexandrudanpop" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; where I post more cool content.&lt;/p&gt;

&lt;p&gt;👇 &lt;strong&gt;Comment below&lt;/strong&gt; 👇&lt;br&gt;
Did I miss anything? What are the top things to know from the React world today?&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Modern Windows 10 development setup</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Sun, 25 Oct 2020 17:26:22 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/modern-windows-10-dev-setup-1lnl</link>
      <guid>https://dev.to/alexandrudanpop/modern-windows-10-dev-setup-1lnl</guid>
      <description>&lt;p&gt;Windows is the &lt;a href="https://en.wikipedia.org/wiki/Usage_share_of_operating_systems#:~:text=The%202019%20Stack%20Overflow%20developer" rel="noopener noreferrer"&gt;most popular desktop &amp;amp; laptop OS&lt;/a&gt;, love it or hate it, lots of programmers run this OS.  &lt;/p&gt;

&lt;p&gt;The reasons may be various, but I like to think that many use it because &lt;strong&gt;it just works&lt;/strong&gt; very well for a lot of stuff - including programming.&lt;/p&gt;

&lt;p&gt;Ok, another reason that matters to many. For some time Mac computers didn't have a real competitor design-wise. I think now, they do. &lt;/p&gt;

&lt;p&gt;I mean just take a look at the new &lt;a href="https://www.amazon.co.uk/dp/B084J4LFJD/ref=as_li_ss_tl?language=en_US&amp;amp;ie=UTF8&amp;amp;linkCode=gs4&amp;amp;linkId=e1bc65bb491f87147af7fe5c371cff86&amp;amp;tag=laptoptalks0e-21" rel="noopener noreferrer"&gt;2020 Dell XPS 13&lt;/a&gt; - that thing is gorgeous. &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%2F51vnnp8fu4r4x55lwmby.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F51vnnp8fu4r4x55lwmby.jpg" alt="Dell xps 13 pic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While I don't want to raise a battle on Windows vs Linux vs Mac, I want to state that I've tried all 3, and I like them all for what they do best. Windows is a very good all-around operating system that also has its quirks, so I want to share what you can do to make your developer experience as good as possible on this OS. &lt;/p&gt;

&lt;h2&gt;
  
  
  Chocolatey 🍫 or Winget
&lt;/h2&gt;

&lt;p&gt;The Package Manager for Windows - this tool, once installed, can do things like: &lt;br&gt;
&lt;code&gt;choco install nodejs&lt;/code&gt;&lt;br&gt;
&lt;code&gt;choco install vscode&lt;/code&gt;&lt;br&gt;
&lt;code&gt;choco install firefox&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Amazing right? You can have a script with everything you need to install on a new machine - making the setup process really easy. Also - they have a cool &lt;a href="https://chocolatey.org/" rel="noopener noreferrer"&gt;website&lt;/a&gt; where you can search packages and see what other nice things &lt;code&gt;choco&lt;/code&gt; does (besides getting some nice dopamine in your brain).&lt;/p&gt;

&lt;p&gt;As of 2023, it's probably better to use &lt;code&gt;winget&lt;/code&gt; instead of &lt;code&gt;choco&lt;/code&gt;, check it out &lt;a href="https://winget.run/" rel="noopener noreferrer"&gt;here&lt;/a&gt; and read more about it on &lt;a href="https://learn.microsoft.com/en-us/windows/package-manager/winget/" rel="noopener noreferrer"&gt;learn.microsoft.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Alternatively, you could also check out &lt;a href="https://scoop.sh/" rel="noopener noreferrer"&gt;Scoop&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cmder 💻
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cmder.net/" rel="noopener noreferrer"&gt;Cmder&lt;/a&gt; is a console emulator - allowing you to have a multi-tab console for Windows - supporting cmd, Powershell &amp;amp; bash. It has lots of customization features - like choosing a background, the font-size, aliases, and other nice features. Also has good keyboard shortcuts out of the box.&lt;/p&gt;

&lt;p&gt;By the way, you can also map your VS Code terminal to be Cmder.&lt;/p&gt;

&lt;p&gt;Some alternatives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701?activetab=pivot:overviewtab" rel="noopener noreferrer"&gt;Windows terminal&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://hyper.is/" rel="noopener noreferrer"&gt;Hyper&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'd say give all a shot and pick the one you like the most.&lt;/p&gt;
&lt;h2&gt;
  
  
  Wox 🔎
&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.wox.one/" rel="noopener noreferrer"&gt;Wox&lt;/a&gt; - I really enjoy using this tool as a Spotlight alternative for Windows. Need to quickly find an app, run something from a command line, calculate something, or search something on google? Wox can do all those things for you - FAST!&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%2F2u26zhojh1udvteo3pm3.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%2F2u26zhojh1udvteo3pm3.gif" alt="Wox launcher"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Code editors
&lt;/h2&gt;

&lt;p&gt;Take your pick, the best of the best run on Windows of course:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VSCode&lt;/li&gt;
&lt;li&gt;Webstorm&lt;/li&gt;
&lt;li&gt;Atom&lt;/li&gt;
&lt;li&gt;Sublime text&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Develop as on a Linux box with WSL2 🐧
&lt;/h2&gt;

&lt;p&gt;Of course, spinning up a Linux VM is pretty easy on Windows with Hyper-V, but why bother when you can get this &lt;em&gt;natively&lt;/em&gt;? You just need to turn on WSL from the Windows features section, and then you can code using Linux-first languages like Ruby or Python in the environment they were designed to run.&lt;/p&gt;

&lt;p&gt;A gotcha when running things in WSL2 is using &lt;code&gt;/mnt/c&lt;/code&gt; that will make your dev experience really slow. You should not use the Windows drives for WSL2 development, but the actual WSL2 drive, for example:&lt;br&gt;
&lt;code&gt;/home/{username}/projects&lt;/code&gt;&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Extra steps to make the OS faster
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Uninstall any bloatware&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.windowscentral.com/how-exclude-files-and-folders-windows-defender-antivirus-scans" rel="noopener noreferrer"&gt;Prevent Windows Security dev folders scanning&lt;/a&gt; (if you are sure you are using only trusted secure software - beware that some hacked &lt;code&gt;npm packages&lt;/code&gt; have exploited Windows machines in the past)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.online-tech-tips.com/computer-tips/simple-ways-to-increase-your-computers-performace-turn-off-indexing-on-your-local-drives/#:~:text=To%20do%20it%2C%20first%20open,After%2C%20click%20Apply." rel="noopener noreferrer"&gt;Turn off Windows search indexing&lt;/a&gt; - since you are using Wox, you don't need it&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Do you need a Mac to code?
&lt;/h4&gt;

&lt;p&gt;Absolutely not. Unless you are doing some OSX/iOS development, you definitely don't need a Mac. Pretty much everything you can do on a Mac is possible on a Windows PC as well. &lt;/p&gt;

&lt;p&gt;Leave a 🧡 &amp;amp; 🦄 if you like this article, also check out my &lt;a href="https://twitter.com/alexandrudanpop" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; where I post more cool content.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Working with .Net Core &amp; React - what I've learned</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Fri, 09 Oct 2020 11:27:13 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/working-with-net-core-react-what-i-ve-learned-ge6</link>
      <guid>https://dev.to/alexandrudanpop/working-with-net-core-react-what-i-ve-learned-ge6</guid>
      <description>&lt;p&gt;I have been using both of those 2 awesome technologies for some time. From the point I started using React, I had a slow migration to the JS ecosystem and started to do more frontend work and less backend work using .Net. &lt;/p&gt;

&lt;p&gt;Lots of folks like ASP.NET Core. 🌟 &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;see the  &lt;a href="https://insights.stackoverflow.com/survey/2020#technology-most-loved-dreaded-and-wanted-web-frameworks" rel="noopener noreferrer"&gt;2020 stack overflow dev survey&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this article, I don't compare them - just telling a few my personal impressions of both ecosystems. &lt;/p&gt;

&lt;p&gt;It's mostly about what I like or dislike about both the ecosystems &amp;amp; their tooling. 👀&lt;/p&gt;

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

&lt;p&gt;Both React and .Net Core are baked up by tech giants. 🗿&lt;br&gt;
This makes picking those technologies easy for decision-makers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The React ecosystem
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;React&lt;/strong&gt; is the dominant go-to solution when it comes to building web applications. &lt;/p&gt;

&lt;h3&gt;
  
  
  Some advantages:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;the ecosystem is huge and more vibrant&lt;/li&gt;
&lt;li&gt;great tools are free - ESlint, Prettier, Typescript, HMR (hot module replacement) - the JS community really has the lead when it comes to DX&lt;/li&gt;
&lt;li&gt;Monorepo tools
&lt;iframe class="tweet-embed" id="tweet-1299752196356136962-277" src="https://platform.twitter.com/embed/Tweet.html?id=1299752196356136962"&gt;
&lt;/iframe&gt;

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



&lt;/li&gt;
&lt;li&gt;An inclination towards FP (functional programming) instead of OOP (object-oriented programming)&lt;/li&gt;
&lt;li&gt;Some advantages are due to working with JS - like the ease of using JSON data and doing object manipulations&lt;/li&gt;
&lt;li&gt;More and more traction to Typescript in the last few years - I think this is a great quality boost for the ecosystem&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Some disadvantages:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;things get deprecated (see examples below)&lt;/li&gt;
&lt;li&gt;using TS doesn't give that seamless typed language experience (yet) as C# does. TS has escape hatches that can make TS code weekly typed (this can be also a benefit for some people)&lt;/li&gt;
&lt;li&gt;Things move much faster - and it's harder to stay up to date&lt;/li&gt;
&lt;li&gt;Standards are still missing in the React ecosystem. This is a good and a bad thing because each project will look very different - from folder structure to the way components are written, to what CSS technology is used in the project. This is somehow nice because it leaves a lot of room for new innovation, but still, it feels like some standards are missing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Examples of deprecation in the React world: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You learned React class components years ago and became an expert using them and all the lifecycle methods and all the class-based patterns. Well...bad luck, React function components with hooks are the new standard (don't get me wrong I absolutely love hooks ❤️).&lt;/li&gt;
&lt;li&gt;If you learned unit testing React components 5 years ago you might have learned Enzyme. At least from let's say 2019 (when also hooks were released), Enzyme is not encouraged to be used in React projects anymore. React Testing Library is the new standard, which has a totally different approach and different testing concepts (that are better). To put this in contrast - if you used .Net and learned to unit test your code with xUnit and Moq, maybe 5 years ago, you would still use those and be encouraged to do so&lt;/li&gt;
&lt;li&gt;You learned some complex state management solution and now there are talks in the community that you should not use it anymore - but maybe you should 😉
&lt;div class="ltag__link"&gt;
  &lt;a href="/alexandrudanpop" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuploads%2Fuser%2Fprofile_image%2F358777%2Fc8c73bce-b48b-4e72-9712-5ec8081e7cb7.jpg" alt="alexandrudanpop"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/alexandrudanpop/why-react-projects-still-use-redux-in-2020-395p" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Why React projects still use Redux&lt;/h2&gt;
      &lt;h3&gt;Alexandru-Dan Pop ・ Aug 8 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Examples of missing standards in the JS world:&lt;br&gt;
Just to give some context - there are 3 popular bundlers / build tools (webpack, parcel, rollup). There are more than 4 popular Rendering libraries (React, Vue, Svelte, Angular). There are at least 10 different ways of doing data fetching in React (with redux using your own middleware, sagas, thunks, redux-observable, useEffect, RxJs, react-query, swr, etc) &lt;/p&gt;

&lt;h2&gt;
  
  
  .Net core
&lt;/h2&gt;

&lt;p&gt;A more mature community who figured out doing things in certain ways. &lt;br&gt;
Now the &lt;strong&gt;.Net core&lt;/strong&gt; ecosystem is obviously not as popular as the React ecosystem. When it comes to server-side applications or API's there is no clear winner, but we can certainly say .Net Core is one of the trending top picks in the world of APIs &amp;amp; backends.&lt;/p&gt;

&lt;h3&gt;
  
  
  Some advantages:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;A more consistent way of building server-side apps&lt;/li&gt;
&lt;li&gt;More stability - the best practices you learn today will probably be also around 5 years from now&lt;/li&gt;
&lt;li&gt;Both C# &amp;amp; F# are excellent languages that evolve a lot over time&lt;/li&gt;
&lt;li&gt;It's just great for building Web APIs, background services, etc&lt;/li&gt;
&lt;li&gt;Microsoft owns .NET, so you will get a pretty nice experience using .Net/.Net Core on other platforms they own - Azure, Azure Devops, Github&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Some disadvantages:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Lacks the advanced OSS tooling in the JS world - for more advanced linting, refactoring tools, code formatting you need to pay (ex for Resharper or Rider)&lt;/li&gt;
&lt;li&gt;Lacks monorepo tools (at least I don't know any)&lt;/li&gt;
&lt;li&gt;The community is not so vibrant. And a lot of folks are not so open to sharing things. This ecosystem would have great success if people would be more open and share things more&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Is it worth knowing both?
&lt;/h2&gt;

&lt;p&gt;Yes! While a lot of new people join programming and try to learn React or some other Javascript framework first, I would actually encourage them to learn a pure backend language first. &lt;/p&gt;

&lt;p&gt;Why? It helps focus on pure coding and avoids learning at first all the complexities of the Web.&lt;/p&gt;

&lt;p&gt;Aside from this, it's an incredible stack to master, as &lt;strong&gt;.Net Core&lt;/strong&gt; offers a consistent way to build complex backends, and &lt;strong&gt;React&lt;/strong&gt; helps you build complex interactive user interfaces.&lt;/p&gt;

&lt;p&gt;Leave a 🧡 &amp;amp; 🦄 if you like this article, also check out my Twitter where I post more cool content.&lt;/p&gt;

&lt;h3&gt;
  
  
  👇 Comment below 👇
&lt;/h3&gt;

&lt;p&gt;Let me know what you think about the &lt;strong&gt;.Net Core&lt;/strong&gt; &amp;amp; &lt;strong&gt;React&lt;/strong&gt; combo. &lt;/p&gt;

&lt;p&gt;Is it worth learning C# with .Net Core or should we just use Node.js server-side and use the same language everywhere?&lt;/p&gt;

</description>
      <category>react</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>typescript</category>
    </item>
    <item>
      <title>What if you could change one thing about your career</title>
      <dc:creator>Alexandru-Dan Pop</dc:creator>
      <pubDate>Fri, 02 Oct 2020 18:01:16 +0000</pubDate>
      <link>https://dev.to/alexandrudanpop/what-if-you-could-change-1-thing-about-your-career-p0e</link>
      <guid>https://dev.to/alexandrudanpop/what-if-you-could-change-1-thing-about-your-career-p0e</guid>
      <description>&lt;p&gt;Hello, fellow devs 👋, if you could change one thing about your dev career so far, or could improve one thing from it, what would it be?&lt;/p&gt;

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