<?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: Ondrej Sevcik</title>
    <description>The latest articles on DEV Community by Ondrej Sevcik (@ondrejsevcik).</description>
    <link>https://dev.to/ondrejsevcik</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%2F579812%2F4825eba1-0962-46f2-8428-57e28a4e8722.jpeg</url>
      <title>DEV Community: Ondrej Sevcik</title>
      <link>https://dev.to/ondrejsevcik</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ondrejsevcik"/>
    <language>en</language>
    <item>
      <title>My Use Cases for Advanced Github Search</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Thu, 22 Feb 2024 19:05:57 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/my-use-cases-for-advanced-github-search-pd7</link>
      <guid>https://dev.to/ondrejsevcik/my-use-cases-for-advanced-github-search-pd7</guid>
      <description>&lt;p&gt;I’ve been overseeing many different repositories at Lokalise and that means also knowing and keeping track of what libraries are in use and in what version.&lt;/p&gt;

&lt;p&gt;I always knew that GitHub has a search functionality, but until recently, I didn’t realize that I can use it exactly for this purpose.&lt;/p&gt;

&lt;p&gt;Here are a few use cases, I use GitHub Search for lately.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find out what versions of package X do we use in different repositories
&lt;/h2&gt;

&lt;p&gt;In my case, the package X is React. I was trying to find out what React versions we still use. This search command gave me the answer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;org:lokalise path:&lt;span class="k"&gt;**&lt;/span&gt;/package.json react-dom NOT is:archived
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Find out how many files with extension X do we have
&lt;/h2&gt;

&lt;p&gt;Github Search returns also the amount of files that match the search. With that, you can also easily find out how many files of certain type you have in your organization.&lt;/p&gt;

&lt;p&gt;In my case, I was looking for how many React components we have.&lt;/p&gt;

&lt;p&gt;A small problem is that once you get over 1000s, it will give you just an approximate number, but in my case, that was still good enough.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;org:lokalise path:&lt;span class="k"&gt;**&lt;/span&gt;/&lt;span class="k"&gt;*&lt;/span&gt;.tsx NOT is:archived
&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%2Fuploads%2Farticles%2Fpx6ot3r3w7eq3inu5y25.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%2Fpx6ot3r3w7eq3inu5y25.png" alt="GitHub Search for .tsx files." width="800" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Find out how many files use styled-components
&lt;/h2&gt;

&lt;p&gt;We’re in a process of migrating from &lt;code&gt;styled-components&lt;/code&gt; to native CSS (which is more web friendly). With this search, I can track easily how the migration is going.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;org:lokalise &lt;span class="s2"&gt;"from 'styled-components'"&lt;/span&gt; NOT is:archived
&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%2Fuploads%2Farticles%2F3lnee8afyhc23mv4u5jl.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%2F3lnee8afyhc23mv4u5jl.png" alt="GitHub Search for file import" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
    </item>
    <item>
      <title>Using Performance API to Measure Front-End Interaction Times</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Wed, 07 Jun 2023 18:01:02 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/using-performance-api-to-measure-front-end-interaction-times-4f0a</link>
      <guid>https://dev.to/ondrejsevcik/using-performance-api-to-measure-front-end-interaction-times-4f0a</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Performance API is a great (native) way to measure how long certain Front-End interactions take.&lt;/li&gt;
&lt;li&gt;Its Observable API allows for easy plug-in of existing monitoring tools.&lt;/li&gt;
&lt;li&gt;It’s only a few lines of code and you’re good to ship.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;To measure the performance of your app’s functionality, you will need to add Markers and Measures into your code.&lt;/p&gt;

&lt;p&gt;Ideally, you add those into critical parts of your application where you want to ensure that they stay performant over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Mark and Measure?
&lt;/h2&gt;

&lt;p&gt;Working with Performance API, you will see &lt;strong&gt;Mark&lt;/strong&gt; and &lt;strong&gt;Measure&lt;/strong&gt; mentioned a lot. Understanding the difference between those two is essential.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mark&lt;/strong&gt; is an object that represents an event on a timeline. It’s created using &lt;code&gt;performance.mark()&lt;/code&gt; call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The measure&lt;/strong&gt; is a measurement between two of those marks. It’s created using &lt;code&gt;performance.measure()&lt;/code&gt; call.&lt;/li&gt;
&lt;/ul&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%2Fhpk963e3ogcy1eib6k2x.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%2Fhpk963e3ogcy1eib6k2x.png" alt="Difference between Marker and Measure."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic use case
&lt;/h2&gt;

&lt;p&gt;Let's measure how long it takes to show the next image after clicking the button.&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%2Fb5gvv2tro3eru2gavmk2.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%2Fuploads%2Farticles%2Fb5gvv2tro3eru2gavmk2.gif" alt="What we're building."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For that, we will have to add two markers - one for &lt;strong&gt;button clicked&lt;/strong&gt; and one for &lt;strong&gt;image loaded&lt;/strong&gt;. With marks in place, we can then measure the time between them.&lt;/p&gt;

&lt;p&gt;(Full example in &lt;a href="https://codesandbox.io/s/wizardly-benji-mimedt?file=/src/index.js" rel="noopener noreferrer"&gt;Codesandbox&lt;/a&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button-clicked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- mark button click&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;imgEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#img&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;imgEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;load&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="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image-loaded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- mark image loaded&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;measure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;measure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;load-next-image-duration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// measure name&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button-clicked&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// start mark&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image-loaded&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// end mark&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;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;measure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;'s duration: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;measure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;once&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;imgEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The benefit of using the native API is that it also shows up your markers and measures in DevTools.&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%2Fnuxvkqchsd0s719es21y.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%2Fnuxvkqchsd0s719es21y.png" alt="DevTools timeline with Performance Markers and Measure."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending measures to external monitoring tools
&lt;/h2&gt;

&lt;p&gt;One last step is to actually log those performance measures into external systems, where you can then analyze your performance trends over time.&lt;/p&gt;

&lt;p&gt;The Measure object has name and duration properties that are ideal candidates to be sent.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/PerformanceObserver" rel="noopener noreferrer"&gt;PerformanceObserver&lt;/a&gt; API, it’s just a few lines of code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;perfObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getEntries&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;entry&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// replace with monitoring tool of your choice&lt;/span&gt;
    &lt;span class="nx"&gt;newrelic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPageAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;duration&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;observer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PerformanceObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;perfObserver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;observer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;entryTypes&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;measure&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;And that’s it. I hope this short introduction helped you to understand how easy it is to use Performance API to monitor your app.&lt;/p&gt;

&lt;p&gt;For advanced use cases, visit the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance_API" rel="noopener noreferrer"&gt;MDN docs for Performance API&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>performance</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Increase CSS Class Selector Specificity to Beat the ID Selector Without Using Important</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Thu, 27 Apr 2023 14:53:13 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/how-to-increase-css-class-selector-specificity-to-beat-the-id-selector-without-using-important-41e7</link>
      <guid>https://dev.to/ondrejsevcik/how-to-increase-css-class-selector-specificity-to-beat-the-id-selector-without-using-important-41e7</guid>
      <description>&lt;p&gt;Recently, while working on some legacy code, I had to figure out how to overwrite ID selector styles without using &lt;code&gt;!important&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The CSS was similar to this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"child"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Content&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;/* specificity 100 + 10 = 110 */&lt;/span&gt;
  &lt;span class="nf"&gt;#parent&lt;/span&gt; &lt;span class="nc"&gt;.child&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="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;/* specificity 10 */&lt;/span&gt;
  &lt;span class="nc"&gt;.child&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="no"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This results in a text with red color, but in my case, I needed to make the text yellow.&lt;/p&gt;

&lt;p&gt;Normally, I would just refactor the CSS and HTML, but in this case, I couldn’t change the HTML and order of CSS due to some legacy code.&lt;/p&gt;

&lt;p&gt;The easy solution would be to use an infamous &lt;code&gt;!important&lt;/code&gt; keyword to overwrite everything, but I didn’t want to go that way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using attribute selector
&lt;/h3&gt;

&lt;p&gt;The better way is to change the ID selector to the attribute selector. Instead of &lt;code&gt;#parent&lt;/code&gt; it's possible to use &lt;code&gt;[id="parent"]&lt;/code&gt;. This has the same specificity as a class selector.&lt;/p&gt;

&lt;p&gt;Now instead of specificity &lt;code&gt;110&lt;/code&gt;, it is down to &lt;code&gt;20&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="c"&gt;/* specificity 10 + 10 = 20 */&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"parent"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;.child&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="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* specificity 10 */&lt;/span&gt;
&lt;span class="nc"&gt;.child&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="no"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Chaining the selector with itself
&lt;/h3&gt;

&lt;p&gt;Now I had to increase the &lt;code&gt;.child&lt;/code&gt; specificity above 20 to beat the &lt;code&gt;[id="parent" .child"&lt;/code&gt; selector. One way to achieve that is to &lt;strong&gt;chain the class selector with itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The specificity of &lt;code&gt;.child&lt;/code&gt; is 10. The specificity of &lt;code&gt;.child.child.child&lt;/code&gt; is 30.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"child"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Content&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;/* specificity 10 + 10 = 20 */&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"parent"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;.child&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="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c"&gt;/* specificity 10 + 10 + 10 = 30 */&lt;/span&gt;
  &lt;span class="nc"&gt;.child.child.child&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="no"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is an easy way to bump up specificity without adding additional classes or knowing about the context where the item will be placed.&lt;/p&gt;

&lt;p&gt;I find this better than using &lt;code&gt;!important&lt;/code&gt;, but it is still a hack. If possible, try to avoid this.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>tip</category>
    </item>
    <item>
      <title>The Reason Why I Don’t Use Gmail as My Primary Email Anymore</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Thu, 02 Mar 2023 07:18:20 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/the-reason-why-i-dont-use-gmail-as-my-primary-email-anymore-3p03</link>
      <guid>https://dev.to/ondrejsevcik/the-reason-why-i-dont-use-gmail-as-my-primary-email-anymore-3p03</guid>
      <description>&lt;p&gt;It’s been 2 years since I realized that my whole online presence is built around Google.&lt;/p&gt;

&lt;p&gt;It’s very convenient to build your whole life around Google Services - Gmail, Drive, Contacts, Photos, YouTube, save Passwords to Chrome, Login with Google, … the list goes on and on. Google services are free, easy to use, and they all work well together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your account has been suspended
&lt;/h2&gt;

&lt;p&gt;The problem is that each service on Google has its own Terms &amp;amp; Conditions, and it’s not that uncommon to get your account suspended because you “breached something somewhere”.&lt;/p&gt;

&lt;p&gt;Once you get suspended, you basically stop existing online, and you lose access to all your data. Everything. Gone. Immediately. And Google has no obligation to talk to you. After all, it’s free.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Centralizing all our online being into the hands of a single giant is not the best idea.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I did not like the idea of that. Not having an access to my email and my passwords could be existential. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PMgkw_SG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4y47vz8ficxggxmiq9za.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PMgkw_SG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4y47vz8ficxggxmiq9za.png" alt="People posting on Twitter about being suspended" width="880" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are &lt;a href="https://twitter.com/miguelytob/status/1315749803041619981"&gt;many&lt;/a&gt; &lt;a href="https://www.businessinsider.com/google-users-locked-out-after-years-2020-10"&gt;stories&lt;/a&gt; &lt;a href="https://twitter.com/com/status/1466928315562958850"&gt;out&lt;/a&gt; &lt;a href="https://kylepiira.com/2020/01/09/why-i-quit-google/"&gt;there&lt;/a&gt; where people got locked out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Portability is freedom
&lt;/h2&gt;

&lt;p&gt;My email is now on my own domain, hosted at Fastmail. I’m using 1Passwords for logins and passkeys. I use Firefox for bookmark sync. And I never use social logins.&lt;/p&gt;

&lt;p&gt;I pay for all of these services. It costs me around 12$ a month and it’s totally worth it. I feel good about supporting more independent internet, plus paying for service has so many other benefits (like a support that actually talks to you, better privacy, loads faster, and so on).&lt;/p&gt;

&lt;p&gt;The point is not to avoid Google at all costs, but to minimize the impact of being suspended. If I would simply switch to Apple or Microsoft, it would be the same problem. &lt;strong&gt;The internet is meant to be decentralized.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I still use YouTube and Google Maps. But they are just yet another service I use. If I would get suspended, it would not be a big deal anymore.&lt;/p&gt;

&lt;p&gt;If you’re in the same position as I was 2 years ago, now is the best time to reconsider your online being.&lt;/p&gt;

</description>
      <category>google</category>
      <category>email</category>
    </item>
    <item>
      <title>Improving the performance of styled components with native CSS features</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Sat, 28 Jan 2023 07:44:13 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/improving-the-performance-of-styled-components-with-native-css-features-27pd</link>
      <guid>https://dev.to/ondrejsevcik/improving-the-performance-of-styled-components-with-native-css-features-27pd</guid>
      <description>&lt;p&gt;Styled components are slow. But can we improve its performance by using some of the native CSS features? I've decided to test it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;The problem with styled components is that they recalculate styles based on runtime values. Every time the component is rendered, it needs to build up the stylesheet and insert it into the document. This is not an issue in small apps, but in larger applications, it affects performance.&lt;/p&gt;

&lt;p&gt;What you want to avoid is dynamic components (a component that depends on theme or props).&lt;/p&gt;

&lt;p&gt;Before a dynamic component is inserted into DOM, it needs to &lt;strong&gt;parse the template → generate CSS → preprocess styles → inject it into DOM&lt;/strong&gt;. Static components on the other hand can skip some of these steps and are thus much faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring alternatives
&lt;/h2&gt;

&lt;p&gt;Given that, I’ve started exploring how could we rewrite dynamic components into static ones.&lt;/p&gt;

&lt;p&gt;Here is a classic example of a dynamic styled component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  padding: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="nx"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1rem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;I&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;m a box&amp;lt;/Box&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This could be easily rewritten as a static component with a help of CSS Variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="s2"&gt;`
  font-size: var(--padding);
`&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1rem&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;I&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;m a box&amp;lt;/Box&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But usually, in larger apps, we don’t use specific values directly, but rather design tokens from the design system.&lt;/p&gt;

&lt;p&gt;Here’s a similar example, but this time with padding with three options.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;small&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;large&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;`
  padding: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;props&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;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;small&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1rem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;medium&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2rem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;large&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3rem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="s2"&gt;;
`&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="nx"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;I&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;m a box&amp;lt;/Box&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we can’t really use CSS variables. But we could use data attributes instead.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;styled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-padding&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;small&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;large&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;`
  &amp;amp;[data-padding="small"] {
    padding: 1rem;
  }
  &amp;amp;[data-padding="medium"] {
    padding: 2rem;
  }
  &amp;amp;[data-padding="large"] {
    padding: 3rem;
  }
`&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Box&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;I&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;m a box&amp;lt;/Box&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This doesn’t look bad, and is much easier to read.&lt;/p&gt;

&lt;p&gt;The only disadvantage of this approach is that it’s actually rendering the &lt;code&gt;data-padding&lt;/code&gt; attribute into the DOM. Writing to DOM might affect the performance as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;I’ve decided to test it out.&lt;/p&gt;

&lt;p&gt;In this &lt;a href="https://codesandbox.io/s/styled-components-perf-test-conditions-ur9tpj" rel="noopener noreferrer"&gt;simple demo&lt;/a&gt;, I build a table with 1000 items in it using 3 different approaches. The first one is using &lt;strong&gt;dynamically styled-components&lt;/strong&gt;, the second is using &lt;strong&gt;statically styled-components&lt;/strong&gt; and the third one is using &lt;strong&gt;plain old CSS class names&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It turns out that using &lt;code&gt;data-attributes&lt;/code&gt; is indeed a little bit faster than using dynamic props on styled-components. Not surprisingly the fastest was using CSS class names.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0k666j6hngd3jv5jim2r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0k666j6hngd3jv5jim2r.png" alt="React Profiller results" width="800" height="266"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Using native CSS features can indeed improve the performance of styled-components. It makes the styles also more readable. Rather than writing CSS inside JS function inside CSS declaration inside JS file, you can just write CSS that everybody understands.&lt;/p&gt;

&lt;p&gt;But using CSS in JS is still controversial. It improves DX while hurting the user experience.&lt;/p&gt;

&lt;p&gt;As long as CSS in JS doesn't improve UX &amp;amp; DX at the same time, it's better to stick with plain old CSS and a some good CSS methodology.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>howto</category>
      <category>development</category>
    </item>
    <item>
      <title>How to detect AdBlock in plain JavaScript with a few lines of code</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Sat, 10 Sep 2022 08:04:15 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/how-to-detect-adblock-in-plain-javascript-with-a-few-lines-of-code-5g27</link>
      <guid>https://dev.to/ondrejsevcik/how-to-detect-adblock-in-plain-javascript-with-a-few-lines-of-code-5g27</guid>
      <description>&lt;p&gt;Using analytics tools to measure the impact of your application is part of every website these days.&lt;/p&gt;

&lt;p&gt;But measuring how many of your users block your analytics is probably even more important.&lt;/p&gt;

&lt;p&gt;And luckily, it’s not that difficult to figure it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;In a nutshell - you need to add a fake advertisement div to your website and check if it is visible or not.&lt;/p&gt;

&lt;p&gt;In practice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add an empty &lt;code&gt;div&lt;/code&gt; that’s positioned in the top right corner of your website. That way, it won’t bother users who don’t use AdBlock.&lt;/li&gt;
&lt;li&gt;Preferably also add &lt;code&gt;aria-hidden="true"&lt;/code&gt; to not show this fake ad to users who use accessibility tools.&lt;/li&gt;
&lt;li&gt;Once the page is loaded, check whether this fake advertisement div is visible or not.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"ad-box"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"position:fixed;top:0;left:0;"&lt;/span&gt; &lt;span class="na"&gt;aria-hidden=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="ni"&gt;&amp;amp;nbsp;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;adBoxEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.ad-box&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;hasAdBlock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getComputedStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;adBoxEl&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="c1"&gt;// ... save to DB&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The way most AdBlocks work these days is that they target specific CSS classes (like &lt;code&gt;class="ad-box"&lt;/code&gt;) and apply &lt;code&gt;display: none&lt;/code&gt; on it. That way, the Ad disappears in your browser.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Always double-check that you don’t break the experience for users that do not use AdBlock.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can see all the CSS classes that are used for blocking in &lt;a href="https://easylist.to/easylist/easylist.txt"&gt;EasyList blocklist&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>adblock</category>
      <category>html</category>
    </item>
    <item>
      <title>20 principles I learned from 10 years of developing software</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Thu, 25 Aug 2022 17:38:25 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/20-principles-i-learned-from-10-years-of-developing-software-5354</link>
      <guid>https://dev.to/ondrejsevcik/20-principles-i-learned-from-10-years-of-developing-software-5354</guid>
      <description>&lt;p&gt;It's been 10 years since I started my first job in the software industry. Here are 20 principles that I have learned and try to follow in my day-to-day life.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Be humble&lt;/strong&gt; - No engineer in the world knows everything, the same applies to you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make it work, make it right&lt;/strong&gt; (and sometimes make it fast).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimize for change&lt;/strong&gt; - Prefer duplication over the wrong abstraction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always write tests&lt;/strong&gt; - If you're not writing tests, you're testing manually.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Solve 80% of use cases&lt;/strong&gt; - You never gonna solve everyone’s problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefer functional programming&lt;/strong&gt; - It's easier to understand. If your code requires a Ph.D. to understand, you’re most likely doing it wrong.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Delete as much code as you can&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Good Enough is Better than Perfect&lt;/strong&gt; - Don't discard meaningful improvement just because it's not perfect.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Criticize in private, praise in public&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make notes&lt;/strong&gt; - If you think you will remember it, you're lying to yourself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Talk to your users&lt;/strong&gt; - The best software is built by engineers who have empathy for their users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learn with intention&lt;/strong&gt; - Practice with a clear and specific goal in mind - what you want to improve and exactly how (deliberate practice).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not generalize early&lt;/strong&gt; - Wait until you have at least 3 duplicates of code before you make an abstraction (aka. Rule Of Three).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix broken windows&lt;/strong&gt; - One hack in code leads to another hack. Soon your code will become unmanageable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fix the problem&lt;/strong&gt; - doesn't matter whose fault it is, it is your problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do what works, not what's fashionable&lt;/strong&gt; - Try it first with a small team. If it works, expand. If not, abort.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The best work requires a good rest&lt;/strong&gt; - Regular time off is essential for top performance. You also don’t expect professional sprinters to sprint all the time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Take small steps&lt;/strong&gt; - Big rewrites don't work. You will lose motivation and focus along the way. Aim to release daily. It gives you the freedom to change focus when necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Praise for good work&lt;/strong&gt; - Something we've observed in animals, but works for people too. You will get better results when you praise people for good work rather than punishing them for a bad one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Perfect code doesn't exist&lt;/strong&gt; - It's better to accept this as a fact rather than wasting time and chasing the impossible.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>career</category>
    </item>
    <item>
      <title>6 rules I follow to get simple and stable tests</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Fri, 05 Aug 2022 14:19:00 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/6-rules-i-follow-to-get-simple-and-stable-tests-229</link>
      <guid>https://dev.to/ondrejsevcik/6-rules-i-follow-to-get-simple-and-stable-tests-229</guid>
      <description>&lt;p&gt;It took me several years of trying and failing to figure out what does work when I write tests. Here are 6 rules that I always follow no matter what kind of tests I write.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow AAA pattern
&lt;/h2&gt;

&lt;p&gt;Clean unit tests follow the &lt;strong&gt;AAA&lt;/strong&gt; pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Arrange:&lt;/strong&gt; Setup the test scenario&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Act:&lt;/strong&gt; Execute the business logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assert:&lt;/strong&gt; Make some expectations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the holy grail of simple tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Single concept per test
&lt;/h2&gt;

&lt;p&gt;Test single concept in each unit test. If you follow the AAA pattern, this should feel natural.&lt;/p&gt;

&lt;p&gt;Oftentimes, I see tests that cover a lot of different concepts in a single unit test. That’s a code smell. It’s better to split up such a test into multiple tests - each testing its own thing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rule of thumb - if there is an &lt;code&gt;act&lt;/code&gt; after your &lt;code&gt;assert&lt;/code&gt;, you should consider to splitting it out into two separate tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your tests will be easier to understand, and easier to fix.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bad - mixing two concepts&lt;/span&gt;
&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should add new item into cart&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;let&lt;/span&gt; &lt;span class="nx"&gt;cart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Shoes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- // Testing adding item into cart&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&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="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeAllItems&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- Testing removing all items from cart&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&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="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Better - split it up&lt;/span&gt;
&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should add new item into cart&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;let&lt;/span&gt; &lt;span class="nx"&gt;cart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cart&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Shoes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&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="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should be possible to remove all items from cart&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;let&lt;/span&gt; &lt;span class="nx"&gt;cart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Cart&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;()]);&lt;/span&gt;
  &lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removeAllItems&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cart&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Avoid logic in your tests
&lt;/h2&gt;

&lt;p&gt;Avoid any &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;else&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt;, or &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator"&gt;ternary operator&lt;/a&gt; in your test code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The moment you use any of the control flow statements - you added logic to your test and now you need a &lt;strong&gt;test for your test&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This often happens with a parametrized test where you expect slightly different behavior for different inputs, but also with tests where someone wanted to avoid failure for a flaky test.&lt;/p&gt;

&lt;p&gt;In cases like these, it’s always better to split it up and keep it flat and simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bad&lt;/span&gt;
&lt;span class="nx"&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;should have focus when clicked&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="nx"&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;Input&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;input&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="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// this null check is pointless&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;input&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveFocus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// Better&lt;/span&gt;
&lt;span class="nx"&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;should have focus when clicked&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="nx"&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;Input&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;click&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="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="nx"&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="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toHaveFocus&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;
  
  
  Optimize for simplicity
&lt;/h2&gt;

&lt;p&gt;Good test is &lt;strong&gt;short, flat, simple&lt;/strong&gt;, and delightful to work with. When you look at a test, you should get the intent immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do not nest&lt;/strong&gt; tests. It adds unnecessary complexity. Each nesting level adds an extra &lt;a href="https://docs.codeclimate.com/docs/cognitive-complexity"&gt;cognitive complexity&lt;/a&gt; to your code.&lt;/p&gt;

&lt;p&gt;Refactor common setup code into a &lt;strong&gt;fixture&lt;/strong&gt; to avoid repetition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Only public API
&lt;/h2&gt;

&lt;p&gt;If your test is doing something that your user can’t, it's most likely testing implementation details.&lt;/p&gt;

&lt;p&gt;This is a code smell. Any change in the underlying implementation will break your test.&lt;/p&gt;

&lt;p&gt;Test only API that your user can use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use TDD to drive your coverage
&lt;/h2&gt;

&lt;p&gt;10/10 times when I use TDD, my code coverage climbs over 80%.&lt;/p&gt;

&lt;p&gt;Start with the &lt;strong&gt;happy path&lt;/strong&gt; - make sure that code works for your primary use cases.&lt;/p&gt;

&lt;p&gt;Continue with &lt;strong&gt;unhappy paths&lt;/strong&gt; - Cover the error conditions, unexpected input, or any other edge cases.&lt;/p&gt;

&lt;p&gt;You can skip testing trivial one-liners, getters, and setters.&lt;/p&gt;

&lt;p&gt;With this, you should hit the 80% coverage mark easily.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don’t obsess about code coverage - it only tells you what lines were executed, not if they work as intended. Focus more on writing meaningful tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  That’s it
&lt;/h2&gt;

&lt;p&gt;With these few rules, you can write tests that everybody will understand and it will be a pleasure to work with.&lt;/p&gt;

&lt;p&gt;Let me know if you have some other rules that you follow, and why.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Writing tests after release is a mistake</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Wed, 27 Apr 2022 16:02:09 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/writing-tests-after-release-is-a-mistake-2nnl</link>
      <guid>https://dev.to/ondrejsevcik/writing-tests-after-release-is-a-mistake-2nnl</guid>
      <description>&lt;p&gt;Writing tests in 2022 is more common than ever before, but more often than not, I see developers writing tests after the code is released to production. And that’s a big mistake.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is wrong with that?
&lt;/h2&gt;

&lt;p&gt;It seems obvious - writing tests takes time, so I will be faster if I don’t spend my time writing them before the code is released, right? Wrong!&lt;/p&gt;

&lt;p&gt;Writing code is just one part of producing features, and developers often ignore all the other areas that get affected. You end up with almost all the same problems like not testing at all.&lt;/p&gt;

&lt;p&gt;When you write tests after the release, you end up&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing your code manually&lt;/strong&gt; - You don’t ship untested code, do you? You either write automatic tests, or you test your code manually. Manual testing is the slowest. The bigger the change, the more time you spend on manual testing. It simply does not scale well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Producing worse Architecture&lt;/strong&gt; - TDD helps you organize your thoughts about the behavior and API design. Bad API accumulates and makes you even slower in the future.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Producing more bugs&lt;/strong&gt; - Manual testing means you test less often. Bad architecture means the code is more complex than it should be. Combine those two, and you end up with more bugs in production code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Longer code reviews&lt;/strong&gt; - No tests, bad architecture, and more bugs will lead to more and longer discussions about the code itself. Check your Pull Requests for how many comments and changes are usually required before you get approval.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Producing code that's harder to test&lt;/strong&gt; - Code that is not written with testing in mind is always more difficult to test. You will write more brittle tests or have to rewrite your code to make it testable. And that is, again, time-consuming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not testing all the edge cases&lt;/strong&gt; - You wrote the code several weeks ago, so it's natural that you forget all the edge cases that should be tested. This will haunt you in the future in the form of bugs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(Sometimes) Skipping the tests&lt;/strong&gt; - Since the code is in production and is working, your manager wants you to work on the next feature, naturally. And so the tests never get written. Don't blame your manager for that.&lt;/p&gt;

&lt;p&gt;All this adds up over time and makes you slower.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do instead?
&lt;/h2&gt;

&lt;p&gt;If you want to write quality software that lasts, there is no way you can avoid writing tests. Writing tests after the release may be better than no tests at all, but it’s not good enough. Unless you write tests first, you will always struggle with quality, design, and delivering on time.&lt;/p&gt;

&lt;p&gt;Testing is a skill, and you need to cultivate it. The more you do it, the better you become at it. And as you get better in TDD, you are likely to produce quality faster.&lt;/p&gt;

&lt;p&gt;Start with TDD today. You won’t regret it, I promise.&lt;/p&gt;

</description>
      <category>testing</category>
    </item>
    <item>
      <title>Why I migrated from ProtonMail to Fastmail (and how)</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Sat, 29 Jan 2022 10:51:57 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/why-i-migrated-from-protonmail-to-fastmail-and-how-12ke</link>
      <guid>https://dev.to/ondrejsevcik/why-i-migrated-from-protonmail-to-fastmail-and-how-12ke</guid>
      <description>&lt;p&gt;I’m a long-time fan of ProtonMail. Their mission is something that resonates with me. That’s why I had a hard time deciding whether I want to leave them or not.&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s the problem?
&lt;/h3&gt;

&lt;p&gt;ProtonMail is built as a completely zero-knowledge service. It means they don’t know anything about my data. That’s great, but it has also some major drawbacks.&lt;/p&gt;

&lt;p&gt;You cannot use anything but their official apps. ProtonMail has a Mail app for iPhone. But there is no Calendar app and there is no way to synchronize contacts between your email and phone.&lt;/p&gt;

&lt;p&gt;For some time I tried using mail and calendar through my mobile browser, but it wasn’t a good experience. Things that should take a few seconds took minutes and over time I was reluctant to do them at all. It was hurting my productivity and I felt disorganized. I started searching for an alternative.&lt;/p&gt;

&lt;h3&gt;
  
  
  Searching for an alternative
&lt;/h3&gt;

&lt;p&gt;I was looking for some privacy-friendly alternative. I’ve also considered switching to Apple iCloud+ with a custom domain, but I quickly decided against it. It’s better to keep my data out of the &lt;a href="https://en.wikipedia.org/wiki/Big_Tech"&gt;Big Five&lt;/a&gt; gang.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Email contains who you know, where you go, and what you do.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After searching for some while, I’ve stumbled over Fastmail. The reviews were very positive and I’ve also recognized them from the 1Password podcast. I gave them a try and I don’t regret it since. It simply works. Scan a &lt;a href="https://www.fastmail.help/hc/en-us/articles/360058752834-Set-up-Fastmail-on-your-device"&gt;setup QR code&lt;/a&gt; on your phone, download configuration profile on your Mac, and you're done - amazing!&lt;/p&gt;

&lt;p&gt;One feature that I’m particularly enjoying is &lt;a href="https://www.fastmail.com/1password/"&gt;Masked email&lt;/a&gt;. I didn't realize this until I've started using it. But being able to create an email alias exactly when you need it is great. More privacy and less tracking across the web.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xTpXG3tv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y76dwuleng2wqq3gryio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xTpXG3tv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y76dwuleng2wqq3gryio.png" alt="Masked email integration with 1Password" width="880" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Migration
&lt;/h3&gt;

&lt;p&gt;Moving Contacts and Calendar was easy as downloading a file (&lt;a href="https://en.wikipedia.org/wiki/ICalendar"&gt;.ics&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/VCard"&gt;vCard&lt;/a&gt;) from ProtonMail and uploading it back to Fastmail. But when it came to encrypted Mail, it wasn’t as straightforward as I would hope.&lt;/p&gt;

&lt;p&gt;Since ProtonMail is zero-knowledge, it’s not possible to use the usual IMAP import to move your data directly between different mail providers. I had to download all my mails with an export tool to the &lt;code&gt;.mbox&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--L6ehC9ng--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fvli72jc8f2zti3466c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--L6ehC9ng--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fvli72jc8f2zti3466c.png" alt="Export email tool from ProtonMail" width="880" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But even after that, the trouble didn’t end. Fastmail doesn’t support uploading the &lt;code&gt;.mbox&lt;/code&gt; file. I used Apple Mail to import my emails from &lt;code&gt;.mbox&lt;/code&gt; first and then connected it with my Fastmail account and drag&amp;amp;dropped my local mails to Fastmail inbox. A bit more work than expected.&lt;/p&gt;

&lt;p&gt;The whole migration including changing DNS records took around 2 hours. Not bad.&lt;/p&gt;

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

&lt;p&gt;I still support ProtonMail in their mission and I will still pay for their VPN. But for now, I’ve decided that I need to migrate somewhere where it fits better into my setup.&lt;/p&gt;

&lt;p&gt;Fastmail turned out to be a perfect alternative. Their service simply works and I like their commitment to privacy and community.&lt;/p&gt;

&lt;p&gt;Maybe one day, I will migrate back, maybe not. Ultimately I’m glad that I have my own domain and can switch between different providers in a few hours. Those 12$/year for a domain are worth the freedom. You simply switch where it makes the most sense for you.&lt;/p&gt;

</description>
      <category>protonmail</category>
      <category>email</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Console.error or throw new Error?</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Sun, 21 Nov 2021 11:50:11 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/consoleerror-or-throw-new-error-c9</link>
      <guid>https://dev.to/ondrejsevcik/consoleerror-or-throw-new-error-c9</guid>
      <description>&lt;p&gt;Recently, I was involved in a discussion about error handling. We couldn't agree on proper usage of &lt;code&gt;console.error&lt;/code&gt; and when to use &lt;code&gt;throw&lt;/code&gt;. So I've decided to write a short post on how I see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use console.error
&lt;/h2&gt;

&lt;p&gt;Almost never. &lt;code&gt;console.error&lt;/code&gt; is nothing else but &lt;code&gt;console.log&lt;/code&gt; that outputs red in your developer tools. &lt;strong&gt;It can’t be really considered as an error handling tool.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;console.error&lt;/code&gt; (or &lt;code&gt;console.assert&lt;/code&gt;) to make assertions to prevent impossible. Anytime you think "this could never happen", add assertion on that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep those assertions also in production code&lt;/strong&gt; unless it is a performance issue. You will experience way more "impossible" scenarios in production and having assertions in your code will help you to discover them earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use throw new Error
&lt;/h2&gt;

&lt;p&gt;Anytime you have corrupted data or an impossible state - throw!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dead program can do less harm than a program with corrupted data.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Consider following scenario&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;try&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;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="nx"&gt;orange&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// handle error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since it’s impossible to create a date from &lt;code&gt;orange&lt;/code&gt;, it’s better to throw an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s the alternative (future)?
&lt;/h2&gt;

&lt;p&gt;Exceptions (throwing errors) are mostly used in OOP languages. Functional languages treat &lt;strong&gt;errors as a type&lt;/strong&gt; rather than something special.&lt;/p&gt;

&lt;p&gt;It's becoming more common to see this pattern also in non-OOP languages. But I would be careful to use it until it becomes standard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"hello.txt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;// do something with file&lt;/span&gt;
    &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;// do something with error&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example above is from Rust. The method &lt;code&gt;open()&lt;/code&gt; returns either &lt;code&gt;File&lt;/code&gt; type or &lt;code&gt;Error&lt;/code&gt; type. In either case, &lt;strong&gt;it’s just a type&lt;/strong&gt;, no &lt;code&gt;exceptions&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I find this error handling most straightforward. It makes it obvious what functions may return &lt;code&gt;Errors&lt;/code&gt;, plus it forces you to handle them properly.&lt;/p&gt;

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

&lt;p&gt;Don't use &lt;code&gt;console.error&lt;/code&gt; for real error handling. Use &lt;code&gt;throw new Error()&lt;/code&gt; when you can't satisfy your business needs. And &lt;strong&gt;treat all errors equally, no matter where they come from&lt;/strong&gt;. It will make your life easier.&lt;/p&gt;

&lt;p&gt;PS: Warning is just a future error.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>errors</category>
      <category>beginners</category>
      <category>opinion</category>
    </item>
    <item>
      <title>On giving and receiving Feedback</title>
      <dc:creator>Ondrej Sevcik</dc:creator>
      <pubDate>Thu, 22 Apr 2021 17:07:54 +0000</pubDate>
      <link>https://dev.to/ondrejsevcik/on-giving-and-receiving-feedback-inl</link>
      <guid>https://dev.to/ondrejsevcik/on-giving-and-receiving-feedback-inl</guid>
      <description>&lt;p&gt;Without a doubt, one of the most difficult soft skills to develop. And though I don't claim to be an expert on the topic, here are some simple rules that worked well for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Giving feedback
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Don’t delay giving feedback&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid anonymous feedback&lt;/strong&gt; — It feels fake and dishonest.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Always give it in private&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Actively prepare for one-on-one meetings&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Write down questions you want to ask&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Give concrete examples&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deliver the bad news&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Avoid shit sandwich&lt;/strong&gt; — It does not work. It feels dishonest.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explain why you deliver given feedback&lt;/strong&gt; — &lt;em&gt;“I believe you can be great…, because …”&lt;/em&gt; is better than just dry feedback. But you also have to mean it, don't be fake.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  When asking for a feedback
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Get well with receiving difficult feedback&lt;/strong&gt; — It's the view of the person delivering it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask specific questions&lt;/strong&gt; — Generic questions lead to generic answers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask for advice rather than feedback&lt;/strong&gt; — People tend to talk more when they are asked for advice. And it does not have a negative tone to it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Other “hacks”
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;“When you do X, it makes me feel like Y”&lt;/em&gt;&lt;/strong&gt; — Feels more genuine.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;As a leader or manager always explain your decisions&lt;/strong&gt; — No matter if you incorporated received feedback or ignored it. People want to know why.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let me know which ones you like and whether you have some that work well for you. &lt;/p&gt;

</description>
      <category>softskills</category>
    </item>
  </channel>
</rss>
