<?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: Jonas Schumacher</title>
    <description>The latest articles on DEV Community by Jonas Schumacher (@jonasmerlin).</description>
    <link>https://dev.to/jonasmerlin</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%2F406124%2F91684d31-1491-43d1-8398-1f070a41ca27.jpeg</url>
      <title>DEV Community: Jonas Schumacher</title>
      <link>https://dev.to/jonasmerlin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jonasmerlin"/>
    <language>en</language>
    <item>
      <title>Search for word boundaries in Vim &amp; VSCode Vim</title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Sat, 03 Dec 2022 13:33:02 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/search-for-word-boundaries-in-vim-vscode-vim-5bl0</link>
      <guid>https://dev.to/jonasmerlin/search-for-word-boundaries-in-vim-vscode-vim-5bl0</guid>
      <description>&lt;p&gt;So you know that &lt;code&gt;/&lt;/code&gt; will bring up search in Vim and VSCode Vim. That's good!&lt;/p&gt;

&lt;p&gt;But then you named a variable &lt;code&gt;is&lt;/code&gt; and now want to find every occurence of that word - but only where it stands alone. So no places where it occurs as part of your &lt;code&gt;isLargePizza()&lt;/code&gt; function for example.&lt;/p&gt;

&lt;p&gt;Luckily, that's doable: &lt;code&gt;\&amp;lt;&lt;/code&gt; matches the beginning of a word and &lt;code&gt;\&amp;gt;&lt;/code&gt; the end.&lt;/p&gt;

&lt;p&gt;So hitting ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/\&amp;lt;is\&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... will to the trick!&lt;/p&gt;

&lt;p&gt;Edit:&lt;/p&gt;

&lt;p&gt;See &lt;a href="https://dev.to/pbnj/comment/23fo0"&gt;this&lt;/a&gt; comment by &lt;a class="mentioned-user" href="https://dev.to/pbnj"&gt;@pbnj&lt;/a&gt; for additional tips relating to word boundary search.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>vim</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Show hidden files &amp; folders in Finder on macOS</title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Fri, 28 Oct 2022 09:29:50 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/show-hidden-files-folders-on-macos-2861</link>
      <guid>https://dev.to/jonasmerlin/show-hidden-files-folders-on-macos-2861</guid>
      <description>&lt;p&gt;Actually, macOS makes it very simple now to toggle the display of hidden files on and off.&lt;/p&gt;

&lt;p&gt;Simply hit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'Command' + 'Shift' + '.'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Vim: Jump to first non-whitespace character in line</title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Mon, 26 Sep 2022 08:34:54 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/vim-jump-to-first-non-whitespace-character-in-line-4487</link>
      <guid>https://dev.to/jonasmerlin/vim-jump-to-first-non-whitespace-character-in-line-4487</guid>
      <description>&lt;p&gt;Press ...&lt;/p&gt;

&lt;p&gt;&lt;code&gt;^&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Yes, that's it.&lt;/p&gt;

</description>
      <category>vim</category>
      <category>tooling</category>
      <category>productivity</category>
    </item>
    <item>
      <title>VSCode VIM Tip: Trigger Hover Info</title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Thu, 08 Sep 2022 08:58:31 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/vscode-vim-tip-trigger-hover-info-9em</link>
      <guid>https://dev.to/jonasmerlin/vscode-vim-tip-trigger-hover-info-9em</guid>
      <description>&lt;p&gt;Error information from the likes of ESLint, TSC etc. are shown as overlays in VSCode. These can be triggered by hovering over the marked section of your code. But this requires you to use your mouse or trackpad. Ain't nobody got time for that!&lt;/p&gt;

&lt;p&gt;Luckily, you can just do the following when using VSCode Vim:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;p&gt;When you don't use VSCode Vim, you'll have to work a bit harder for that sweet, sweet error info though:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;Cmd&amp;gt;K + &amp;lt;Cmd&amp;gt;I&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Fun!&lt;/p&gt;

</description>
      <category>vim</category>
      <category>vscode</category>
      <category>tooling</category>
      <category>productivity</category>
    </item>
    <item>
      <title>VIM Tip: Replace Without Yanking</title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Thu, 08 Sep 2022 08:49:58 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/vim-tip-replace-without-yanking-1ojn</link>
      <guid>https://dev.to/jonasmerlin/vim-tip-replace-without-yanking-1ojn</guid>
      <description>&lt;p&gt;You yanked a word and want to use it to replace more than one other word. The naive approach of selecting each of these other words and then hitting &lt;code&gt;p&lt;/code&gt; doesn't really work though, does it? &lt;/p&gt;

&lt;p&gt;This is because the first &lt;code&gt;p&lt;/code&gt; yanks the highlighted word at the same time, replacing the original word in the register.&lt;/p&gt;

&lt;p&gt;The solution is to paste from the 0th register directly:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"0p&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;That you can do however many times you like.&lt;/p&gt;

</description>
      <category>vim</category>
      <category>vscode</category>
      <category>tooling</category>
      <category>productivity</category>
    </item>
    <item>
      <title>VIM Quick Tip: Convert Motion to Upper- or Lowercase</title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Sun, 05 Sep 2021 12:58:59 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/vim-quick-tip-convert-motion-to-upper-or-lowercase-3m34</link>
      <guid>https://dev.to/jonasmerlin/vim-quick-tip-convert-motion-to-upper-or-lowercase-3m34</guid>
      <description>&lt;p&gt;This is part of a series of posts that give you very small, quick tips on how to do things in VIM. This time: converting motions to upper- or lowercase. There are many ways to do this, but this is the one I'm using.&lt;/p&gt;

&lt;p&gt;Suppose you have the following "word": &lt;code&gt;screaming_snake&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you wanted to convert that to uppercase, move to the beginning of the word and type &lt;code&gt;gUw&lt;/code&gt; from normal mode, where &lt;code&gt;w&lt;/code&gt; is the word motion. This will give you &lt;code&gt;SCREAMING_SNAKE&lt;/code&gt;. Now, if you hit &lt;code&gt;guw&lt;/code&gt;, it will revert back to the original.&lt;/p&gt;

</description>
      <category>vim</category>
      <category>vscode</category>
    </item>
    <item>
      <title>In what order does Jest execute tests anyway? (And how to change it!)</title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Tue, 03 Aug 2021 12:34:18 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/in-what-order-does-jest-execute-tests-anyway-and-how-to-change-it-26pm</link>
      <guid>https://dev.to/jonasmerlin/in-what-order-does-jest-execute-tests-anyway-and-how-to-change-it-26pm</guid>
      <description>&lt;p&gt;Jest will execute different test files potentially in parallel, potentially in a different order from run to run. Per file, &lt;a href="https://jestjs.io/docs/setup-teardown#order-of-execution-of-describe-and-test-blocks"&gt;it will run all describe blocks first and then run tests in sequence, in the order it encountered them while executing the describe blocks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's an illustration of that per file behavior, copied straight out of the doc link above:&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;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;outer&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;describe outer-a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;describe inner 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;describe inner 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test for describe inner 1&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&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="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;describe outer-b&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test for describe outer&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&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="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;describe inner 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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;describe inner 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test for describe inner 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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;test for describe inner 2&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;describe outer-c&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// describe outer-a&lt;/span&gt;
&lt;span class="c1"&gt;// describe inner 1&lt;/span&gt;
&lt;span class="c1"&gt;// describe outer-b&lt;/span&gt;
&lt;span class="c1"&gt;// describe inner 2&lt;/span&gt;
&lt;span class="c1"&gt;// describe outer-c&lt;/span&gt;
&lt;span class="c1"&gt;// test for describe inner 1&lt;/span&gt;
&lt;span class="c1"&gt;// test for describe outer&lt;/span&gt;
&lt;span class="c1"&gt;// test for describe inner 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to run files in sequence as well, run Jest with the &lt;code&gt;--runInBand&lt;/code&gt; command line flag. (&lt;code&gt;-i&lt;/code&gt; does the same thing.) Doing this, the scheduler might still run them in a different &lt;em&gt;order&lt;/em&gt; from run to run. To prevent this as well, &lt;a href="https://jestjs.io/docs/configuration#testsequencer-string"&gt;you will need to define your own test sequencer&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;To sort test files alphabetically for example, create a file with the following contents:&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;// testSequencer.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Sequencer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@jest/test-sequencer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;CustomSequencer&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Sequencer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tests&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Test structure information&lt;/span&gt;
    &lt;span class="c1"&gt;// https://github.com/facebook/jest/blob/6b8b1404a1d9254e7d5d90a8934087a9c9899dab/packages/jest-runner/src/types.ts#L17-L21&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;copyTests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tests&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;copyTests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;testA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;testB&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;testA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;testB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&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="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;CustomSequencer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, set the following in your Jest config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// jest.config.js
{
  "testSequencer": "path/to/testSequencer.js"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>node</category>
      <category>testing</category>
    </item>
    <item>
      <title>Great Talks: Jest Architecture Overview </title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Wed, 28 Jul 2021 08:20:24 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/great-talks-jest-architecture-overview-1h73</link>
      <guid>https://dev.to/jonasmerlin/great-talks-jest-architecture-overview-1h73</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;❓ This post is the first in a series in which I will recommend and discuss talks on programming topics which I liked and found interesting. The idea is not to provide a detailed summary, but to draw your attention to and hopefully make you watch the talk itself, and then provide a few of my own observations and highlights as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Talk
&lt;/h2&gt;

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

&lt;p&gt;We'll kick this series off with a talk I watched recently. &lt;a href="https://youtu.be/3YDiloj8_d0"&gt;Jest Architecture Overview&lt;/a&gt; by &lt;a href="https://twitter.com/cpojer"&gt;Christoph Nakazawa&lt;/a&gt; goes over the architecture of the &lt;a href="https://jestjs.io/"&gt;Jest testing framework&lt;/a&gt; at a really well chosen level of detail. Not too high, not too low, just right to get a better understanding of, and feeling for, what is actually going on when you run Jest.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes &amp;amp; Observations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The lo-fi presentation is actually really refeshing and makes this feel like an architecture session you would do with your colleagues&lt;/li&gt;
&lt;li&gt;Whiteboard might actually beat out Powerpoint for technical topics, probably because it doesn't feel like you need to dumb anything down to fit the medium&lt;/li&gt;
&lt;li&gt;Also, there's a lot more meaningful interaction between the speaker and the text&lt;/li&gt;
&lt;li&gt;Basically, this has shown me how much unreaped potential there is for technical talks to give you real, instead of merely felt, insight&lt;/li&gt;
&lt;li&gt;Nakazawa talks a lot about the things Jest does purely to deliver a better user experience&lt;/li&gt;
&lt;li&gt;Jest does a lot of stuff to prioritize which tests to run first: e.g. it maintains a cache with tests and their results and will run tests that failed during the previous run first&lt;/li&gt;
&lt;li&gt;The most basic heuristic they use for this is file size, this breaks down when a test imports a lot of stuff though&lt;/li&gt;
&lt;li&gt;Over 50% of the work done during the firt run might actually be transforming the source, these results are cached though, which is why subseqent runs might be a lot faster&lt;/li&gt;
&lt;li&gt;Transforms of code are done very late in the process and only when the code is needed. This isn't done earlier because this static analysis would be hard to do reliably and might actually waste a lot of time&lt;/li&gt;
&lt;li&gt;Long-running tests are prioritized by the scheduler so they finish roughly when the smaller tests are finished as well. The idea here is to use one of the available cores or threads for such a long running process, while the others run the smaller ones. (Here, it isn't made clear what happens if there are a lot of long running tests. Will they occupy the available resources until there aren't enough long running tests to occupy all cores anymore? Or is the scheduler "smarter" than that? Would it actually be smarter at all to keep a core free, even if there are a lot of slow tests?)&lt;/li&gt;
&lt;li&gt;Jest is made up of a lot of small packages with very specific tasks&lt;/li&gt;
&lt;li&gt;These might actually be swapped out individually via the config if your usecase calls for it&lt;/li&gt;
&lt;li&gt;There's a lot going on, but there also seems to be a lot of change over time, with more and more stuff being split-up, replaced etc. Nothing comes out perfectly on first try.&lt;/li&gt;
&lt;li&gt;When it comes down to it, it's really all about the basics: walking a directory, filtering out files, importing code etc. These things are then combined into a framework. Jest's architecture makes this very explicit&lt;/li&gt;
&lt;li&gt;Naming is hard for everyone&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>testing</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Automatically lint &amp; format your code on commit when using Next.js</title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Sat, 24 Jul 2021 16:05:35 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/automatically-lint-format-your-code-on-commit-when-using-next-js-3p6g</link>
      <guid>https://dev.to/jonasmerlin/automatically-lint-format-your-code-on-commit-when-using-next-js-3p6g</guid>
      <description>&lt;p&gt;&lt;em&gt;In this post, we will be setting up &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt; with &lt;a href="https://typicode.github.io/husky/#/"&gt;Husky&lt;/a&gt; and &lt;a href="https://github.com/okonet/lint-staged"&gt;lint-staged&lt;/a&gt; to run &lt;a href="https://eslint.org/"&gt;ESLint&lt;/a&gt; and &lt;a href="https://prettier.io/"&gt;Prettier&lt;/a&gt; whenever we commit a file.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you want to take a look at the final product first, or if you don't care about the step-by-step, here's &lt;a href="https://github.com/jonasmerlin/next-lint-on-commit"&gt;the accompanying repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You probably already know, or can imagine, the advantages of automatically linting and formatting each and every piece of code commited to your repo. So I won't convince you of its merits here, but get straight into the action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up a new Next.js Project
&lt;/h2&gt;

&lt;p&gt;Start by setting up a new Next.js project if you don't have one yet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app &lt;span class="nt"&gt;--typescript&lt;/span&gt;
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn create next-app &lt;span class="nt"&gt;--typescript&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we are using the Typescript template. But you can simply leave the &lt;code&gt;--typescript&lt;/code&gt; off if you like to suffer. Your choice, really.&lt;/p&gt;

&lt;p&gt;Choose whatever name you want. I'll presume you chose "website" though.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to read more about the process of setting up Next.js, take a look at their &lt;a href="https://nextjs.org/docs/getting-started"&gt;getting started guide&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Prettier as a devDependency
&lt;/h2&gt;

&lt;p&gt;ESLint will look at your code and try to prevent potential bugs by looking at its semantics. Prettier will look at the formatting and change it according to its rules. Since Next.js comes with ESLint pre-installed and pre-configured, that's already taken care of. That leaves Prettier.&lt;/p&gt;

&lt;p&gt;Change into your newly created project folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;website
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, install Prettier as a devDependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; &lt;span class="nt"&gt;--save-exact&lt;/span&gt; prettier
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; &lt;span class="nt"&gt;--exact&lt;/span&gt; prettier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create an empty Prettier config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="o"&gt;{}&amp;gt;&lt;/span&gt; .prettierrc.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will let tools like your editor know you are using Prettier.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optional: Create a .prettierignore file
&lt;/h3&gt;

&lt;p&gt;If you plan to use Prettier outside of the Git hook we are setting up below, you should probably create a &lt;code&gt;.prettierignore&lt;/code&gt; file. This allows you to list folders and files you don't want to format.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; .prettierignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Prettier documentation says it's a good idea to base this on your "gitignore and .eslintignore (if you have one)." So ... do that.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to read more about the process of setting up Prettier, take a look at their &lt;a href="https://prettier.io/docs/en/install.html"&gt;installation guide&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Edit your .eslintrc
&lt;/h2&gt;

&lt;p&gt;Some of the ESLint rules Next.js comes pre-configured with are about formatting. But we want Prettier to handle everything related to the formatting of our code. This is why we'll install &lt;a href="https://github.com/prettier/eslint-config-prettier"&gt;eslint-config-prettier&lt;/a&gt; and add it to our &lt;code&gt;.eslintrc&lt;/code&gt;, where it will disable all existing rules that might interfere with Prettier.&lt;/p&gt;

&lt;p&gt;Install eslint-config-prettier by running the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; eslint-config-prettier
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; eslint-config-prettier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;.eslintrc&lt;/code&gt; Next.js created should look like the following:&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.eslintrc&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="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next/core-web-vitals"&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;Change this to the following:&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.eslintrc&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="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next/core-web-vitals"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prettier"&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;&lt;em&gt;If you want to read more about the process of combining ESLint and Prettier in a Next.js project, take a look at &lt;a href="https://nextjs.org/docs/basic-features/eslint#usage-with-prettier"&gt;the Next.js "Usage with Prettier" guide&lt;/a&gt;, as well as &lt;a href="https://prettier.io/docs/en/integrating-with-linters.html"&gt;Prettier's "Integrating with Linters" guide&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install lint-staged
&lt;/h2&gt;

&lt;p&gt;At this point, you would be able to run ESLint and Prettier manually. But ain't nobody got time for that. Also, "&lt;strong&gt;Manually&lt;/strong&gt; Lint &amp;amp; Format your Code on Commit When Using Next.js" is not the title of this article and I don't want to disappoint you. So let's introduce lint-staged into the mix.&lt;/p&gt;

&lt;p&gt;The good thing is that they make it very easy to set up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx mrm@2 lint-staged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will install Husky, a tool that makes is easy to manage Git hooks, and detect which linting and formatting tools are already installed. It will then set everything up more or less correctly. We'll come to the "less" part next.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to read more about the process of setting up lint-staged, take a look at &lt;a href="https://github.com/okonet/lint-staged#installation-and-setup"&gt;their installation and setup guide&lt;/a&gt;, as well as &lt;a href="https://prettier.io/docs/en/precommit.html"&gt;Prettier's pre-commit hook guide&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Edit the Git Hook
&lt;/h2&gt;

&lt;p&gt;After running the above, you should have the following entry in your &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&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;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"lint-staged"&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;"*.js"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eslint --cache --fix"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"*.{js,css,md}"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prettier --write"&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;Change this to the following:&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&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;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"lint-staged"&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;"*.{js,jsx,ts,tsx,css,md}"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prettier --write"&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;This will run Prettier on all staged files of the listed types when you run &lt;code&gt;git commit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, you would be forgiven to assume that to also run ESLint, we should put it in there as well. But since Next.js comes with its own pre-configured wrapper around ESLint, wich doesn't take the files it operates on as arguments, we will do something slightly different. We will edit the Git hook that Husky created, during the installation of lint-staged, directly. Right now, it should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In file .husky/pre-commit&lt;/span&gt;

&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/_/husky.sh"&lt;/span&gt;

npx lint-staged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change this to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In file .husky/pre-commit&lt;/span&gt;

&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;dirname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;/_/husky.sh"&lt;/span&gt;

yarn lint:write &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npx lint-staged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then add the following script to your &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;In&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&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;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&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="nl"&gt;"lint:write"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next lint --cache --fix"&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="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will call the Next.js version of ESLint and tell it to automatically &lt;code&gt;--fix&lt;/code&gt; any issues that it finds that can be fixed automatically. Also, the &lt;code&gt;--cache&lt;/code&gt; tells it to only do so on changed files.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to read more about the undocumented command line options Next.js' lint command accepts, take a look at my &lt;a href="https://dev.to/jonasmerlin/eslint-command-line-options-supported-by-next-lint-incl-fix-18c8"&gt;post on the topic&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  We're Done!
&lt;/h2&gt;

&lt;p&gt;Now, when you run &lt;code&gt;git commit&lt;/code&gt;, both ESLint and Prettier should check that you don't commit any crap. This should also work when using VSCode's own Git UI. Other Git UIs might have issues though. Sublime Merge for example can't find my node.js installation, most likely because it's installed and managed via nvm. There are almost certainly solutions to this, but since I haven't looked them up yet they fall outside the scope of this tutorial.&lt;/p&gt;

&lt;p&gt;Don't forget that you can use or take a look at &lt;a href="https://github.com/jonasmerlin/next-lint-on-commit"&gt;the accompanying repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hope you found this helpful. If you find any erros or run into issues, feel free to tell me in the comments.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 This post was published 2021/07/14 and last updated 2021/07/14. Since node libraries change and break all the time, there's a non-trivial chance that all of this is obsolete and none of it works when you read this in your flying taxi, gulpin' on insect protein shakes sometime in the distant future or, let's be honest here, next week. If so, tell me in the comments and I'll see if an update would still be relevant.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>git</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Use the Next.js Image Component in Storybook</title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Wed, 21 Jul 2021 13:01:30 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/how-to-use-the-next-js-image-component-in-storybook-1415</link>
      <guid>https://dev.to/jonasmerlin/how-to-use-the-next-js-image-component-in-storybook-1415</guid>
      <description>&lt;p&gt;&lt;em&gt;In this post, we will be setting up &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; and &lt;a href="https://storybook.js.org/" rel="noopener noreferrer"&gt;Storybook&lt;/a&gt; in a way that makes it possible to use Next.js' Image component in components rendered inside Storybook.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you want to take a look at the final product first, or if you don't care about the step-by-step, here's &lt;a href="https://github.com/jonasmerlin/next-storybook" rel="noopener noreferrer"&gt;the accompanying repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Rendering a component that uses the Next.js Image component inside Storybook might have you running into a few gotchas. I myself ran into two:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Storybook can't seem to find the image you statically import from your &lt;code&gt;public&lt;/code&gt; directory, resulting in the following error:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Failed to parse src "static/media/public/&amp;lt;imageName&amp;gt;.jpg" on `next/image`, if using relative image it must start with a leading slash "/" or be an absolute URL (http:// or https://)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Storybook can't find the blur placeholder image that is automatically generated by Next.js and injected into the &lt;code&gt;blurDataURL&lt;/code&gt; prop, resulting in the following error:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Image with src "static/media/public/&amp;lt;imageName&amp;gt;.jpg" has "placeholder='blur'" property but is missing the "blurDataURL" property.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reasons for both of these are actually the same: when run inside Storybook, your code won't run through Next.js' build process, during which the correct URLs/Paths and alternative sizes for your hosted images as well as the placeholder images are created and injected into your code.&lt;/p&gt;

&lt;p&gt;If you know how, both of these are straightforward to solve. But finding the solutions can be kind of an odyssey. So here they are in one place.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: in this post, I assume you have already set up both Next.js as well as Storybook. If not, do that and then come back here.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Storybook Can't Find Images Imported from Next.js' &lt;code&gt;public&lt;/code&gt; Directory
&lt;/h2&gt;

&lt;p&gt;Let's assume you have the following component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/ImageTest.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&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/image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;testImage&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;../public/testImage.jpg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ImageTest&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;testImage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A stack of colorful cans&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fill&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ImageTest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the following story for it:&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;// stories/ImageTest.stories.js&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="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ImageTest&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../components/ImageTest&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="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Image/ImageTest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ImageTest&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;Template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&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;ImageTest&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;KitchenSink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
&lt;span class="nx"&gt;KitchenSink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you were to run Storybook now, this would be what you saw:&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%2Fy31ndpdo1ou82mm76p88.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%2Fy31ndpdo1ou82mm76p88.png" alt="next-storybook-01" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I first encountered this, I reasoned Storybook simply couldn't find the assets in Next.js' &lt;code&gt;public/&lt;/code&gt; directory. But running with the &lt;code&gt;-s public/&lt;/code&gt; command line option to tell it about the directory doesn't solve the problem.&lt;/p&gt;

&lt;p&gt;After some digging, the issue here seems to be the things going on behind the scenes of the &lt;code&gt;Image&lt;/code&gt; component. One of its most useful features is that it will automatically optimize the image you pass it and create and serve alternative sizings of it on demand. Next.js can't work its magic when the &lt;code&gt;Image&lt;/code&gt; component is rendered inside Storybook though, and that's why the solution here is to simply turn these optimizations off in this context. To do this, we'll have to add the following to Storybook's setup 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="c1"&gt;// .storybook/preview.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;NextImage&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/image&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;OriginalNextImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NextImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;NextImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&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="na"&gt;configurable&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="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&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="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;OriginalNextImage&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;unoptimized&lt;/span&gt;
    &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code will replace the &lt;code&gt;Image&lt;/code&gt; component's default export with our own version, which adds the &lt;code&gt;unoptimized&lt;/code&gt; prop to every instance of it. With this, "the source image will be served as-is instead of changing quality, size, or format", according to the Next.js documentation. And since we added this to Storybook's setup code, this will only be done when our component is rendered inside Storybook.&lt;/p&gt;

&lt;p&gt;Credit for this solution goes to &lt;a href="https://github.com/rajansolanki" rel="noopener noreferrer"&gt;Github user rajansolanki&lt;/a&gt;, who synthesized a few prior solution attempts in &lt;a href="https://github.com/vercel/next.js/issues/18393#issuecomment-783269086" rel="noopener noreferrer"&gt;this comment on the relevant Github issue&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to read more about Next.js' &lt;code&gt;Image&lt;/code&gt; component and the props you can pass into it, take a look at &lt;a href="https://nextjs.org/docs/basic-features/image-optimization" rel="noopener noreferrer"&gt;the introduction to its features&lt;/a&gt; as well as &lt;a href="https://nextjs.org/docs/api-reference/next/image#unoptimized" rel="noopener noreferrer"&gt;its documentation&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Storybook Can't Find the Blur Placeholder Image That is Automatically Generated by Next.js and Injected Into the &lt;code&gt;blurDataURL&lt;/code&gt; Prop
&lt;/h2&gt;

&lt;p&gt;Another nice feature of the &lt;code&gt;Image&lt;/code&gt; component is that it will automatically generate small, blurred placeholder images for display during the loading of the full image.&lt;/p&gt;

&lt;p&gt;All we need to do to activate this feature is to pass the &lt;code&gt;placeholder="blur"&lt;/code&gt; prop:&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;// src/components/ImageTest.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&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/image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;testImage&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;../public/testImage.jpg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ImageTest&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;testImage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A stack of colorful cans&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fill&lt;/span&gt;&lt;span class="dl"&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;blur&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// this is new!&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ImageTest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But this will immediately result in the following error when we run Storybook again:&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%2Fzr1brrj04y800ge8pwa3.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%2Fzr1brrj04y800ge8pwa3.png" alt="next-storybook-02" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The reason for this is basically the same as before. Next.js will generate a placeholder image and inject it into the component for us. So that one line of code we added actually does a whole lot in the background, all of which, again, is not automatically done when run inside Storybook. Luckily the solution is a one liner as well:&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;// .storybook/preview.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;NextImage&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/image&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;OriginalNextImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NextImage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;NextImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&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="na"&gt;configurable&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="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&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="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;OriginalNextImage&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;unoptimized&lt;/span&gt;
      &lt;span class="c1"&gt;// this is new!&lt;/span&gt;
      &lt;span class="nx"&gt;blurDataURL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data:image/jpeg;base64,/9j/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICwgIyYnKSopGR8tMC0oMCUoKSj/2wBDAQcHBwoIChMKChMoGhYaKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCj/wAARCAADAAQDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAf/xAAbEAADAAMBAQAAAAAAAAAAAAABAgMABAURUf/EABUBAQEAAAAAAAAAAAAAAAAAAAMF/8QAFxEAAwEAAAAAAAAAAAAAAAAAAAECEf/aAAwDAQACEQMRAD8Anz9voy1dCI2mectSE5ioFCqia+KCwJ8HzGMZPqJb1oPEf//Z&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we have done here is a bit of a hack, granted. But it's effective, as all good hacks are. With this, we're setting all placeholder images to be the same data, at least in the context of Storybook. The string above is actually the base64 representation of the placeholder for the &lt;a href="https://plaiceholder.co/" rel="noopener noreferrer"&gt;plaiceholder example image on their homepage&lt;/a&gt;. But we could just as easily upload our own image there and use that.&lt;/p&gt;

&lt;p&gt;And with this, you should see the following when running Storybook:&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%2Fdpc6m420z6f4vo4tf8td.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%2Fdpc6m420z6f4vo4tf8td.png" alt="next-storybook-04" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: our testImage for this is &lt;a href="https://unsplash.com/photos/6VCtB0wdgM0" rel="noopener noreferrer"&gt;this image by Studio Blackthorns on Unsplash&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want to read more about the automatic placeholder generation of Next.js' &lt;code&gt;Image&lt;/code&gt; component, take a look at &lt;a href="https://nextjs.org/docs/api-reference/next/image#placeholder" rel="noopener noreferrer"&gt;the &lt;code&gt;placeholder&lt;/code&gt; prop's documentation&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Don't forget that you can use or take a look at &lt;a href="https://github.com/jonasmerlin/next-storybook" rel="noopener noreferrer"&gt;the accompanying repo&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 This post was published 2021/07/21 and last updated 2021/07/21. Since node libraries change and break all the time, there's a non-trivial chance that all of this is obsolete and none of it works when you read this in your flying taxi, gulpin' on insect protein shakes sometime in the distant future or, let's be honest here, next week. If so, tell me in the comments and I'll see if an update would still be relevant.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>nextjs</category>
      <category>storybook</category>
      <category>react</category>
    </item>
    <item>
      <title>eslint command line options supported by next lint (incl. --fix)</title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Wed, 07 Jul 2021 13:33:57 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/eslint-command-line-options-supported-by-next-lint-incl-fix-18c8</link>
      <guid>https://dev.to/jonasmerlin/eslint-command-line-options-supported-by-next-lint-incl-fix-18c8</guid>
      <description>&lt;p&gt;next.js comes with its own CLI for linting your code, &lt;code&gt;next lint&lt;/code&gt;, which is basically a preconfigured wrapper around eslint.&lt;/p&gt;

&lt;p&gt;What the documentation doesn't tell you though is whether this wrapper accepts the same command line options as eslint. The short answer is: it doesn't. At least not &lt;em&gt;all&lt;/em&gt; of them, but a whole lot more than the only one documented by next.js' sparse documentation for this command, the &lt;code&gt;--dir&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;I found out about this only via &lt;a href="https://github.com/vercel/next.js/discussions/26179"&gt;this GitHub issue&lt;/a&gt;. It links to &lt;a href="https://github.com/vercel/next.js/blob/canary/packages/next/cli/next-lint.ts#L91-L120"&gt;this file on GitHub, which contains a comment with the full list of supported options&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The exact list and place might change in the future, but it should pretty much always stay in that file, which is where you will find the most recent version of the list. Still, for convenience's sake, here's the list as of 2021/07/07:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Options
        Basic configuration:
          -h, --help                     List this help
          -d, --dir Array                Set directory, or directories, to run ESLint - default: 'pages', 'components', and 'lib'
          -c, --config path::String      Use this configuration file, overriding all other config options
          --ext [String]                 Specify JavaScript file extensions - default: .js, .jsx, .ts, .tsx
          --resolve-plugins-relative-to path::String  A folder where plugins should be resolved from, CWD by default
        Specifying rules:
          --rulesdir [path::String]      Use additional rules from this directory
        Fixing problems:
          --fix                          Automatically fix problems
          --fix-type Array               Specify the types of fixes to apply (problem, suggestion, layout)
        Ignoring files:
          --ignore-path path::String     Specify path of ignore file
          --no-ignore                    Disable use of ignore files and patterns
        Handling warnings:
          --quiet                        Report errors only - default: false
          --max-warnings Int             Number of warnings to trigger nonzero exit code - default: -1
        Inline configuration comments:
          --no-inline-config             Prevent comments from changing config or rules
          --report-unused-disable-directives  Adds reported errors for unused eslint-disable directives ("error" | "warn" | "off")
        Caching:
          --cache                        Only check changed files - default: false
          --cache-location path::String  Path to the cache file or directory - default: .eslintcache

        Miscellaneous:
          --no-error-on-unmatched-pattern  Prevent errors when pattern is unmatched - default: false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nextjs</category>
      <category>eslint</category>
      <category>react</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Source Your Own Daily-Quotes in Obsidian</title>
      <dc:creator>Jonas Schumacher</dc:creator>
      <pubDate>Mon, 07 Jun 2021 19:31:29 +0000</pubDate>
      <link>https://dev.to/jonasmerlin/source-your-own-daily-quotes-in-obsidian-4i7i</link>
      <guid>https://dev.to/jonasmerlin/source-your-own-daily-quotes-in-obsidian-4i7i</guid>
      <description>&lt;p&gt;&lt;strong&gt;Hey! This post has gotten a bit old and I'm no longer using the solution described here myself. I will keep the post around, but now recommend taking a look at either &lt;a href="https://github.com/decatetsu/local-quotes" rel="noopener noreferrer"&gt;this plugin&lt;/a&gt; or &lt;a href="https://forum.obsidian.md/t/displaying-a-random-quote-in-my-daily-note/27225/3" rel="noopener noreferrer"&gt;this more elegant solution&lt;/a&gt;. Though I can't vouch for either myself, I no longer feel confident in my own solution decribed below as well.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;In this post you will learn how to collect quotes in Obsidian and then use them inside your daily notes for inspiration. Either as a replacement or in addition to the quotes from &lt;a href="https://quotes.rest/" rel="noopener noreferrer"&gt;https://quotes.rest/&lt;/a&gt; many people already use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;If you use Obsidian there's a good chance you heard about the concept of daily notes. They are a great tool to add to your workflow and Obsidian makes it very easy to use them via its native Daily Note Plug-In. Also, if you have looked for inspiration in how other people set-up and use their daily notes, it's safe to assume you've seen at least a few that make use of &lt;a href="https://silentvoid13.github.io/Templater/" rel="noopener noreferrer"&gt;Templater's&lt;/a&gt; &lt;code&gt;tp.web.daily_quote()&lt;/code&gt; function to query &lt;a href="https://quotes.rest/" rel="noopener noreferrer"&gt;https://quotes.rest/&lt;/a&gt; for an inspirational quote to display for the day.&lt;/p&gt;

&lt;p&gt;This is great! But in keeping with the spirit of letting your notes represent &lt;em&gt;your&lt;/em&gt; interests and helping you remember what you learn, I thought it would be cool to collect my own quotes from the things I read, watch and listen to and then display a random one of those in each of my daily notes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You'll Need
&lt;/h2&gt;

&lt;p&gt;If you want to replicate the whole workflow described below, you will need Obsidian itself and then:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enable the "Daily notes" plugin from the Core plugins&lt;/li&gt;
&lt;li&gt;Install the &lt;a href="https://silentvoid13.github.io/Templater/" rel="noopener noreferrer"&gt;Templater&lt;/a&gt; Community plugin&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I Collect My Quotes
&lt;/h2&gt;

&lt;p&gt;When I process some kind of media to incorporate it into my vault, I collect quotes I find interesting, beautiful or which simply describe the contents of the piece of media eloquently or succinctly.&lt;/p&gt;

&lt;p&gt;For each of these, I create a new note with a title of the form &lt;code&gt;(QUOTE) "This is the beautiful, eloquent quote I captured."&lt;/code&gt; (So to be clear: the quote itself goes inside the title.)&lt;/p&gt;

&lt;p&gt;I then you'll need to put at least the tag &lt;code&gt;#quote&lt;/code&gt; inside the body. You can additionally put whatever you want in there. But for this to work, you will need at least that tag - or another tag of your choosing you will put in all and only your quote notes - inside the note.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, to recap&lt;/strong&gt;: quote goes in the title, &lt;code&gt;#quote&lt;/code&gt; (or a tag of your choosing) in the body.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create A Script to Link to a Random Quote
&lt;/h2&gt;

&lt;p&gt;Now, create a new note wherever you create your templates and put the following script in there:&lt;/p&gt;

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

&lt;span class="o"&gt;&amp;lt;%*&lt;/span&gt; 
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;quoteFiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metadataCache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCachedFiles&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;filename&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;// get all filenames in the vault and iterate through all of them, calling a function for each of them&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metadataCache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// get the tags in the  file w/ the given name&lt;/span&gt;
        &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[]).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#quote&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// filter out all tags that are not "#quote"&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;tags&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;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;(QUOTE)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// list will contain at least one tag for the relevant notes, also filter out all notes that dont start w/ "QUOTE"&lt;/span&gt;
            &lt;span class="nx"&gt;quoteFiles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filename&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="nx"&gt;filename&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;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// cut off last three characters from filename, otherwise the links would contain `.md` at the end&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;randomIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;quoteFiles&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;tR&lt;/span&gt; &lt;span class="o"&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;quoteFiles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;randomIndex&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;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;And then put this one inside your daily note template:&lt;/p&gt;

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

&lt;span class="o"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="nx"&gt;tp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[[Random Quote]]&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That's it!&lt;/p&gt;

&lt;p&gt;Here's an example from my daily note from today:&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%2Fnynlt9efxi46xgd8p5pv.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%2Fnynlt9efxi46xgd8p5pv.png" alt="an example from my vault"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(The quote is from Jeroen Fieren's great post &lt;a href="https://technosoof.wordpress.com/2020/05/23/the-opposite-collectors-fallacy/" rel="noopener noreferrer"&gt;The Opposite Collector’s Fallacy&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;p&gt;In creating this, I had help from users torantine, SkepticMystic and koala from the Obsidian Discord Server. Also, the function above is &lt;em&gt;heavily&lt;/em&gt; based on the &lt;code&gt;findTargets()&lt;/code&gt; function from the &lt;a href="https://github.com/pjeby/tag-wrangler" rel="noopener noreferrer"&gt;tag-wrangler&lt;/a&gt; plugin.&lt;/p&gt;

&lt;p&gt;Also, thanks to &lt;a class="mentioned-user" href="https://dev.to/thedyslexicpoet"&gt;@thedyslexicpoet&lt;/a&gt; for catching a bug in my original script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Edits
&lt;/h2&gt;

&lt;p&gt;2021/07/24:&lt;/p&gt;

&lt;p&gt;Fixed a potential bug in the script by removing the &lt;code&gt;'&lt;/code&gt; in &lt;code&gt;don't&lt;/code&gt; in this line:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tags&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;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;(QUOTE)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// list will contain at least one tag for the relevant notes, also filter out all notes that don't start w/ "QUOTE"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Turning it into this:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tags&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;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;(QUOTE)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// list will contain at least one tag for the relevant notes, also filter out all notes that dont start w/ "QUOTE"&lt;/span&gt;


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

&lt;/div&gt;

</description>
      <category>obsidian</category>
      <category>pkm</category>
      <category>productivity</category>
      <category>zettelkasten</category>
    </item>
  </channel>
</rss>
