Björn-Eric's Developer notes
https://bjornericabr.prose.sh
2022-11-18T06:17:56Z
collection of thoughts and findings working as a fullstack web developer.
bjornericabr
Persist Svelte store in localstorage
2022-12-31T03:52:11Z
https://bjornericabr.prose.sh/persist-svelte-store-in-localstorage
<p>Svelte stores are awesome, and sometimes you want to keep them around a bit
longer. Here, we use localstorage.</p>
<pre class="chroma"><code><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">writable</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">"svelte/store"</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="kr">import</span> <span class="kr">type</span> <span class="p">{</span> <span class="nx">IProduct</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">"$lib/types"</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="kr">export</span> <span class="kr">const</span> <span class="nx">storeName</span> <span class="o">=</span> <span class="s2">"dailies"</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="kd">let</span> <span class="nx">initValue</span>: <span class="kt">IProduct</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[];</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1">// Load Store from localstorage
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"></span><span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nb">window</span> <span class="o">!==</span> <span class="s2">"undefined"</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"> <span class="kr">const</span> <span class="nx">storedStore</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="nx">storeName</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">storedStore</span> <span class="o">&&</span> <span class="nx">storedStore</span> <span class="o">!==</span> <span class="s2">"[]"</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"> <span class="nx">initValue</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">storedStore</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="kr">export</span> <span class="kr">const</span> <span class="nx">dailies</span> <span class="o">=</span> <span class="nx">writable</span><span class="p"><</span><span class="nt">IProduct</span><span class="err">[]</span><span class="p">>([...</span><span class="nx">initValue</span><span class="p">]);</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1">// Persist store in localstorage
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="c1"></span><span class="nx">dailies</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">((</span><span class="nx">val</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nb">window</span> <span class="o">!==</span> <span class="s2">"undefined"</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl"> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="nx">storeName</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">val</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="p">});</span>
</span></span></code></pre><h3 id="but-what-if-we-want-to-create-lots-of-stores"><a class="anchor" href="#but-what-if-we-want-to-create-lots-of-stores" rel="nofollow">#</a> But what if we want to create lots of stores?</h3>
<p>Let's make our store creation it into a function:</p>
<pre class="chroma"><code><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">writable</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">"svelte/store"</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kr">export</span> <span class="kd">function</span> <span class="nx">createStore</span><span class="p"><</span><span class="nt">T</span><span class="p">>(</span><span class="nx">storeName</span>: <span class="kt">string</span><span class="p">,</span> <span class="nx">initValue</span>: <span class="kt">T</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"> <span class="c1">// Load Store from localstorage
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nb">window</span> <span class="o">!==</span> <span class="s2">"undefined"</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"> <span class="kr">const</span> <span class="nx">storedStore</span> <span class="o">=</span> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">getItem</span><span class="p">(</span><span class="nx">storeName</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">storedStore</span> <span class="o">&&</span> <span class="nx">storedStore</span> <span class="o">!==</span> <span class="s2">"[]"</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"> <span class="nx">initValue</span> <span class="o">=</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">storedStore</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"> <span class="kr">const</span> <span class="nx">store</span> <span class="o">=</span> <span class="nx">writable</span><span class="p"><</span><span class="nt">T</span><span class="p">>(</span><span class="nx">initValue</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl"> <span class="c1">// Persist store in localstorage
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="c1"></span> <span class="nx">store</span><span class="p">.</span><span class="nx">subscribe</span><span class="p">((</span><span class="nx">val</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nb">window</span> <span class="o">!==</span> <span class="s2">"undefined"</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"> <span class="nx">localStorage</span><span class="p">.</span><span class="nx">setItem</span><span class="p">(</span><span class="nx">storeName</span><span class="p">,</span> <span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">val</span><span class="p">));</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"> <span class="p">});</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl"> <span class="k">return</span> <span class="nx">store</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="p">}</span>
</span></span></code></pre><p>We now have a store creation function that takes two arguments, 1. the name of
the store and 2. an initial store value. We can use it like this:</p>
<pre class="chroma"><code><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// demoStore.ts
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span><span class="kr">import</span> <span class="p">{</span> <span class="nx">createStore</span> <span class="p">}</span> <span class="kr">from</span> <span class="s2">"./createStore"</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="kr">export</span> <span class="kr">type</span> <span class="nx">Demo</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"> <span class="nx">name</span>: <span class="kt">string</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="kr">export</span> <span class="kr">const</span> <span class="nx">demo</span> <span class="o">=</span> <span class="nx">createStore</span><span class="p"><</span><span class="nt">Demo</span><span class="err">[]</span><span class="p">>(</span><span class="s2">"demoStore"</span><span class="p">,</span> <span class="p">[]);</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1">// Mutation functions related to store
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"></span><span class="kr">export</span> <span class="kd">function</span> <span class="nx">addDemo</span><span class="p">(</span><span class="nx">name</span>: <span class="kt">string</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"> <span class="nx">demo</span><span class="p">.</span><span class="nx">update</span><span class="p">((</span><span class="nx">draft</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"> <span class="kr">const</span> <span class="nx">next</span> <span class="o">=</span> <span class="p">[...</span><span class="nx">draft</span><span class="p">];</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"> <span class="nx">next</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span> <span class="nx">name</span> <span class="p">});</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"> <span class="k">return</span> <span class="nx">next</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"> <span class="p">});</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="p">}</span>
</span></span></code></pre><hr>
<p><a href="/" rel="nofollow">Home</a></p>
Currying in Typescript
2022-12-21T08:33:31Z
https://bjornericabr.prose.sh/currying
<pre class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="kd">function</span> <span class="nx">a</span><span class="p">(</span><span class="nx">one</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"> <span class="k">return</span> <span class="kd">function</span> <span class="nx">b</span><span class="p">(</span><span class="nx">two</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"> <span class="k">return</span> <span class="kd">function</span> <span class="nx">c</span><span class="p">(</span><span class="nx">three</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">one</span><span class="p">,</span> <span class="nx">two</span><span class="p">,</span> <span class="nx">three</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"> <span class="p">};</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"> <span class="p">};</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="p">}</span>
</span></span></code></pre><p>is the same as</p>
<pre class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="kr">const</span> <span class="nx">a</span> <span class="o">=</span> <span class="p">(</span><span class="nx">one</span><span class="p">)</span> <span class="p">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"> <span class="k">return</span> <span class="p">(</span><span class="nx">two</span><span class="p">)</span> <span class="p">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"> <span class="k">return</span> <span class="p">(</span><span class="nx">three</span><span class="p">)</span> <span class="p">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">one</span><span class="p">,</span> <span class="nx">two</span><span class="p">,</span> <span class="nx">three</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"> <span class="p">};</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"> <span class="p">};</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="p">};</span>
</span></span></code></pre><p>is the same as</p>
<pre class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="kr">const</span> <span class="nx">a</span> <span class="o">=</span> <span class="p">(</span><span class="nx">one</span><span class="p">)</span> <span class="p">=></span> <span class="p">(</span><span class="nx">two</span><span class="p">)</span> <span class="p">=></span> <span class="p">(</span><span class="nx">three</span><span class="p">)</span> <span class="p">=></span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">one</span><span class="p">,</span> <span class="nx">two</span><span class="p">,</span> <span class="nx">three</span><span class="p">);</span>
</span></span></code></pre><p>They are all called the same</p>
<pre class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="nx">a</span><span class="p">(</span><span class="mi">12</span><span class="p">)(</span><span class="mi">14</span><span class="p">)(</span><span class="mi">16</span><span class="p">);</span> <span class="c1">// 12, 14, 16
</span></span></span></code></pre><h2 id="partially-calling"><a class="anchor" href="#partially-calling" rel="nofollow">#</a> Partially calling</h2>
<p>Calling the function less times than parameters accepted will return the last
function with the two previous params baked in</p>
<pre class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="kr">const</span> <span class="nx">c</span> <span class="o">=</span> <span class="nx">a</span><span class="p">(</span><span class="mi">12</span><span class="p">)(</span><span class="mi">14</span><span class="p">);</span> <span class="c1">// (c) => console.log(a, b, c)
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"></span><span class="nx">c</span><span class="p">(</span><span class="mi">16</span><span class="p">);</span> <span class="c1">// 12, 14, 16
</span></span></span></code></pre><hr>
<p><a href="/" rel="nofollow">Home</a></p>
The naming of things
2022-12-15T08:48:58Z
https://bjornericabr.prose.sh/the-naming-of-things
<h2 id="naming-api-services-when-using-react-query"><a class="anchor" href="#naming-api-services-when-using-react-query" rel="nofollow">#</a> Naming API services when using React Query</h2>
<p>📁 Folder: <code>/services/{path}</code> (services can be whatever you want but services is
vague enough).</p>
<p><code>GET</code> is implied.</p>
<p><code>use{ Create | Delete | Update}{Noun(id) | Nouns}.ts</code></p>
<table>
<thead>
<tr>
<th>API Path</th>
<th>Doing</th>
<th>Hook Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>/users</td>
<td>GET all users</td>
<td><code>useUsers()</code></td>
</tr>
<tr>
<td>/users/{email}</td>
<td>GET user by email</td>
<td><code>useUser(email:string)</code></td>
</tr>
<tr>
<td>/users/{email}</td>
<td>PUT update user</td>
<td><code>useUpdateUser(user:User)</code></td>
</tr>
</tbody>
</table>
<hr>
<p><a href="/" rel="nofollow">Home</a></p>
There are only two hard things in Computer Science; cache invalidation and naming things. - Phil Karlton
Typescript Function and Type Utils
2022-12-12T10:05:55Z
https://bjornericabr.prose.sh/typescript-function-and-type-utils
<h3 id="check-if-object-is-empty"><a class="anchor" href="#check-if-object-is-empty" rel="nofollow">#</a> Check if object is empty</h3>
<pre class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="cm"> * Check if an object is empty
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="kr">export</span> <span class="kd">function</span> <span class="nx">isEmpty</span><span class="p">(</span><span class="nx">obj</span>: <span class="kt">Object</span><span class="p">)</span><span class="o">:</span> <span class="kr">boolean</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"> <span class="k">return</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">obj</span><span class="p">).</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="p">}</span>
</span></span></code></pre><hr>
<p><a href="/" rel="nofollow">Home</a></p>
A collection of small utility functions and utility types.
Conditionally add to array or object in Typescript
2022-12-12T14:24:59Z
https://bjornericabr.prose.sh/conditionally-add-to-array-or-object
<p>Conditionally add to object</p>
<pre class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">id</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">user</span><span class="p">;</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="kr">const</span> <span class="nx">conditionallyAdded</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"> <span class="c1">// Conditionally add name if it exists
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"></span> <span class="p">...(</span><span class="nx">name</span> <span class="o">&&</span> <span class="p">{</span> <span class="nx">name</span> <span class="p">}),</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"> <span class="c1">// ... and add id (if it exists) as userId
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="c1"></span> <span class="p">...(</span><span class="nx">id</span> <span class="o">&&</span> <span class="p">{</span><span class="nx">userId</span>: <span class="kt">id</span><span class="p">})</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="p">}</span>
</span></span></code></pre><p>Conditionally add to array</p>
<pre class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="c1">// Add 'canEdit' and 'canDelete' to userPrivileges array if user is admin
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="c1"></span><span class="kr">const</span> <span class="nx">userPrivileges</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'canRead'</span><span class="p">,</span> <span class="s1">'canWrite'</span><span class="p">]</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="kr">const</span> <span class="nx">privileges</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"> <span class="p">...(</span><span class="nx">user</span><span class="p">.</span><span class="nx">isAdmin</span> <span class="o">?</span> <span class="p">[</span><span class="s1">'canEdit'</span><span class="p">,</span> <span class="s1">'canDelete'</span><span class="p">]</span> <span class="o">:</span> <span class="p">[]),</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"> <span class="p">...</span><span class="nx">userPrivileges</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="p">]</span>
</span></span></code></pre><p>@ref <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax" rel="nofollow">MDN: Spread syntax (...)</a></p>
<hr>
<p><a href="/" rel="nofollow">Home</a></p>
Avoid undefined params in objects by conditionally spreading them.
Measure execution times in Javascript
2022-12-31T03:52:11Z
https://bjornericabr.prose.sh/measure-execution-time-in-javascript
<h2 id="using-consoletime"><a class="anchor" href="#using-consoletime" rel="nofollow">#</a> Using <code>console.time</code></h2>
<pre class="chroma"><code><span class="line"><span class="ln"> 1</span><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">time</span><span class="p">(</span><span class="s1">'Looping'</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">step</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">step</span> <span class="o"><</span> <span class="mf">100.000</span><span class="p">;</span> <span class="nx">step</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"> <span class="c1">// Do something 100 000 times
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">timeLog</span><span class="p">(</span><span class="s1">'Looping'</span><span class="p">)</span> <span class="c1">// Log out current time
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">step</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">step</span> <span class="o"><</span> <span class="mf">100.000</span><span class="p">;</span> <span class="nx">step</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"> <span class="c1">// Do something 100 000 more times
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">timeEnd</span><span class="p">(</span><span class="s1">'Looping'</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1">// output: Looping: 0.09716796875 ms
</span></span></span></code></pre><h2 id="using-performancenow"><a class="anchor" href="#using-performancenow" rel="nofollow">#</a> using <code>performance.now</code></h2>
<p>In the next example we could use <code>new Date()</code> but that would not give us the ms granularity of <a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance/now" rel="nofollow"><code>performance.now</code></a></p>
<pre class="chroma"><code><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kr">const</span> <span class="nx">timeStart</span> <span class="o">=</span> <span class="nx">performance</span><span class="p">.</span><span class="nx">now</span><span class="p">()</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">step</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">step</span> <span class="o"><</span> <span class="mi">100000000</span><span class="p">;</span> <span class="nx">step</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"> <span class="c1">// Do something 100 000 times
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="kr">const</span> <span class="nx">timeIntermediate</span> <span class="o">=</span> <span class="nx">performance</span><span class="p">.</span><span class="nx">now</span><span class="p">()</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`Intermediate time </span><span class="si">${</span><span class="nx">timeIntermediate</span> <span class="o">-</span> <span class="nx">timeStart</span><span class="si">}</span><span class="sb"> ms`</span><span class="p">)</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">step</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">step</span> <span class="o"><</span> <span class="mi">100000000</span><span class="p">;</span> <span class="nx">step</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"> <span class="c1">// Do something 100 000 times
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="kr">const</span> <span class="nx">timeEnd</span> <span class="o">=</span> <span class="nx">performance</span><span class="p">.</span><span class="nx">now</span><span class="p">()</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`End time </span><span class="si">${</span><span class="p">(</span><span class="nx">timeEnd</span> <span class="o">-</span> <span class="nx">timeStart</span><span class="p">)</span><span class="o">*</span><span class="mi">1000</span><span class="si">}</span><span class="sb"> s`</span><span class="p">)</span>
</span></span></code></pre><hr>
<p><a href="/" rel="nofollow">Home</a></p>
Poor mans React Query / SWR
2022-12-12T10:27:22Z
https://bjornericabr.prose.sh/poor-mans-react-query-swr
<p>Sometimes you don't want to, or can't add a (another) dependency and just want to send of a request and know how it went.</p>
<pre class="chroma"><code><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// useFetcher.ts
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span><span class="kr">export</span> <span class="kd">function</span> <span class="nx">useFetcher</span><span class="p"><</span><span class="nt">T</span><span class="p">>(</span><span class="nx">url</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="p">{</span> <span class="nx">isLoading</span>: <span class="kt">boolean</span><span class="p">,</span> <span class="nx">error</span>: <span class="kt">any</span><span class="p">,</span> <span class="nx">data</span>: <span class="kt">T</span> <span class="o">|</span> <span class="kc">undefined</span> <span class="p">}</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"> <span class="kr">const</span> <span class="p">[</span><span class="nx">data</span><span class="p">,</span> <span class="nx">setData</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="kc">undefined</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"> <span class="kr">const</span> <span class="p">[</span><span class="nx">isLoading</span><span class="p">,</span> <span class="nx">setIsLoading</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"> <span class="kr">const</span> <span class="p">[</span><span class="nx">error</span><span class="p">,</span> <span class="nx">setError</span><span class="p">]</span> <span class="o">=</span> <span class="nx">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"> <span class="kr">const</span> <span class="kr">get</span> <span class="o">=</span> <span class="kr">async</span> <span class="p">()</span> <span class="o">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"> <span class="nx">setIsLoading</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"> <span class="nx">fetch</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"> <span class="p">.</span><span class="nx">then</span><span class="p">((</span><span class="nx">resp</span><span class="p">)</span> <span class="o">=></span> <span class="nx">resp</span><span class="p">.</span><span class="nx">json</span><span class="p">())</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"> <span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">data</span> <span class="o">=></span> <span class="nx">setData</span><span class="p">(</span><span class="nx">data</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"> <span class="p">.</span><span class="k">catch</span><span class="p">(</span><span class="nx">error</span> <span class="o">=></span> <span class="nx">setError</span><span class="p">(</span><span class="nx">error</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"> <span class="p">.</span><span class="k">finally</span><span class="p">(()</span> <span class="o">=></span> <span class="nx">setIsLoading</span><span class="p">(</span><span class="kc">false</span><span class="p">))</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl"> <span class="nx">useEffect</span><span class="p">(()</span> <span class="o">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"> <span class="kr">get</span><span class="p">()</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"> <span class="p">},</span> <span class="p">[])</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl"> <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl"> <span class="nx">data</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl"> <span class="nx">isLoading</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">25</span><span class="cl"> <span class="nx">error</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">26</span><span class="cl"> <span class="p">};</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="p">}</span>
</span></span></code></pre><p>And use it something like this:</p>
<pre class="chroma"><code><span class="line"><span class="ln"> 1</span><span class="cl"><span class="kr">type</span> <span class="nx">Todo</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"> <span class="nx">userId</span>: <span class="kt">number</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"> <span class="nx">id</span>: <span class="kt">number</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"> <span class="nx">title</span>: <span class="kt">string</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"> <span class="nx">completed</span>: <span class="kt">boolean</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="kr">const</span> <span class="nx">todos</span> <span class="o">=</span> <span class="nx">useFetcher</span><span class="p"><</span><span class="nt">Todo</span><span class="err">[]</span><span class="p">>(</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"> <span class="s1">'https://jsonplaceholder.typicode.com/todos'</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="nx">todos</span><span class="p">.</span><span class="nx">isLoading</span><span class="p">)</span> <span class="k">return</span> <span class="p"><</span><span class="nt">div</span><span class="p">></span><span class="nx">Loading</span><span class="p">...</</span><span class="nt">div</span><span class="p">></span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="nx">todos</span><span class="p">.</span><span class="nx">error</span><span class="p">)</span> <span class="k">return</span> <span class="p"><</span><span class="nt">div</span><span class="p">></span><span class="nb">Error</span><span class="o">:</span> <span class="p">{</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="p">}</</span><span class="nt">div</span><span class="p">></span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">return</span> <span class="p">(</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"> <span class="p"><</span><span class="nt">ul</span><span class="p">></span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"> <span class="p">{</span><span class="nx">todos</span><span class="p">.</span><span class="nx">data</span><span class="o">?</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">todo</span><span class="p">)</span> <span class="o">=></span> <span class="p">(</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"> <span class="p"><</span><span class="nt">li</span> <span class="na">key</span><span class="o">=</span><span class="p">{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">id</span><span class="p">}>{</span><span class="nx">todo</span><span class="p">.</span><span class="nx">title</span><span class="p">}</</span><span class="nt">li</span><span class="p">></span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"> <span class="p">))}</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl"> <span class="p"></</span><span class="nt">ul</span><span class="p">></span>
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="p">)</span>
</span></span></code></pre><p>By not destructuring <code>todos</code> we can use <code>useFetcher</code> as many times as we want, on multiple URLs. If you are only going to fetch once this might look cleaner:</p>
<pre class="chroma"><code><span class="line"><span class="ln">1</span><span class="cl"><span class="kr">const</span> <span class="p">{</span> <span class="nx">isLoading</span><span class="p">,</span> <span class="nx">error</span><span class="p">,</span> <span class="nx">data</span> <span class="p">}</span> <span class="o">=</span> <span class="nx">useFetcher</span><span class="p"><</span><span class="nt">Todo</span><span class="err">[]</span><span class="p">>(</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"> <span class="s1">'https://jsonplaceholder.typicode.com/todos'</span><span class="p">,</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="cm">/* ... */</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="nx">isLoading</span><span class="p">)</span> <span class="k">return</span> <span class="p"><</span><span class="nt">div</span><span class="p">></span><span class="nx">Loading</span><span class="p">...</</span><span class="nt">div</span><span class="p">></span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="k">return</span> <span class="p"><</span><span class="nt">div</span><span class="p">></span><span class="nb">Error</span><span class="o">:</span> <span class="p">{</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="p">}</</span><span class="nt">div</span><span class="p">></span>
</span></span></code></pre><hr>
<p><a href="/" rel="nofollow">Home</a></p>
A request state wrapper around fetch
Links
2022-12-12T10:05:54Z
https://bjornericabr.prose.sh/links
<h1 id="good-reads"><a class="anchor" href="#good-reads" rel="nofollow">#</a> Good reads</h1>
<ul>
<li><a href="https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction" rel="nofollow">The Wrong Abstraction</a></li>
<li><a href="https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/" rel="nofollow">The Law of Leaky Abstractions</a></li>
<li><a href="https://agilemanifesto.org/principles.html" rel="nofollow">Twelve Principles of Agile Software</a></li>
</ul>
<h1 id="good-watches"><a class="anchor" href="#good-watches" rel="nofollow">#</a> Good watches</h1>
<ul>
<li><a href="https://www.youtube.com/watch?v=SxdOUGdseq4" rel="nofollow">Simple Made Easy</a></li>
<li><a href="https://www.youtube.com/watch?v=n7wH2XdOWpM" rel="nofollow">Stop Starting, Start Finishing</a></li>
<li><a href="https://youtu.be/9K20e7jlQPA" rel="nofollow">You're Doing Agile Wrong (Agile isn't scrum)</a></li>
</ul>
<hr>
<p><a href="/" rel="nofollow">Home</a></p>
Good reads and watches.
Making a Makefile for web development
2022-12-17T09:11:39Z
https://bjornericabr.prose.sh/making-a-makefile
<p>I find Makefiles to be a great form of documentation, and adding help for the targets makes them even greater.</p>
<blockquote>
<p><em>TLDR;</em> Provide help messages for Make targets using <code>target_name: ## This is the help message</code>. Then just run <code>make</code> to get a good overview of the project.</p>
</blockquote>
<pre class="chroma"><code><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c"># V A R I A B L E S #
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c"></span><span class="nv">COLOR_RESET</span> <span class="o">=</span> <span class="se">\0</span>33<span class="o">[</span>0m
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nv">COLOR_INFO</span> <span class="o">=</span> <span class="se">\0</span>33<span class="o">[</span>32m
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="nv">COLOR_COMMENT</span> <span class="o">=</span> <span class="se">\0</span>33<span class="o">[</span>33m
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c"># T A R G E T S #
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c"></span><span class="nf">default</span><span class="o">:</span> <span class="n">help</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="nf">help</span><span class="o">:</span> <span class="c">## Display this help message
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c"></span> @printf <span class="s2">"</span><span class="si">${</span><span class="nv">COLOR_COMMENT</span><span class="si">}</span><span class="s2">Usage:</span><span class="si">${</span><span class="nv">COLOR_RESET</span><span class="si">}</span><span class="s2">\n"</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"> @printf <span class="s2">" make [target]\n\n"</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"> @printf <span class="s2">"</span><span class="si">${</span><span class="nv">COLOR_COMMENT</span><span class="si">}</span><span class="s2">Available targets:</span><span class="si">${</span><span class="nv">COLOR_RESET</span><span class="si">}</span><span class="s2">\n"</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"> @grep -E <span class="s1">'^[a-zA-Z_-]+:.*?## .*$$'</span> <span class="k">$(</span>MAKEFILE_LIST<span class="k">)</span> <span class="p">|</span> awk <span class="s1">'BEGIN {FS = ":.*?## "}; { \
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="s1"> printf " ${COLOR_INFO}%-30s${COLOR_RESET} %s\n", $$1, $$2 \
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="s1"> }'</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="c">####
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c"></span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="nf">up</span><span class="o">:</span> <span class="c">## Start Docker development environment
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="c"></span> docker compose up -d
</span></span><span class="line"><span class="ln">21</span><span class="cl"> open http://localhost:8000
</span></span><span class="line"><span class="ln">22</span><span class="cl">
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="nf">down</span><span class="o">:</span> <span class="c">## Docker development environment
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="c"></span> docker compose down
</span></span><span class="line"><span class="ln">25</span><span class="cl">
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="nf">clean</span><span class="o">:</span> <span class="c">## Clean /dist, /preview and Docker container
</span></span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="c"></span> rm -r ./preview ./dist <span class="o">||</span> <span class="nb">true</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl"> docker compose rm -sf
</span></span><span class="line"><span class="ln">29</span><span class="cl">
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="nf">build</span><span class="o">:</span> <span class="n">install</span> <span class="c">## Build Plugin
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="c"></span> yarn build
</span></span><span class="line"><span class="ln">32</span><span class="cl">
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="nf">dev</span><span class="o">:</span> <span class="c">## Hotreloaded preview of standalone Svelte app
</span></span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="c"></span> yarn dev
</span></span><span class="line"><span class="ln">35</span><span class="cl">
</span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="nf">install</span><span class="o">:</span> <span class="c">## Install dependencies
</span></span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="c"></span> yarn install
</span></span><span class="line"><span class="ln">38</span><span class="cl">
</span></span><span class="line"><span class="ln">39</span><span class="cl"><span class="nf">version</span><span class="o">:</span> <span class="c">## Display package version
</span></span></span><span class="line"><span class="ln">40</span><span class="cl"><span class="c"></span> @cat package.json <span class="p">|</span> jq .version
</span></span></code></pre><p>This example file comes from a Svelte project that get containerized on Gitlab. We can either run it with Yarn on Docker. The important stuff here is lines 13-15 - setting up the color variables and the <code>help</code> target.</p>
<h2 id="explanations"><a class="anchor" href="#explanations" rel="nofollow">#</a> Explanations</h2>
<h3 id="the-help-target"><a class="anchor" href="#the-help-target" rel="nofollow">#</a> The <code>help</code> target</h3>
<p>The somewhat unreadable lines 13-15 does in simpler terms does this:</p>
<ul>
<li>greps for all lines beginning with a word followed by a ":" in <a href="https://ftp.gnu.org/old-gnu/Manuals/make-3.80/html_node/make_17.html" rel="nofollow">MAKEFILE_LIST</a> eg. all targets in current file</li>
<li>pipes the obove to <code>awk</code> that in turn
<ul>
<li>sets the field separator to <code>: ##</code></li>
<li>pretty prints target name and help line</li>
</ul>
</li>
</ul>
<p>We can now annotate our targets with a <code>##</code> to provide a help message for that target!</p>
<p>This is used quite a lot <a href="https://github.com/search?q=%5E%5Ba-zA-Z_-%5D%2B%3A.%2A%3F%23%23+.%2A%24%24%27+%24%28MAKEFILE_LIST%29&type=code" rel="nofollow">in the wild</a>.</p>
<h3 id="some-notes-on-the-makefile-syntax"><a class="anchor" href="#some-notes-on-the-makefile-syntax" rel="nofollow">#</a> Some notes on the Makefile syntax</h3>
<p>Prefixing a command with <code>@</code> will run, but now print the command. Targets can depend on other targets by listing them after the <code>:</code> (and before the <code>##</code> in our case).</p>
<p>Make can "chain" multiple targets after one another so running <code>make clean up</code> will run the targets <code>run</code> and <code>up</code> consecutively.</p>
<hr>
<p><a href="/" rel="nofollow">Home</a></p>