<?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: Aurélien Delogu</title>
    <description>The latest articles on DEV Community by Aurélien Delogu (@pyrsmk).</description>
    <link>https://dev.to/pyrsmk</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%2F421989%2Fdbc533a4-62a0-4b2a-b09a-bef4091a9f7f.jpg</url>
      <title>DEV Community: Aurélien Delogu</title>
      <link>https://dev.to/pyrsmk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pyrsmk"/>
    <language>en</language>
    <item>
      <title>I benchmarked several queue algorithms</title>
      <dc:creator>Aurélien Delogu</dc:creator>
      <pubDate>Mon, 25 Jul 2022 14:15:00 +0000</pubDate>
      <link>https://dev.to/pyrsmk/i-benchmarked-several-queue-algorithms-4hp6</link>
      <guid>https://dev.to/pyrsmk/i-benchmarked-several-queue-algorithms-4hp6</guid>
      <description>&lt;p&gt;A few weeks ago I posted a &lt;a href="https://dev.to/pyrsmk/code-snippet-a-performant-async-queue-kdb"&gt;code snippet&lt;/a&gt; about an async queue. I wrongly implied that this queue was &lt;em&gt;performant&lt;/em&gt; but this was not the case (I mostly said it was performant according to other solutions I analyzed at the time) as stated by &lt;a class="mentioned-user" href="https://dev.to/peerreynders"&gt;@peerreynders&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;He came with an algorithm based on swapping arrays so the queue would stay performant without having an O(n) time complexity. I found some other algorithms here and there and I wondered wich solution would be the best one, so I benchmarked them.&lt;/p&gt;

&lt;p&gt;To simplify the benchmarking, I dropped all the &lt;code&gt;async&lt;/code&gt; handling layer, to focus only on the queue itself.&lt;/p&gt;




&lt;p&gt;I tested 4 different algorithms. The related code is available on &lt;a href="https://github.com/pyrsmk/queue-benchmarks" rel="noopener noreferrer"&gt;Github&lt;/a&gt; if you want to see the different implementations and the benchmark:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;first algo: &lt;code&gt;Array.shift()&lt;/code&gt; calls (that's what I used); when dequeuing, we simply call &lt;code&gt;shift()&lt;/code&gt; on the item list&lt;/li&gt;
&lt;li&gt;second algo: swapping arrays (&lt;a class="mentioned-user" href="https://dev.to/peerreynders"&gt;@peerreynders&lt;/a&gt;'s solution); it uses two arrays, one for enqueuing items, and one for dequeuing them; when the dequeuing array is empty, the arrays are quickly resized and swapped&lt;/li&gt;
&lt;li&gt;third algo: ring array; this code is using two indexes with one array to keep track of its start and end offsets; when dequeuing a &lt;code&gt;delete&lt;/code&gt; operation is called on the current index&lt;/li&gt;
&lt;li&gt;fourth algo: half size clean up; when reaching the half size of the queue on dequeuing operation, the array is sliced up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you know other algorithms, please tell me and I'll add it to the benchmarks.&lt;/p&gt;




&lt;p&gt;Here's the results:&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%2F4nrla8v2idlh6bvr568l.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%2F4nrla8v2idlh6bvr568l.png" alt="Queue algorithms benchmark results"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When enqueuing/dequeuing 1 item:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  queue1.ts is the fastest
   2.89x faster than queue4.ts
   4.73x faster than queue2.ts
   11.67x faster than queue3.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For 1000 items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  queue2.ts is the fastest
   1.17x faster than queue4.ts
   7.18x faster than queue1.ts
   10.21x faster than queue3.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For 10 000 items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  queue2.ts is the fastest
   1.2x faster than queue4.ts
   8.63x faster than queue1.ts
   12.81x faster than queue3.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For 100 000 items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  queue2.ts is the fastest
   1.19x faster than queue4.ts: enqueue/dequeue 100_000 items
   8.26x faster than queue3.ts: enqueue/dequeue 100_000 items
   5523.86x faster than queue1.ts: enqueue/dequeue 100_000 items
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;The first algorithm is performing better when there's only some elements in the queue. But the performance drastically decreases when reaching a few hundreds of them, and it becomes really critical when reaching thousands of items where enqueuing/dequeuing only one element on a queue of 100 000 items takes &lt;code&gt;4.5s&lt;/code&gt;...&lt;/p&gt;

&lt;p&gt;The second algorithm is clearly the winner. But we could optimize things when there's only a few elements in the queue.&lt;/p&gt;

&lt;p&gt;The third algorithm is the slower implementation, after the first one. This is because of the &lt;code&gt;delete&lt;/code&gt; operation executed at each &lt;code&gt;dequeue()&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;The fourth algorithm is performing well, but can be optimized. Currently, it updates the internal array when reaching the half size of it. It can lead to some performance issues when enqueuing/dequeuing items completely and constantly. To improve that, we could compute dynamically an ideal items count so we slice the array up more often.&lt;/p&gt;




&lt;p&gt;To conclude: I need to update my &lt;a href="https://dev.to/pyrsmk/code-snippet-a-performant-async-queue-kdb"&gt;code snippet&lt;/a&gt; 😀&lt;/p&gt;

&lt;p&gt;Last note: &lt;code&gt;Array.shift()&lt;/code&gt; is getting optimized on &lt;a href="https://lannonbr.com/blog/2020-01-27-shift-optimizations/" rel="noopener noreferrer"&gt;some&lt;/a&gt; &lt;a href="https://bugs.chromium.org/p/v8/issues/detail?id=12730" rel="noopener noreferrer"&gt;platforms&lt;/a&gt;, but we shouldn't rely on this to implement algorithms, IMHO.&lt;/p&gt;




&lt;p&gt;Credits: Photo by &lt;a href="https://unsplash.com/@adriendlf?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Adrien Delforge&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/queue?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>deno</category>
    </item>
    <item>
      <title>What music genre do you listen to when coding?</title>
      <dc:creator>Aurélien Delogu</dc:creator>
      <pubDate>Thu, 14 Jul 2022 05:28:42 +0000</pubDate>
      <link>https://dev.to/pyrsmk/what-music-genre-do-you-listen-to-when-coding-5a4m</link>
      <guid>https://dev.to/pyrsmk/what-music-genre-do-you-listen-to-when-coding-5a4m</guid>
      <description>&lt;p&gt;And share with us your favorite track!&lt;/p&gt;




&lt;p&gt;For me, I listen to vocals-less music because otherwise it catches my attention to much and keep from think well about my code. My prefered genres so far, depending on the mood: ambient, psybient, psytrance, progressive house, as well as classical music and movie soundtracks.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>music</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>How to use the contenteditable attribute in Vue 3</title>
      <dc:creator>Aurélien Delogu</dc:creator>
      <pubDate>Mon, 11 Jul 2022 14:55:57 +0000</pubDate>
      <link>https://dev.to/pyrsmk/how-to-use-the-contenteditable-attribute-in-vue-3-a89</link>
      <guid>https://dev.to/pyrsmk/how-to-use-the-contenteditable-attribute-in-vue-3-a89</guid>
      <description>&lt;p&gt;Since I'm unemployed, I'm working on a side project in Vue 3 / TypeScript, so I keep myself up-to-date in frontend development.&lt;/p&gt;

&lt;p&gt;Lastly, even if I've 15 years of full-stack experience, I encountered the &lt;code&gt;contenteditable&lt;/code&gt; HTML attribute that I didn't know anything about (man there's so much to know in HTML/CSS today).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For those who don't know about it neither, it's an attribute that makes the target tag editable by a simple click: everything is handled natively by the browser itself!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In my application, I had a title that I needed to make editable and I implemented the behaviour by replacing the title by an input when it was clicked. Then I put a &lt;code&gt;v-model&lt;/code&gt; attribute on it, and hid the input when the enter button is pressed (and then displayed the title again in place). I already thought when I coded this that it was a bit cumbersome... So I was really intrigued when I met this &lt;code&gt;contenteditable&lt;/code&gt; UFO (well, it's not flying per say, but you understood).&lt;/p&gt;

&lt;p&gt;I managed to quickly update my code and tested how the thingy worked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;setup&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&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;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My title&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;titleElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Event&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLInputElement&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;titleElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;defineExpose&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;titleElement&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"titleElement"&lt;/span&gt; &lt;span class="na"&gt;contenteditable&lt;/span&gt; &lt;span class="na"&gt;spellcheck=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;keydown.enter=&lt;/span&gt;&lt;span class="s"&gt;"validate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well... It seems that is all we need 😅🦄&lt;/p&gt;

&lt;p&gt;It's clearly better now without the complexity of dealing the edition by ourselves!&lt;/p&gt;

&lt;p&gt;Here's the &lt;a href="https://sfc.vuejs.org/#eNpdkk1P8zAMx7+KlctaaaT3qkPPc5gEEtw49pK17hZI0yhxNlDV747TFAQc0ibxL37527P475y8RhS1aELntSMISNGBUfZ8aAWFVty3FkCPbvIEM3gc9nBT1F1ggcFPI+z4/a61ieomGwhIk0E4JLTYPX/k8678AxwNjmhp42w0honEDNF2pCcLV2V0rwgLvCawhmP6lzAnCiBfS1L+jAQqwMPL89OjdZE216U8meiLNTDkoJJ9xpTbzxTypdTWon/Bd3bp9ZifLemTVo+Dtnh8d1PAYv5dwbKiaa26FKtxD0UJh3tQBj3lqxynZLqpstgsLR8IR2e4zlXoptfXpEgS/0eQViTtiHfYa1InFjg4NKa7YPfG7KBMQIb+veFHP92sTKRnw5eIWx8B5i17WNbimooDsqmpvtMQe5HbfTcqJ1/DZHk8VtHbzcBTUX+1gUNE9l7z5kLkQl1VYejSUL0GOflzxTvpoyU9osQw3p38dAvo2XErNo0XsXwC0APhCA=="&gt;playable snippet&lt;/a&gt; if you want to have fun with it!&lt;/p&gt;

&lt;p&gt;If you have any questions, don't hesitate to ask them in the comment section 😉&lt;/p&gt;




&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@thoughtcatalog?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Thought Catalog&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/pencil-man?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>vue</category>
      <category>html</category>
    </item>
    <item>
      <title>Code snippet: a simple rate limiter</title>
      <dc:creator>Aurélien Delogu</dc:creator>
      <pubDate>Fri, 08 Jul 2022 09:44:53 +0000</pubDate>
      <link>https://dev.to/pyrsmk/code-snippet-a-simple-rate-limiter-3gfk</link>
      <guid>https://dev.to/pyrsmk/code-snippet-a-simple-rate-limiter-3gfk</guid>
      <description>&lt;p&gt;This code snippet is different from my previous one: &lt;a href="https://dev.to/pyrsmk/code-snippet-a-performant-async-queue-kdb"&gt;A performant async queue&lt;/a&gt;. Even if it works quite the same way.&lt;/p&gt;

&lt;p&gt;The big difference is that it runs functions after some wait time, instead of waiting some time &lt;strong&gt;after&lt;/strong&gt; functions have finished to run.&lt;/p&gt;

&lt;p&gt;There's also an NPM package: &lt;a href="https://github.com/pyrsmk/dumb-limiter"&gt;dumb-limiter&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Code snippet: How to test and understand DOM events better with this simple HTML snippet</title>
      <dc:creator>Aurélien Delogu</dc:creator>
      <pubDate>Fri, 08 Jul 2022 09:14:13 +0000</pubDate>
      <link>https://dev.to/pyrsmk/code-snippet-how-to-test-and-understand-dom-events-better-with-this-simple-html-snippet-3dd6</link>
      <guid>https://dev.to/pyrsmk/code-snippet-how-to-test-and-understand-dom-events-better-with-this-simple-html-snippet-3dd6</guid>
      <description>&lt;p&gt;Because sometimes we don't understand what's going on with DOM events (even more on mobiles), here's an HTML page to test and understand things.&lt;/p&gt;

&lt;p&gt;You just have to save it as an HTML file and load it in your browser (by drag-n-droping it for example). At the end of this file there's a list of events that are bypassed to avoid generating a lot of output. You can add/remove events from this list, based on what you want to test. And, of course, you can add/remove HTML tags (just after the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag): add a button, a select, anything you need so you can understand more deeply how DOM events are triggered when interacting with a web page 🦄&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>html</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Code snippet: A performant async queue</title>
      <dc:creator>Aurélien Delogu</dc:creator>
      <pubDate>Fri, 08 Jul 2022 08:51:25 +0000</pubDate>
      <link>https://dev.to/pyrsmk/code-snippet-a-performant-async-queue-kdb</link>
      <guid>https://dev.to/pyrsmk/code-snippet-a-performant-async-queue-kdb</guid>
      <description>&lt;p&gt;Here's a queue that handles async functions in order with a wait time between each callback. You can call it from anywhere, all tasks will stay in order and won't overlap each other. It can be used for rate limiting, for example.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;There's also an NPM package that has a more complete API: &lt;a href="https://github.com/pyrsmk/dumb-queue"&gt;dumb-queue&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Code snippet: How to browse a directory recursively</title>
      <dc:creator>Aurélien Delogu</dc:creator>
      <pubDate>Fri, 08 Jul 2022 08:37:08 +0000</pubDate>
      <link>https://dev.to/pyrsmk/code-snippet-how-to-browse-a-directory-recursively-2mh5</link>
      <guid>https://dev.to/pyrsmk/code-snippet-how-to-browse-a-directory-recursively-2mh5</guid>
      <description>&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Code Snippet: How to avoid calling a function twice until its task has finished</title>
      <dc:creator>Aurélien Delogu</dc:creator>
      <pubDate>Fri, 01 Jul 2022 14:20:25 +0000</pubDate>
      <link>https://dev.to/pyrsmk/share-friday-avoid-calling-a-callback-several-times-with-this-code-snippet-16g4</link>
      <guid>https://dev.to/pyrsmk/share-friday-avoid-calling-a-callback-several-times-with-this-code-snippet-16g4</guid>
      <description>&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Fresh is out, neat! But are there other "hybrid" frameworks out there?</title>
      <dc:creator>Aurélien Delogu</dc:creator>
      <pubDate>Thu, 30 Jun 2022 09:22:05 +0000</pubDate>
      <link>https://dev.to/pyrsmk/fresh-is-out-neat-but-are-there-other-hybrid-frameworks-out-there-558l</link>
      <guid>https://dev.to/pyrsmk/fresh-is-out-neat-but-are-there-other-hybrid-frameworks-out-there-558l</guid>
      <description>&lt;p&gt;&lt;a href="https://fresh.deno.dev/"&gt;Fresh&lt;/a&gt; just came out, and it really reminds me of &lt;a href="https://www.phoenixframework.org/"&gt;Phoenix&lt;/a&gt; which also handles backend development and also hydrates frontend with reactive components.&lt;/p&gt;

&lt;p&gt;Of course, there is SSR in React/Vue/Svelte, and we can also think of Meteor.js but it seems to me that this is not the same intention behind it as those "hybrid" frameworks.&lt;/p&gt;

&lt;p&gt;Anyway, do you know any other framework that does server side rendering and handles hydration/reactivity too?&lt;/p&gt;

&lt;p&gt;You can cite any framework in any language of course!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>discuss</category>
      <category>deno</category>
    </item>
    <item>
      <title>How to run a local webserver nowadays</title>
      <dc:creator>Aurélien Delogu</dc:creator>
      <pubDate>Tue, 25 Aug 2020 17:21:48 +0000</pubDate>
      <link>https://dev.to/pyrsmk/you-don-t-need-a-local-apache-nginx-server-anymore-to-test-your-website-3nh1</link>
      <guid>https://dev.to/pyrsmk/you-don-t-need-a-local-apache-nginx-server-anymore-to-test-your-website-3nh1</guid>
      <description>&lt;p&gt;In the early 2000s, &lt;strong&gt;when we wanted to develop our website we generally ended up installing Apache locally with PHP, MySQL, and PhpMyAdmin&lt;/strong&gt; (hey, I heard someone said &lt;em&gt;"eew!"&lt;/em&gt; in the assembly). This setup could take several hours to days, depending on what you wanted to achieve (mostly with Apache's config files).&lt;/p&gt;

&lt;p&gt;You could also install EasyPHP or WAMP to save you a lot of time, but these tools always came with counterparts, and nowadays a good app/website should be contained in its own project directory (e.g. git repository).&lt;/p&gt;

&lt;p&gt;In 2020 (OMG, am I that &lt;em&gt;old&lt;/em&gt;?!), &lt;strong&gt;development tools have improved a lot&lt;/strong&gt;. It is not needed anymore to install a local webserver with a complex configuration. Furthermore, to maximize the same behavior across machines, project's dependencies and resources should be run in isolation and not leak in the system.&lt;/p&gt;

&lt;p&gt;Let's see how to achieve it with some of the most trending languages!&lt;/p&gt;

&lt;h2&gt;
  
  
  The quickest not so dirty way
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;These different methods will rely on having a static website or internal routing in your application. Any more complex routing/rewriting will, of course, require a real webserver. The same to note if you need to use a database that you cannot mock. These specific needs are handled in the next section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Also, note that all the following commands are creating a server accessible at &lt;code&gt;http://localhost:8080/&lt;/code&gt; serving the current directory and that I didn't list all possible alternatives from popular frameworks (you should already know how to use them, right?) or any available package to keep this article as short as possible.&lt;/p&gt;




&lt;p&gt;I encourage the use of a Makefile (or any other tool like &lt;a href="https://css-tricks.com/why-npm-scripts/"&gt;NPM scripts&lt;/a&gt;) so you don't have to bother anymore with that "what is the command already?" perpetual question when switching between different projects. For example:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Then, you'll always have the same command to type across your projects: &lt;code&gt;make serve&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  For static websites
&lt;/h3&gt;

&lt;p&gt;You can use the &lt;a href="https://github.com/http-party/http-server"&gt;http-server&lt;/a&gt; NPM package. It's a very powerful web server with support for Gzip, SSL, or catch-all routing. Just install it in your project's dev dependencies and run it with &lt;code&gt;npx http-server&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are also several other web server libraries like &lt;a href="https://www.npmjs.com/package/glance"&gt;glance&lt;/a&gt; or &lt;a href="http://harpjs.com/"&gt;harp&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  For &lt;a href="https://deno.land/"&gt;Deno&lt;/a&gt; projects
&lt;/h3&gt;

&lt;p&gt;You can use the standard &lt;code&gt;file_server&lt;/code&gt; lib:&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="nv"&gt;$ &lt;/span&gt;deno &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-allow-net&lt;/span&gt; &lt;span class="nt"&gt;-allow-read&lt;/span&gt; file_server https://deno.land/std/http/file_server.ts
&lt;span class="nv"&gt;$ &lt;/span&gt;~/.deno/bin/file_server &lt;span class="nt"&gt;-port&lt;/span&gt; 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  For PHP 5.4+ apps
&lt;/h3&gt;

&lt;p&gt;You can use the PHP binary itself with: &lt;code&gt;php -S localhost:8080&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also: if you don’t have migrated to PHP 7 yet, please do.&lt;/p&gt;
&lt;h3&gt;
  
  
  For Ruby projects
&lt;/h3&gt;

&lt;p&gt;Starting with 1.9.2, use &lt;code&gt;ruby -run -e httpd . -p 8080&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With older versions, use &lt;code&gt;ruby -rwebrick -e'WEBrick::HTTPServer.new(:Port=&amp;gt;8080,:DocumentRoot=&amp;gt;Dir.pwd).start'&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  With Python
&lt;/h3&gt;

&lt;p&gt;Like PHP, Python has also its integrated server!&lt;/p&gt;

&lt;p&gt;With Python 2: &lt;code&gt;python -m SimpleHTTPServer 8080&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With Python 3: &lt;code&gt;python3 -m http.server 8080&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  With &lt;a href="https://golang.org/"&gt;Go&lt;/a&gt; language
&lt;/h3&gt;

&lt;p&gt;You can use spark:&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="nv"&gt;$ &lt;/span&gt;go get github.com/rif/spark
&lt;span class="nv"&gt;$ &lt;/span&gt;spark &lt;span class="nt"&gt;-port&lt;/span&gt; 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  In &lt;a href="https://crystal-lang.org/"&gt;Crystal&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;We can make use of a standard library:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crystal &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s1"&gt;'require "http/server"; HTTP::Server.new(8000, HTTP::StaticFileHandler.new(".")).listen'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  For &lt;a href="https://www.rust-lang.org/"&gt;Rust&lt;/a&gt; projects
&lt;/h3&gt;

&lt;p&gt;I did not forget our &lt;a href="https://www.rustaceans.org/"&gt;Rustaceans&lt;/a&gt; folks 😉️&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="nv"&gt;$ &lt;/span&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;https
&lt;span class="nv"&gt;$ &lt;/span&gt;http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can also use &lt;a href="https://github.com/svenstaro/miniserve"&gt;miniserve&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Finally, with &lt;a href="https://elixir-lang.org/"&gt;Elixir&lt;/a&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;elixir &lt;span class="nt"&gt;--no-halt&lt;/span&gt; &lt;span class="nt"&gt;--app&lt;/span&gt; inets &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;":inets.start(:httpd,[{:server_name,'s'},{:document_root,'.'},{:server_root,'.'},{:port,8080}])"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  The longest and reliable way
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JfwWAfH_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uk9jl4f6imoay2cxj6kv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JfwWAfH_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/uk9jl4f6imoay2cxj6kv.png" alt="" width="880" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe you already know Docker? It's a container management tool vastly used nowadays to ship apps with their underlying stack (like a database, a server, a log manager, etc…).&lt;/p&gt;

&lt;p&gt;To test an application locally, &lt;strong&gt;creating a Docker image with the same configuration as your production server is clearly the preferred and cleaner way&lt;/strong&gt;. Having your resources containerized minimizes the side effects of different environments with your project and makes your team happy.&lt;/p&gt;

&lt;p&gt;For our example, I won't enter into all the details of the creation of an image, but I created a Github repository with a sample website to show you how it is done. This example covers a docker image with Nginx and PHP7: &lt;a href="https://github.com/pyrsmk/docker-nginx-example"&gt;https://github.com/pyrsmk/docker-nginx-example&lt;/a&gt;. But the same principle is easily customizable to Apache and any other language.&lt;/p&gt;



&lt;p&gt;For the following, you'll need to &lt;a href="https://docs.docker.com/get-docker/"&gt;install docker on your system&lt;/a&gt;. When it's done, you must add your user to the &lt;code&gt;docker&lt;/code&gt; group:&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;su - &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;USER&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now, create an account on &lt;a href="https://hub.docker.com/"&gt;DockerHub&lt;/a&gt;, and &lt;a href="https://docs.docker.com/engine/reference/commandline/login/"&gt;log in&lt;/a&gt; to it.&lt;/p&gt;

&lt;p&gt;Done? Now let's take a look at what our image looks like.&lt;/p&gt;



&lt;p&gt;Here's our &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;With the comments, it's pretty straightforward to understand what is going on, but there are several things to note here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we're using &lt;a href="https://alpinelinux.org/"&gt;Linux Alpine&lt;/a&gt; to build our image because it is small as hell (contrary to Ubuntu) so it builds and runs fast&lt;/li&gt;
&lt;li&gt;to better handle services in our image we installed &lt;a href="https://github.com/just-containers/s6-overlay"&gt;S6-Overlay&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;we added &lt;code&gt;bash&lt;/code&gt; as a dependency for debugging purpose&lt;/li&gt;
&lt;li&gt;we're overwriting configuration files directly because it's simpler than processing each file separately; those configuration files are stored in the &lt;code&gt;etc&lt;/code&gt; folder on our example repository&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The other interesting file is the &lt;code&gt;Makefile&lt;/code&gt; (the following example is the concatenation of both Makefiles from the example repository, for simplicity):&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The code for the &lt;code&gt;build&lt;/code&gt; task seems a bit complicated but it's because we want to automate all other tasks since it's better to &lt;a href="https://medium.com/@mccode/using-semantic-versioning-for-docker-image-tags-dfde8be06699"&gt;set a version number for each image we're building&lt;/a&gt;. It's not really needed and this code can be simplified, but why not begin with good practices?&lt;/p&gt;

&lt;p&gt;Let's explain a bit what the tasks are doing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;make build&lt;/code&gt;: it shows us the current Docker image version and asks us for the new version, then builds it&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;make publish&lt;/code&gt;: it publishes our image on DockerHub, especially useful when working on a team but also to make backups&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;make bash&lt;/code&gt;: really useful when we need to debug when we're working on our image (Dockerfile, configuration files, etc…), it runs bash inside the container&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;make serve&lt;/code&gt;: this is what we're interested in, it runs the image and exposes the inner server to &lt;code&gt;localhost:8080&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note that you shouldn't/won't be able to run the commands from the repository directly as they rely on my own account &lt;code&gt;pyrsmk&lt;/code&gt; 😉️&lt;/p&gt;




&lt;p&gt;We're done for today!&lt;/p&gt;

&lt;p&gt;If you have any questions, do not hesitate to ask as I know that Docker is not easy stuff to step in!&lt;/p&gt;

&lt;p&gt;If you're interested to learn more about Docker, &lt;a href="https://docs.docker.com/develop/"&gt;there are many useful official resources to read&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;You can subscribe to my &lt;a href="https://mailing.origami.st/"&gt;mailing list&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you appreciate my work, you may want to support me for the small price of a coffee ☕️ via &lt;a href="https://ko-fi.com/pyrsmk"&gt;Ko-fi&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>webdev</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
