<?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: Guillaume Martigny</title>
    <description>The latest articles on DEV Community by Guillaume Martigny (@gmartigny).</description>
    <link>https://dev.to/gmartigny</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%2F59396%2Fa3e2cd08-87bc-4a11-832f-993c5843a943.jpg</url>
      <title>DEV Community: Guillaume Martigny</title>
      <link>https://dev.to/gmartigny</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gmartigny"/>
    <language>en</language>
    <item>
      <title>TypeScript is wasting my time</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Fri, 22 Apr 2022 12:47:46 +0000</pubDate>
      <link>https://dev.to/gmartigny/typescript-is-wasting-my-time-130n</link>
      <guid>https://dev.to/gmartigny/typescript-is-wasting-my-time-130n</guid>
      <description>&lt;p&gt;⚠️ This is a bit of a rant as I've lost patience with TypeScript and I need to vent.&lt;/p&gt;

&lt;p&gt;While converting a medium sized Nuxt application (~15 pages, i18n, auth, REST API) to TypeScript, I compiled a list of pain points (no specific order). This is not the first time that TS made me miserable while trying to use it. Maybe this is a "me" problem and I lack knowledge or skills. But, if this is the case, I bet that a lot of new developers also hit these roadblocks and didn't say anything because of the hype surrounding TS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is it &lt;code&gt;null&lt;/code&gt; tho ?
&lt;/h2&gt;

&lt;p&gt;Consider this simple "cache initialization" code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;key&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;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cache/init&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="nx"&gt;key&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="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?target=5&amp;amp;jsx=0#code/PIIwVgpgxgLgdAawgTwM4AoA2B7KBDTAZRmwCc8BzCASjgDMyBRPKAC3XSWWoAIBeAHw8A3gCgePVCVIQ4UbAFsFASxjoA5PjYQA9MoB2q9QBoR4iTy7HzEgG4EArhABcPAFKFgAOTgAHPKSoEFi4BMRklLJUMACSMBAKnCjU1NYSAL7UANyimVlAA"&gt;Playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It iterate over all items in &lt;code&gt;localStorage&lt;/code&gt; and send the parsed value to the store.&lt;br&gt;
Here, I get an error under &lt;code&gt;localStorage.getItem(key)&lt;/code&gt; because &lt;code&gt;JSON.parse&lt;/code&gt; accept &lt;code&gt;string&lt;/code&gt; as its first argument and &lt;code&gt;localStorage.getItem&lt;/code&gt; can return &lt;code&gt;null&lt;/code&gt;. Ok ... but ... whatever dude ! &lt;code&gt;JSON.parse(null)&lt;/code&gt; doesn't even produce an error. Even worse, I can't have unset values because I'm looping over existing items in the &lt;code&gt;localStorage&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;"compact"&lt;/code&gt; is not &lt;code&gt;"compact"&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Consider this number formater code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;formatNumber&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="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;notation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;compact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;maximumFractionDigits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NumberFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&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;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;format&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://www.typescriptlang.org/play?target=7#code/GYVwdgxgLglg9mABMOAnAtgQygOROgIwFNUAKAN0wBsQiAuRMfY1AGkSszAHMGBnKKhg9EAXkQByImAkBKRAG8AUIkQQEAxHAAOsDWMUrVjOFGzwwDCevTbM0CayOqsADxjp8AMVT29YABEYbhgoPgYARidVAF8AbiN1ME0UDGwoEgMASTAoKgA6PEISLzQsKFJOHnYdfz5ZBNVUIigQVCRU8ozUfM7sCmpaBqUYpSA"&gt;Playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;options&lt;/code&gt; parameter is underlined with an error because the field &lt;code&gt;notation&lt;/code&gt; is a string when it should be &lt;code&gt;"compact" | "standard" | "scientific" | "engineering" | undefined&lt;/code&gt;. Well ... it's hardcoded to &lt;code&gt;"compact"&lt;/code&gt;, which is pretty close to &lt;code&gt;"compact"&lt;/code&gt; to me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Type &lt;code&gt;IDontCare&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Consider this plugin declaration in Nuxt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Function&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;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myPlugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="cm"&gt;/* Plugin code */&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;&lt;a href="https://www.typescriptlang.org/play?target=7#code/KYDwDg9gTgLgBAE2AMwIYFcA28AUB9AGjgEsA7AK2AGMYAuOAMXVJuIlIEo4BeAPjgDeAKDgkK1GDgDkAWwCeABUzoA5mSlEA9ACo4S1WThUISONs0cA3EIC+1oA"&gt;Playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Nuxt, plugins are called with 2 parameters. The first is the Nuxt context, the second is a function that add the plugin to said context.&lt;br&gt;
Here, I don't use the context, so set it to &lt;code&gt;_&lt;/code&gt; (as per the recommendations). But I get an error because it has an implicit type &lt;code&gt;any&lt;/code&gt;. I mean ... right, but who cares ? I'm not using this parameter. I have specifically renamed it to inform that I don't use it. Why does it reports as an error ?&lt;/p&gt;
&lt;h2&gt;
  
  
  Code duplication !
&lt;/h2&gt;

&lt;p&gt;This one is pretty nasty to me. Again, consider a plugin declaration in Nuxt. This plugin expose a set of function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DontCare&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* Code code code */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* Code code code */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myPlugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;API&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;Everything's good until there. Now, I want to use it in my code. I have to declare the injected function in every possible place.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;
    &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue/types/vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// this.$myPlugin inside Vue components&lt;/span&gt;
  &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;$myPlugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nuxt/types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// nuxtContext.app.$myPlugin inside asyncData, fetch, plugins, middleware, nuxtServerInit&lt;/span&gt;
  &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NuxtAppOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;$myPlugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// nuxtContext.$myPlugin&lt;/span&gt;
  &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Context&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;$myPlugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vuex/types/index&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// this.$myPlugin inside Vuex stores&lt;/span&gt;
  &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Store&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;$myPlugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DontCare&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;API&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* Code code code */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&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="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* Code code code */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myPlugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;API&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;The worst part is not even that &lt;strong&gt;I&lt;/strong&gt; have to &lt;a href="https://typescript.nuxtjs.org/cookbook/plugins#plugin-2"&gt;tell TS that Nuxt is injecting my plugin everywhere&lt;/a&gt;. The worst part is that I have to make sure that every function signature in the plugin match with the interface. Why can't I infer types from the API itself ? Also, &lt;code&gt;ctrl + click&lt;/code&gt; become useless as it points to the interface and not the implementation (maybe an IDE issue, but still ...).&lt;/p&gt;

&lt;p&gt;The cherry on top is that now, ESlint is pouting because function params in the interface are considered unused.&lt;/p&gt;

&lt;h2&gt;
  
  
  Import without the extension
&lt;/h2&gt;

&lt;p&gt;TS need the file extension to detect the file type and compile accordingly. Fair enough, but now I have to go through all my import and add &lt;code&gt;.vue&lt;/code&gt; everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic interface
&lt;/h2&gt;

&lt;p&gt;I have an URL builder that I can chain call to append to a string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api&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;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4321&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="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;articles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entity&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;builder&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&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;url&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;entity&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Usage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&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;API&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4321&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;articles&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 'api/users/4321/articles'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is fine and dandy until TS coming shrieking. I can declare a type listing my entities and use this type as key in a &lt;code&gt;Record&lt;/code&gt; (see Code duplication !). But I also need to describe the &lt;code&gt;toString&lt;/code&gt; and &lt;code&gt;currentUser&lt;/code&gt; methods aside.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Entities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;articles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;URLBuilder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;URLBuilder&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;URLBuilder&lt;/span&gt;
  &lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api&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="na"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;URLBuilder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;currentUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4321&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="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Entities&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;articles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;entity&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;builder&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;url&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;entity&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;builder&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;&lt;a href="https://www.typescriptlang.org/play?pretty=true#code/C4TwDgpgBAogdsAlkiBnKBeKByArqiAJ1WygB8cBDQpAYwBs1sBuAKFEigFUAlAGQBCuRPQAmRTFADerKHKi1chQhARcChABQBKAFzd+QkeMKz5wAPYBlYIURwA5jv2pb9h6wC+UAGTSzcgDaANYQIFD2sAjIiGgAuvqaiKIA-C5ujtqYAHwGgsJiRF6sAPQAVFBWlAC20JSo7ODQvPnGElgy8gpKKmoaznlGhaZdljZ2jgOuEx7efjwQtBaEogA88EgoqAA0UEmp6TNZGLktQybZrGUlrKxLcK5QAIIACgCSkjo5-l2MwFBKeiSbCUMCIFgBBQWB7-ABGBRM+jOCPaPy68kUylUwHURC+nXRhJUwCUcCgwAAFohUAA6fBEVCabAAFgAzAAmACM2G0bEJck820ho2sGScWQJ-PkxNJAMI9D5-M8kM8bEh90e2JiaH0G21qECcUkgTwGhIuxBNEQDCYcUVci1WxpADNljBKLQKZpNI6QMdcpL0fC2oRAr6jVhnbg4LQkNC9sk0lBpu4JcL+YCoABqLAAAxKABIpL7PEXklAUlB82XRJ5c1B9NhsHX7VKoDLCGTKdTW11lX3ebcuh2ycHhmxVbcNRZGDT6BYnLmi683joaZjejj+toadQ6IxGdo64OgA"&gt;Playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Problem solved ? Not quite ... The temporary builder initialized while building the whole thing is not yet of type &lt;code&gt;URLBuilder&lt;/code&gt;. I have no idea how to say "This &lt;strong&gt;will&lt;/strong&gt; be of type T in a few lines".&lt;/p&gt;

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

&lt;p&gt;I'm absolutely sure that all those issues are due to some lack of knowledge. If you have an elegant solution for any of those, please share in the comments.&lt;/p&gt;

&lt;p&gt;Microsoft is not investing so much energy in something that's wasting time. I would love to come back to this article in a few years and finding all of this ridiculous, but for now, I really don't get the hype around Typescript.&lt;/p&gt;

&lt;p&gt;Thanks for indulging me 😎&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>opinion</category>
      <category>discuss</category>
      <category>letmelivemylife</category>
    </item>
    <item>
      <title>How I write web apps in 2021 ?</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Wed, 10 Feb 2021 11:21:46 +0000</pubDate>
      <link>https://dev.to/gmartigny/how-i-write-web-apps-in-2021-3ji2</link>
      <guid>https://dev.to/gmartigny/how-i-write-web-apps-in-2021-3ji2</guid>
      <description>&lt;h1&gt;
  
  
  Content
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
Introduction

&lt;ul&gt;
&lt;li&gt;Disclaimer&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Languages&lt;/li&gt;

&lt;li&gt;

Installation

&lt;ul&gt;
&lt;li&gt;Vue&lt;/li&gt;
&lt;li&gt;Bundler&lt;/li&gt;
&lt;li&gt;Optionals&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Development

&lt;ul&gt;
&lt;li&gt;
Adding views and components

&lt;ul&gt;
&lt;li&gt;Views&lt;/li&gt;
&lt;li&gt;Components&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Dynamic page

&lt;ul&gt;
&lt;li&gt;Fetch from API&lt;/li&gt;
&lt;li&gt;User editing&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Component libraries&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;Deployment&lt;/li&gt;

&lt;li&gt;Troubleshooting&lt;/li&gt;

&lt;li&gt;FAQ&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In this article, I'm going to present you step by step what tools I use.&lt;br&gt;
You can follow along, but it's more important to understand "why I am doing this" rather than "what I am doing".&lt;br&gt;
A good advice is, try to do the same step alongside me in this tutorial. Then, try to change a few bigger and bigger things. Finally, at the end, you should be able to do everything again on your own.&lt;/p&gt;

&lt;p&gt;You can find all the produced code over at &lt;a href="https://github.com/GMartigny/tuto2021" rel="noopener noreferrer"&gt;the Github repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;First of all, and this is really important, all of this is my own bias opinion on development. We all have our unique way at looking at things.&lt;br&gt;
Web development is a huge and complex topic. This post is not meant to describe the easiest or quickest methods.&lt;br&gt;
However, this is the methods I grew up preferring (for reasons I'll get to), and the one I'm most capable of explaining in details.&lt;/p&gt;

&lt;p&gt;From here, I assume you have basic Javascript and Vue understanding. I'm also not going to detail how to &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;install Node.js&lt;/a&gt; and &lt;a href="https://docs.npmjs.com/" rel="noopener noreferrer"&gt;how to use NPM&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Languages
&lt;/h1&gt;

&lt;p&gt;With that out of the way, let's start with languages.&lt;br&gt;
I have worked with Javascript for about 10 years. It has a lot of detractors, but it was and still is the language I enjoy the most.&lt;br&gt;
It's easy to use, has one of the largest community and can power huge application.&lt;/p&gt;

&lt;p&gt;Of course, I'm also writing everything in English. Although it's not my mother tongue, it's recognize as the international language.&lt;/p&gt;
&lt;h1&gt;
  
  
  Installation
&lt;/h1&gt;

&lt;p&gt;Node.js is installed on my computed, so I'll use NPM to install all my JS dependencies.&lt;br&gt;
The first thing I always do when starting a new project is&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This will create the &lt;code&gt;package.json&lt;/code&gt; file.&lt;br&gt;
Then I manually create a &lt;code&gt;readme.md&lt;/code&gt; and &lt;code&gt;.gitignore&lt;/code&gt; file as well as a &lt;code&gt;src&lt;/code&gt; directory that will be useful later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flpstd2l5dxpp8n0crehk.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%2Fi%2Flpstd2l5dxpp8n0crehk.png" alt="Preview of my project file system"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Vue
&lt;/h2&gt;

&lt;p&gt;I like Vue and that's what I mostly use. The installation is straightforward&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install vue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Bundler
&lt;/h2&gt;

&lt;p&gt;I like the &lt;a href="https://vuejs.org/v2/guide/single-file-components.html" rel="noopener noreferrer"&gt;modular template syntaxe&lt;/a&gt; that Vue offer. However, this is not native JS that a browser can understand.&lt;br&gt;
So, it needs to be transformed before it can be used.&lt;/p&gt;

&lt;p&gt;I use Webpack for that. The installation is not as simple because we need a lot more modules.&lt;br&gt;
First, let's start with Webpack itself and its CLI interface&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install webpack webpack-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Then, I need to add the plugin that handle Vue files with its compiler&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install vue-loader vue-template-compiler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Finally, chances are that I'm going to write CSS, so I need another pair of plugins to handle CSS code&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install css-loader style-loader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Now, I need to configure Webpack. This is the least fun part, but we need to understand this step to solve possible future issues.&lt;br&gt;
Webpack can be configured with a file named &lt;code&gt;webpack.config.js&lt;/code&gt;, so let's create it.&lt;/p&gt;

&lt;p&gt;Here is the bare minimum. We'll come back later if we need to expand 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;// Get the vue-loader plugin&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;VueLoaderPlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue-loader/lib/plugin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// This is what the file exports&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="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// My entry point&lt;/span&gt;
    &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./src/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="c1"&gt;// All Vue files use the vue-loader&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;vue$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue-loader&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;// All CSS files use css than style loaders&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;css$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;use&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;style-loader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;css-loader&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="c1"&gt;// Register the vue-loader plugin&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;VueLoaderPlugin&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With all that out of the way, I just need to run in my terminal&lt;/p&gt;

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

&lt;/div&gt;

&lt;p&gt;to see my project being entirely compacted and minified. This will fail for now, don't worry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optionals
&lt;/h2&gt;

&lt;p&gt;These tools are out of scope for this article. Maybe I'll go in more details in the next one.&lt;/p&gt;

&lt;p&gt;I always use Eslint to check for potential mistakes in my code.&lt;br&gt;
In order to use it with my personal configuration I run&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install eslint eslint-plugin-vue @gmartigny/eslint-config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;I try to test my code to catch regression and be sure that I cover most use cases. I use AVA for the test and NYC for the code coverage.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install ava nyc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
  
  
  Development
&lt;/h1&gt;

&lt;p&gt;That's already a lot of steps, and I haven't even write a single line of code. All of that looks like a lot, but trust me, it will make you go faster in the future.&lt;/p&gt;

&lt;p&gt;The most attentives around you would remember that in my Webpack configuration, the entry file was &lt;code&gt;./src/index.js&lt;/code&gt;. So, let's start there.&lt;br&gt;
I create an &lt;code&gt;index.js&lt;/code&gt; file in &lt;code&gt;src&lt;/code&gt; and add a few lines of code to call Vue (&lt;a href="https://vuejs.org/v2/guide/installation.html#Explanation-of-Different-Builds" rel="noopener noreferrer"&gt;with ESM&lt;/a&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Import Vue, I prefer the ESM syntaxe&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&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;vue/dist/vue.esm.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Create a new Vue instance targeted at the element with the id "app"&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="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;With this bare-bones JS file, I can safely run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ webpack --mode=development --watch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;to trigger Webpack in development mode (slower but more descriptive on errors) with watch (will rebuild every time I change the code).&lt;br&gt;
This will create a new &lt;code&gt;main.js&lt;/code&gt; file within a &lt;code&gt;dist&lt;/code&gt; directory. It's the file that my final users will use.&lt;/p&gt;

&lt;p&gt;I now create a &lt;code&gt;index.html&lt;/code&gt; file (usually in a &lt;code&gt;public&lt;/code&gt; directory, but it doesn't matter).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Test&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- My target element --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- The JS file from webpack --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"../dist/main.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Opening this file in your browser will show nothing as expected, but this is all working. This is the state of my project so far.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F707iwd57o7c0mufrgsc8.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%2Fi%2F707iwd57o7c0mufrgsc8.png" alt="Preview of my project file system"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding views and components
&lt;/h2&gt;

&lt;p&gt;Your Vue files should be split between views (an individual screen, eg: Menu, About ...) and components (composing your views, eg: Button, Footer ...)&lt;br&gt;
Both works the same, but don't have the same concerns. So let's add two directories (&lt;code&gt;views&lt;/code&gt; and &lt;code&gt;components&lt;/code&gt;) in &lt;code&gt;src&lt;/code&gt; to sort them out.&lt;/p&gt;
&lt;h3&gt;
  
  
  Views
&lt;/h3&gt;

&lt;p&gt;Let's begin by creating a new view. This is going to be the homepage, so I'll call the file &lt;code&gt;Home.vue&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I used a capital letter in the file name to show that it's a class as in other OOP language like Java.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&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;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/h1&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;&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="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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to go into that view, I have to tell my Vue instance to render it. In the &lt;code&gt;index.js&lt;/code&gt; file, I'll add the necessary lines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&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;vue/dist/vue.esm.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Import the view&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Home&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;./views/Home.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// Declare it as a components I'll use (I know, views are treated as components by Vue)&lt;/span&gt;
    &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// Render the view&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;Home/&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to have more views, you need navigation between the views, so you need &lt;code&gt;vue-router&lt;/code&gt;. We're not going to talk about it for now.&lt;/p&gt;

&lt;h3&gt;
  
  
  Components
&lt;/h3&gt;

&lt;p&gt;Imagine I want to have a simple card (title + text) for each film I want to see, I don't want to duplicate the code for each cards. A good rule is DRY (Don't Repeat Yourself).&lt;br&gt;
If you write something more than twice, it should be factorized in one place.&lt;/p&gt;

&lt;p&gt;Again, I create a new file called &lt;code&gt;Film.vue&lt;/code&gt; in the &lt;code&gt;components&lt;/code&gt; directory.&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;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;class=&lt;/span&gt;&lt;span class="s"&gt;"film"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Title&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Text&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&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;&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="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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Film&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="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="c"&gt;&amp;lt;!-- scoped because I don't want to interfere with any other component --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.film&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&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;And use it in &lt;code&gt;Home.vue&lt;/code&gt;.&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;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- Use the component --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Film&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Film&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Film&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&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;&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="c1"&gt;// Import the component&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Film&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;../components/Film.vue&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Declare the component&lt;/span&gt;
        &lt;span class="nx"&gt;Film&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you should already see, I have 3 cards with the same title and text.&lt;br&gt;
Which is not what I want to do.&lt;br&gt;
If I add properties to my card component and write data in my home view, it will allow me to define value for each individual card.&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;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;class=&lt;/span&gt;&lt;span class="s"&gt;"film"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- Use properties here --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;h2&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;/h2&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&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;&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="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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Film&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// Properties list declaration&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&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="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;style&lt;/span&gt; &lt;span class="na"&gt;scoped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;.film&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;style&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- Loop through my data --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Film&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"(film, index) in films"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"index"&lt;/span&gt;
              &lt;span class="na"&gt;:title=&lt;/span&gt;&lt;span class="s"&gt;"film.title"&lt;/span&gt; &lt;span class="na"&gt;:text=&lt;/span&gt;&lt;span class="s"&gt;"film.text"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&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;&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Film&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;../components/Film.vue&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Film&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// data should be a function&lt;/span&gt;
    &lt;span class="nf"&gt;data &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// that return a set of values&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;films&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alien&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;It follows the crew of the commercial space tug Nostromo, who encounter the eponymous Alien, an aggressive and deadly extraterrestrial set loose on the ship.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="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="s2"&gt;Interstellar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;In a dystopian future where humanity is struggling to survive, it follows a group of astronauts who travel through a wormhole near Saturn in search of a new home for mankind.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="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="s2"&gt;Reservoir Dogs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Diamond thieves whose planned heist of a jewelry store goes terribly wrong.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&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;With that in place, any changes applied to my data will be reflected on screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic page
&lt;/h2&gt;

&lt;p&gt;I can, for example, fetch data from an API or allow the user to edit the page (or both 😉).&lt;/p&gt;

&lt;h3&gt;
  
  
  Fetch from API
&lt;/h3&gt;

&lt;p&gt;First, I'll fetch my data from a mock API online. In order to do that, I start by emptying the data array.&lt;br&gt;
Then, according to the &lt;a href="https://vuejs.org/v2/guide/instance.html#Lifecycle-Diagram" rel="noopener noreferrer"&gt;Vue lifecycle&lt;/a&gt;, I can use &lt;code&gt;mounted&lt;/code&gt; function to execute code when the view appears on screen.&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;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- ... --&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;&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Film&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;../components/Film.vue&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Film&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;data &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Emtpy film list&lt;/span&gt;
            &lt;span class="na"&gt;films&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;mounted &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Fetch from mock API&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://mock-film-api-t0jk5mabvwnt.runkit.sh/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Load result into films list&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;films&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  User editing
&lt;/h3&gt;

&lt;p&gt;In the same way, I can allow users to add new film to the list. A small HTML form that push a new entry when submitted will see the modifications reflected on the view.&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;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;v-app&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Film&lt;/span&gt; &lt;span class="na"&gt;v-for=&lt;/span&gt;&lt;span class="s"&gt;"(film, index) in films"&lt;/span&gt; &lt;span class="na"&gt;:key=&lt;/span&gt;&lt;span class="s"&gt;"index"&lt;/span&gt;
              &lt;span class="na"&gt;:title=&lt;/span&gt;&lt;span class="s"&gt;"film.title"&lt;/span&gt; &lt;span class="na"&gt;:text=&lt;/span&gt;&lt;span class="s"&gt;"film.text"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- Form that will call addFilm when submitted --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;submit=&lt;/span&gt;&lt;span class="s"&gt;"addFilm"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Title&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
                &lt;span class="c"&gt;&amp;lt;!-- v-model link the input value to a variable --&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"inputTitle"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Text&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"inputText"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Add&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/v-app&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;&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Film&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;../components/Film.vue&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Home&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Film&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;data &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;films&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
            &lt;span class="c1"&gt;// Holds the value of each input&lt;/span&gt;
            &lt;span class="na"&gt;inputTitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;inputText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;mounted &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// New method&lt;/span&gt;
        &lt;span class="nf"&gt;addFilm &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="c1"&gt;// Stop the form from reloading the page (default behavior)&lt;/span&gt;
            &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="c1"&gt;// Add a new film to the list&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;films&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputTitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;});&lt;/span&gt;
            &lt;span class="c1"&gt;// Clear out input fields&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will of course not save anything online, and changes made will be lost when the page is reloaded.&lt;br&gt;
You could improve this example by sending a request to a server that save the inputs in a database.&lt;/p&gt;
&lt;h2&gt;
  
  
  Component libraries
&lt;/h2&gt;

&lt;p&gt;I'm lazy. Being an efficient developer often means being lazy.&lt;br&gt;
Instead of creating all my components, I can use already existing libraries of components. That way, I can focus more on content instead of how to correctly design a datepicker.&lt;/p&gt;

&lt;p&gt;Since I use Vue, I choose a Vue compatible library, &lt;a href="https://vuetifyjs.com/en/getting-started/installation/#webpack-install" rel="noopener noreferrer"&gt;Vuetify&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install vuetify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Really few changes are needed to activate it in &lt;code&gt;index.js&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&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;vue/dist/vue.esm.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Get Vuetify and its CSS&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vuetify&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;vuetify&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vuetify/dist/vuetify.min.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Home&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;./views/Home.vue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Prepare the usage of vuetify&lt;/span&gt;
&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Vuetify&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;vuetify&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vuetify&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;// Pass the instance to Vue&lt;/span&gt;
    &lt;span class="nx"&gt;vuetify&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;el&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;Home/&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I can use it everywhere in my application (here in &lt;code&gt;Film.vue&lt;/code&gt;).&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;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- All Vuetify components are prefixed with "v-" --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;v-col&lt;/span&gt; &lt;span class="na"&gt;cols=&lt;/span&gt;&lt;span class="s"&gt;"12"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;v-card&lt;/span&gt; &lt;span class="na"&gt;shaped&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;v-card-title&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;/v-card-title&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;v-card-text&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="si"&gt;}}&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/v-card-text&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/v-card&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/v-col&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;&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="c1"&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="c"&gt;&amp;lt;!-- I don't need my crappy style anymore --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Deployment
&lt;/h1&gt;

&lt;p&gt;One of my favorite recent discovery is serverless. Basically, as long as your application is stateless (always return the same result with the same parameters), you don't need to have a complex, always running server. By leveraging the power of caching and ressource sharing you can reduce your server to almost nothing.&lt;/p&gt;

&lt;p&gt;Using &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;, I'm able to freely host, deploy and serve with a few clicks. All I need is for the project to be on &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Troubleshooting
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;You are using the runtime-only build of Vue where the template compiler is not available.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your import of Vue is wrong. If you remember, there are many ways to import Vue. By default, &lt;code&gt;import "vue"&lt;/code&gt; will call the &lt;code&gt;vue.runtime.common.js&lt;/code&gt; file.&lt;br&gt;
In my code here, I'm using the ESM with template (so I need the &lt;code&gt;vue.esm.js&lt;/code&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[Vuetify] Multiple instances of Vue detected / this.$vuetify is undefined&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your application and Vuetify didn't import the "same" Vue. As explain above, it's important to import the right Vue for your usage.&lt;br&gt;
A nice solution to this is to create an alias in webpack.&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;// In webpack.config.js&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="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// This will tell all your code to use the same Vue.&lt;/span&gt;
    &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;vue&lt;/span&gt;&lt;span class="na"&gt;$&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue/dist/vue.esm.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  FAQ
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Why do you don't use CLI to setup your app ? (like &lt;code&gt;vue-cli&lt;/code&gt; or &lt;code&gt;create-react-app&lt;/code&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While these CLI are great ways to quickstart a project, they slow you down in the long run. They all use the same technologies I presented you today, but in a complex and confusing way.&lt;br&gt;
Using &lt;code&gt;create-react-app&lt;/code&gt; install about 2000 packages. If something goes wrong, debugging that much code is not an easy task.&lt;br&gt;
I've always preferred taking the longer road, but at the end of the day, understand what's going on.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why don't you need to import each Vuetify components when you use them ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When I do &lt;code&gt;Vue.use(Vuetify);&lt;/code&gt; in the &lt;code&gt;index.js&lt;/code&gt;, it activates it in the whole project.&lt;br&gt;
It's possible to import only Vuetify components when you use them. But this requires a bit more work that is out of scope for this tutorial.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why don't you use &lt;strong&gt;X&lt;/strong&gt; instead of &lt;strong&gt;Y&lt;/strong&gt; ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I'm used to it. I'm sure you'll find better alternative to any tools or methods I describe above. But I know them.&lt;br&gt;
At the end of the day, it's more important to deliver than endlessly learn new technologies.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What are my alternatives ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Angular&lt;/li&gt;
&lt;li&gt;Svelte&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vuetify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Material-UI&lt;/li&gt;
&lt;li&gt;Any CSS frameworks:

&lt;ul&gt;
&lt;li&gt;Bootstrap&lt;/li&gt;
&lt;li&gt;Bulma&lt;/li&gt;
&lt;li&gt;Tailwind&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Webpack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rollup&lt;/li&gt;
&lt;li&gt;Skypack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vercel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Netlify&lt;/li&gt;
&lt;li&gt;Heroku&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
      <category>vue</category>
      <category>webpack</category>
    </item>
    <item>
      <title>Pencil.js quick-start</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Tue, 24 Mar 2020 13:24:45 +0000</pubDate>
      <link>https://dev.to/gmartigny/pencil-js-quick-start-omn</link>
      <guid>https://dev.to/gmartigny/pencil-js-quick-start-omn</guid>
      <description>&lt;p&gt;I recently spent some time putting together a new way to discover the &lt;a href="https://pencil.js.org/"&gt;Pencil.js library&lt;/a&gt;. In 9 steps, I show how to create this nice interactive scene form scratch.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/GMartigny/embed/dyoKGoP?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Go check it out on &lt;a href="https://pencil.js.org/quick-start/"&gt;the Pencil.js website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It was a fun exercise to find the most straightforwards way to present a handful of modules. I also tried to keep it short in order to not make it boring.&lt;/p&gt;

&lt;p&gt;I really hope you like it and this help new people discover all Pencil.js can offer. If you followed the tutorial to the end, I would love to hear what you think about it.&lt;/p&gt;

&lt;p&gt;Peace 😎&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>showdev</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Come code with me ...</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Mon, 05 Aug 2019 16:43:48 +0000</pubDate>
      <link>https://dev.to/gmartigny/come-code-with-me-5a5e</link>
      <guid>https://dev.to/gmartigny/come-code-with-me-5a5e</guid>
      <description>&lt;p&gt;From now on, I'll stream my working process &lt;a href="https://www.twitch.tv/gmartigny"&gt;over Twitch&lt;/a&gt; everyday.&lt;br&gt;
So come join me all days of the week from &lt;a href="https://www.worldtimebuddy.com/?qm=1&amp;amp;lid=2988507&amp;amp;h=2988507&amp;amp;date=2019-8-5&amp;amp;sln=12-18"&gt;12:00pm to 6:00pm CEST&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So why come joining me ?&lt;/p&gt;

&lt;p&gt;I'll be working on open-source projects using modern Javascript stack. I'll do my best to answer any question related to the stream, so come if you want to have a nice chat about new web technologies.&lt;br&gt;
Also, you can laugh at my weird French accent 🤓🇫🇷.&lt;/p&gt;

&lt;p&gt;I hope to see you there, and until next time, peace ✌️&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>livecoding</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Arbitrary large integer</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Fri, 02 Aug 2019 13:22:21 +0000</pubDate>
      <link>https://dev.to/gmartigny/arbitrary-large-integer-1j7h</link>
      <guid>https://dev.to/gmartigny/arbitrary-large-integer-1j7h</guid>
      <description>&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;At one point or another, while using JS, you should have encounter the limitation of number encoding. The most infamous example is:&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="mf"&gt;0.1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mf"&gt;0.3&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Javascript encode numbers using 64bits of memory (64 binary digits). Since we want to deal with floating numbers (non-finite set), modern languages have to rely on weird maths.&lt;br&gt;
I'm not going to explain it here, because I don't understand it fully myself. But you should know that storing infinite precision numbers over finite memory is not possible.&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 3.141592653589793 "only" 16 digits long.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As it can lack precision for small number, it's also true for large numbers. As soon as you go higher than &lt;code&gt;Number.MAX_SAFE_INTEGER&lt;/code&gt; or &lt;code&gt;2^53 - 1&lt;/code&gt;, you're subject to error.&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="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MAX_SAFE_INTEGER&lt;/span&gt;     &lt;span class="c1"&gt;// =&amp;gt; 9007199254740991&lt;/span&gt;
&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MAX_SAFE_INTEGER&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 9007199254740992 (1 + 2 = 2 ?)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can get even worse if your integer goes beyond &lt;code&gt;Number.MAX_VALUE&lt;/code&gt; or &lt;code&gt;2^1024 - 1&lt;/code&gt;, because JS will treat it as &lt;code&gt;Infinity&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MAX_VALUE&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 1.7976931348623157e+308&lt;/span&gt;
&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MAX_VALUE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; Infinity&lt;/span&gt;
&lt;span class="mf"&gt;1.8e308&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; Infinity&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Recently, Javascript has a new number representation: &lt;a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Objets_globaux/BigInt"&gt;BigInt&lt;/a&gt;. It's now supported by &lt;a href="https://caniuse.com/#feat=bigint"&gt;FireFox (v68), Chrome (v67) and Edge (v76)&lt;/a&gt;. This allow you to write number as large as your computer memory can handle.&lt;/p&gt;

&lt;p&gt;It's extremely easy to use, just add a &lt;code&gt;n&lt;/code&gt; character in the end of your numbers.&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="mi"&gt;99&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; Infinity&lt;/span&gt;
&lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 436073206168265161501341703386462012231079860756206...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you can't add the &lt;code&gt;n&lt;/code&gt;, like when you consume the result of a function, you can wrap it in a constructor.&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;BigInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getNumberViewers&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;BigInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getAverageWatchDuration&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a few thing to remember while using BigInts.&lt;/p&gt;

&lt;p&gt;First, BigInts are not compatible with regular numbers. So, you need to transform all operand to one or the other when doing maths.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bigInt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;bigInt&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; TypeError: Cannot mix BigInt and other types&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Secondly, BigInts are not compatible with &lt;code&gt;Math&lt;/code&gt;. Only basic maths operation are allowed.&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; TypeError: Cannot convert a BigInt value to a number&lt;/span&gt;
&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thirdly, while division are supported, they automatically round to the closest to 0 integer.&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="mi"&gt;19&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 1n&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; -1n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, you'll have to consider that BigInt are a bit more ressource consuming than native numbers. So you should be using them only when manipulating ever growing numbers, like timestamps, users actions ...&lt;/p&gt;




&lt;p&gt;I hope you enjoy this little article. Look for more articles from me on the right panel and consider following me on &lt;a href="https://github.com/GMartigny"&gt;Github&lt;/a&gt; or &lt;a href="https://twitter.com/GMartigny"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Until next time, peace ✌️&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Do you know any social network for personal projects ?</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Tue, 09 Jul 2019 18:59:26 +0000</pubDate>
      <link>https://dev.to/gmartigny/do-you-know-any-social-network-for-personal-projects-1n17</link>
      <guid>https://dev.to/gmartigny/do-you-know-any-social-network-for-personal-projects-1n17</guid>
      <description>&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;Many of us (not everyone) love to create side projects and more often than not these projects are never finished or never see a single user.&lt;/p&gt;

&lt;p&gt;That's a shame that so many hours and motivation are poured into the void. So I was looking for some kind of social network for digital makers. Whether it be art, code, sound, etc, you could share what you're working on and get unbiased feedback. At the same time it could allow to connect people with complementary skills willing to work together.&lt;/p&gt;

&lt;p&gt;There's so many social network out there, but I can't find any dedicated to ongoing projects and &lt;a href="https://www.reddit.com/r/AppIdeas/comments/8sc63n/a_social_network_for_side_projects/"&gt;I don't seems to be the only one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Do you know anything like it ?&lt;/p&gt;

</description>
      <category>help</category>
      <category>discuss</category>
    </item>
    <item>
      <title>V8.js - Access native v8 engine function from Javascript</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Fri, 17 May 2019 18:52:21 +0000</pubDate>
      <link>https://dev.to/gmartigny/v8-js-access-native-v8-engine-function-from-javascript-plc</link>
      <guid>https://dev.to/gmartigny/v8-js-access-native-v8-engine-function-from-javascript-plc</guid>
      <description>&lt;p&gt;When Google decide to create his own web browser, their engineers build a brand new Javascript engine. Build for speed and memory performance, its adoption into Node.js makes it the most influential engine out there.&lt;/p&gt;

&lt;p&gt;A few things was impossible to do in Javascript. Specifically discussing with the engine itself and make use of its native methods. Getting a precise measure of the heap memory size (&lt;a href="https://developer.mozilla.org/docs/Web/API/Performance#Properties"&gt;only possible on Chrome&lt;/a&gt;), triggering the garbage collector or getting the optimisation status of a function was inaccessible to Javascripts devs.&lt;/p&gt;

&lt;p&gt;Not anymore.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://github.com/GMartigny/v8.js"&gt;V8.js&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;Using the flag &lt;code&gt;--allow-natives-syntax&lt;/code&gt; on execution now allow you to call all V8's native methods. Since the syntaxe can still be a bit clanky, V8.js wrap it around a more classic library interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;Like any other library available on NPM, you can install V8.js with one command line:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install v8.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Or add a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag in your HTML page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/v8.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Or --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://cdn.jsdelivr.net/npm/v8.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Once installed, V8.js can be required and expose a list of functions for you to use.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;v8&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="s2"&gt;v8.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Only for node&lt;/span&gt;

&lt;span class="nx"&gt;v8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getHeapUsage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;v8&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="s2"&gt;v8.js&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;previousUsage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;v8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getHeapUsage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;v8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collectGarbage&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;afterUsage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;v8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getHeapUsage&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="s2"&gt;`Just cleared &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;previousUsage&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;afterUsage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bytes of memory.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  I need you !
&lt;/h2&gt;

&lt;p&gt;I still consider it a beta version (hence the v0.2.0 version). So I'll warmly welcome any feedback.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/v8/v8/blob/master/src/runtime/runtime.h"&gt;list of available functions of the v8 engine&lt;/a&gt; is quite large and I didn't want to include everything blindly. So if you see something useful V8.js is missing &lt;a href="https://github.com/GMartigny/v8.js/issues/new"&gt;raise a new issue&lt;/a&gt; with your use-case.&lt;/p&gt;

&lt;p&gt;Peace ✌️&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Why the JS ecosystem is awesome !</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Sat, 27 Apr 2019 17:26:36 +0000</pubDate>
      <link>https://dev.to/gmartigny/why-the-js-ecosystem-is-awesome-48nl</link>
      <guid>https://dev.to/gmartigny/why-the-js-ecosystem-is-awesome-48nl</guid>
      <description>&lt;p&gt;The Javascript world is today's the most vibrant development ecosystem. It's popularity propelled it from a simple scripting gadget to the backbone of today's web. Browsers are more powerful each passing day, NPM registry grows to whooping 1 million packages and Node has long shown it's a competent back-end language.&lt;/p&gt;

&lt;p&gt;Today, we're going to create a tiny project from scratch together and take full advantage of all that. I want to show you that you don't need years of experience to create something cool.&lt;br&gt;
Buckle up, it's a long ride, but I promise you that by the end you can do it all by yourself.&lt;/p&gt;
&lt;h2&gt;
  
  
  Act I: the code
&lt;/h2&gt;

&lt;p&gt;Let's say you have an idea you want to code. No, no, a simpler one. Something that can fit in one function. Something like creating a unique image per username, returning the hour of any timezone or return a random color.&lt;/p&gt;

&lt;p&gt;For our purposes, we're going to create a function that give a blank image given dimensions. No big deal, just create a canvas, color it and return the data. We will called it &lt;code&gt;lorem-pix&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, I start every project the same way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir lorem-pix
$ cd lorem-pix
$ git init
$ npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, let's create that &lt;code&gt;index.js&lt;/code&gt; and start coding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loremPix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createCanvas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&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;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&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;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toDataURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/png&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="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;loremPix&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, you should note that &lt;code&gt;createCanvas&lt;/code&gt; is not defined. If I was in a browser, I'll just have to do &lt;code&gt;document.createElement("canvas")&lt;/code&gt;, but I already know I don't want to stay in the browser environment and Node has no &lt;code&gt;Canvas&lt;/code&gt; support. 😱&lt;br&gt;
What could we do ?&lt;/p&gt;
&lt;h2&gt;
  
  
  Act II: NPM
&lt;/h2&gt;

&lt;p&gt;With hundreds of thousands of packages, &lt;a href="https://npmjs.com" rel="noopener noreferrer"&gt;NPM&lt;/a&gt; potentially hold a solution for any of your problems. As NPM-cli comes bundled with Node, it's safe to say that it's the most influential program in Javascript.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't mix-up NPM and NPM-cli. The former is the public registry holding all the codes while the latter is the utility requesting from the registry.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A &lt;a href="https://www.npmjs.com/search?q=canvas" rel="noopener noreferrer"&gt;bit of research&lt;/a&gt; gives me exactly what I need. All left to do is fetching the desired dependency.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm install canvas
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add a &lt;code&gt;require&lt;/code&gt; at the top of our &lt;code&gt;index.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createCanvas&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;canvas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note that Node sadly don't support the &lt;a href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/import" rel="noopener noreferrer"&gt;&lt;code&gt;import&lt;/code&gt; statement&lt;/a&gt; as of today.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And voilà, our function is now done. We can even publish it at NPM so anyone can use it. Just make sure your &lt;code&gt;package.json&lt;/code&gt; is correctly filled and we're good to go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, this is already pretty great. We have a function that rely on someone else code and we published it so anyone can rely on us.&lt;br&gt;
But why not go a little further ?&lt;/p&gt;
&lt;h2&gt;
  
  
  Act III: CLI
&lt;/h2&gt;

&lt;p&gt;Since &lt;a href="https://github.com/npm/npm/releases/tag/v5.2.0" rel="noopener noreferrer"&gt;NPM-cli &lt;code&gt;5.2.0&lt;/code&gt;&lt;/a&gt;, a new command is available: &lt;code&gt;npx&lt;/code&gt;. Thanks to it, you can execute code hosted on NPM with a single command line. It magically download, install what need to be and run the required binary file.&lt;/p&gt;

&lt;p&gt;But we need to have a binary executable. Our JS function is great, but can only be called by a JS script.&lt;br&gt;
Let's remedy that by creating a new file named &lt;code&gt;cli.js&lt;/code&gt;. Running a plain text file on the operating system is not going to work. We need to tell which program have to parse the code inside it. In our case we need it to be Node (default is &lt;code&gt;bash&lt;/code&gt; on unix or &lt;code&gt;cmd.exe&lt;/code&gt; on windows). Fortunately, we can do so with a &lt;a href="https://www.wikiwand.com/en/Shebang_(Unix)" rel="noopener noreferrer"&gt;shebang&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cp"&gt;#!/usr/bin/env node
&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loremPix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;writeFileSync&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs&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;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&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;2&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;dataURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loremPix&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lorem.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dataURL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Done creating image.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the first line, you can notice the shebang thing. Then we import our own library and the Node file-system utility.&lt;br&gt;
Next, we gather the inputs from the command-line arguments, the first one being the program (&lt;code&gt;node&lt;/code&gt;) and the second one the file executed (&lt;code&gt;cli.js&lt;/code&gt;). Anything after that is treated as arguments to our function.&lt;br&gt;
Finally, the script &lt;a href="https://nodejs.org/api/fs.html#fs_fs_writefilesync_file_data_options" rel="noopener noreferrer"&gt;write the file&lt;/a&gt; using the returned data. Details don't matter, but it need a file name, some data and the encoding method.&lt;/p&gt;

&lt;p&gt;After a &lt;code&gt;chmod&lt;/code&gt; to add execution rights, we are now able to run this script like any program installed on your computer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ chmod +x cli.js
$ ./cli.js 200 150 red
&amp;gt; Done creating image.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom! A new file called &lt;code&gt;lorem.png&lt;/code&gt; appeared right next to the &lt;code&gt;cli.js&lt;/code&gt; and you guessed it, it's a red image of 200 by 150 pixels.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fo61xkrhzfn1zxjfp2vow.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fo61xkrhzfn1zxjfp2vow.png" alt="Red image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Incredible! 😮&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It means that anyone with Node installed can call &lt;code&gt;npx&lt;/code&gt; to use our fantastic library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx lorem-pix 200 150 red
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now, what if we want to make it available to user even without Node ?&lt;/p&gt;

&lt;h2&gt;
  
  
  Act IV: API
&lt;/h2&gt;

&lt;p&gt;Historically, JS was created to be used on back-end and Node is the rightful heir of that history. If our code is deployed on a Node back-end, it can be run with a simple URL call.&lt;br&gt;
I'm going to use &lt;a href="https://zeit.co/now" rel="noopener noreferrer"&gt;ZEIT's &lt;code&gt;now&lt;/code&gt;&lt;/a&gt; because I love it. It's so simple it hurt.&lt;/p&gt;

&lt;p&gt;First, we can again add a new file called &lt;code&gt;api.js&lt;/code&gt; and fill it according to &lt;a href="https://zeit.co/docs/v2/deployments/official-builders/node-js-now-node/" rel="noopener noreferrer"&gt;the documentation&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loremPix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;parse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;query&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loremPix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/png&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="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&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;Almost like &lt;code&gt;cli.js&lt;/code&gt;: import our library, parse the URL for the right parameters and write the result to the response back to the user.&lt;/p&gt;

&lt;p&gt;We also need a &lt;code&gt;now.json&lt;/code&gt; file to configure &lt;code&gt;now&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"builds"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api.js"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@now/node"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"routes"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/api/(?&amp;lt;width&amp;gt;[^/]+)/?(?&amp;lt;height&amp;gt;[^/]*)/?(?&amp;lt;color&amp;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;"dest"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/api.js?width=$width&amp;amp;height=$height&amp;amp;color=$color"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="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;First we tell &lt;code&gt;now&lt;/code&gt; to use Node to run &lt;code&gt;api.js&lt;/code&gt;. Kind of like the shebang for the &lt;code&gt;cli.js&lt;/code&gt;.&lt;br&gt;
The hieroglyphs by the end is a regular expression. Users are lazy and so am I. It's easier for me to parse URL like &lt;code&gt;api.js?width=200&amp;amp;height=150&lt;/code&gt;, but it's more simple for users to write &lt;code&gt;api/200/150&lt;/code&gt;. The regexp do just that by rerouting requests.&lt;/p&gt;

&lt;p&gt;Ok, time to deploy the API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npx now login
$ npx now
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once done, the program tells you which URL you can use to execute the code. In my case:&lt;br&gt;
&lt;a href="https://lorem-pix-o5fjmzam5.now.sh/api/200/150/red" rel="noopener noreferrer"&gt;https://lorem-pix-o5fjmzam5.now.sh/api/200/150/red&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The API return an image whenever someone request it. It means that any HTML page can use it without any installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://lorem-pix-o5fjmzam5.now.sh/api/200/150/red"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"placeholder"&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;Hol' up a minute !&lt;/p&gt;

&lt;h2&gt;
  
  
   Act V: Webservice
&lt;/h2&gt;

&lt;p&gt;Any HTML page can use it ? Why not create our own page ?&lt;br&gt;
We already set &lt;code&gt;now&lt;/code&gt; to host the JS code, we can add a static HTML page along side it. More than just a landing page to present our project, we can have user inputs with live preview of the result.&lt;br&gt;
Yet another file, this time of course named &lt;code&gt;index.html&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Lorem pix&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    ...
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"live preview"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"preview"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"front/live-preview.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;form&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;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;preview&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;livePreview&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&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;height&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;color&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="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I put the CSS and JS file under the &lt;code&gt;front&lt;/code&gt; folder just for organization's sake. Here's what our script looks like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;API_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://lorem-pix-o5fjmzam5.now.sh/api&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;livePreview&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&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;API_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nf"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&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;url&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;Pretty straightforward!&lt;br&gt;
I just used &lt;code&gt;encodeURIComponent&lt;/code&gt; to avoid the &lt;code&gt;#&lt;/code&gt; charactere messing with the URL.&lt;br&gt;
Finally, we need tell &lt;code&gt;now&lt;/code&gt; to serve the static files in &lt;code&gt;now.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="nl"&gt;"builds"&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@now/html-minifier"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/front/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@now/static"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's not forget to deploy again with &lt;code&gt;npx now&lt;/code&gt; and &lt;a href="https://lorem-pix-8kqz0zewu.now.sh/" rel="noopener noreferrer"&gt;we are live&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;What a ride!&lt;br&gt;
Being able to access the same function as a package, a CLI, an API and a front-end webservice is still incredible for me. I highly encourage everyone reading to try and do it's own. You can access the whole &lt;a href="https://github.com/GMartigny/lorem-pix" rel="noopener noreferrer"&gt;code-base at Github&lt;/a&gt; and copy/paste from here.&lt;br&gt;
With a little more creativity than just making a blank image, I'm sure all of you can offer some great product. Be sure to share them in comments below.&lt;/p&gt;

&lt;p&gt;Peace 🙏&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>showdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Awesome projects under 1000 stars (3) - Lyo</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Wed, 07 Nov 2018 10:42:15 +0000</pubDate>
      <link>https://dev.to/gmartigny/awesome-projects-under-1000-stars-3---lyo-2k93</link>
      <guid>https://dev.to/gmartigny/awesome-projects-under-1000-stars-3---lyo-2k93</guid>
      <description>&lt;h1&gt;
  
  
  &lt;a href="https://github.com/bokub/lyo" rel="noopener noreferrer"&gt;Lyo&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;One of the most appreciated feature of the Javascript environment is undoubtedly the &lt;a href="https://www.npmjs.com" rel="noopener noreferrer"&gt;NPM&lt;/a&gt; huge choice of open-source packages. Easy to use, (mostly) reliable, fast, secure ... it has many big advantages under its belt.&lt;/p&gt;

&lt;p&gt;On the other hand, one of the most hated subject, even by veteran developer is the weird dichotomy between node.js and javascript browser engines. The language offer the possibility to run the same code on back-end and front-end, but we never quite got where it works seamlessly.&lt;/p&gt;

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

&lt;p&gt;Lyo aim to fill that gap. This tool could turn any node.js package into a single file browser library.&lt;br&gt;
Let's walk through an example to see it running.&lt;/p&gt;

&lt;p&gt;First, I choose a random package on NPM that I want to have on my browser. A common feature missing from Javascript is native encryption, so I choose &lt;a href="https://www.npmjs.com/package/sha1" rel="noopener noreferrer"&gt;sha1&lt;/a&gt;. Imagine I want to add this hashing script to a plain HTML page.&lt;/p&gt;

&lt;p&gt;Since &lt;a href="https://www.npmjs.com/package/npx" rel="noopener noreferrer"&gt;npx&lt;/a&gt; exists, I don't even have to install Lyo, I can just run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx lyo get sha1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;From top to bottom, we can see that :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lyo was installed in 6.5s&lt;/li&gt;
&lt;li&gt;run over sha1 version 1.1.1&lt;/li&gt;
&lt;li&gt;it read the file sha1.js&lt;/li&gt;
&lt;li&gt;output a file named sha1.min.js&lt;/li&gt;
&lt;li&gt;named the library &lt;code&gt;sha1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Browserify, Babel and Uglify was successfully ran&lt;/li&gt;
&lt;li&gt;Lyo terminated without error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then, I can simply add the output file into my HTML page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"sha1.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sha1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;P@ssWord&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// =&amp;gt; 56355fa0c17cb7f9dc0d936f6c7aa385114ee097&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How easy is this !&lt;/p&gt;

&lt;p&gt;Not easy enough ? You don't even want to open your terminal ? Lyo got you covered. Open &lt;a href="https://lyo.now.sh/" rel="noopener noreferrer"&gt;lyo.now.sh&lt;/a&gt; on your favorite browser and enter the name of the package you want to compile. Lyo will take care of everything and output how you can use this package over a CDN or node.js.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lyo.now.sh/sha1" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2oeg126bxci6cgquz73t.png" alt="Lyo service" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the other side of the spectrum, why not provide your user with a browser version of your node.js package ?&lt;br&gt;
Of course, you might already use Browserify or Webpack, but you can now delegate all the work to Lyo.&lt;/p&gt;

&lt;p&gt;Open your project folder, then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx lyo init
npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lyo will edit the &lt;code&gt;package.json&lt;/code&gt; file to add itself as a dependency and add a script to execute it.&lt;br&gt;
Now, every time you publish your work on NPM, it will be packed in a single file. This file can then be directly downloaded or through a CDN like &lt;a href="https://www.jsdelivr.com/" rel="noopener noreferrer"&gt;jsDelivr&lt;/a&gt; or &lt;a href="https://unpkg.com/#/" rel="noopener noreferrer"&gt;unpkg&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A few caveat, Lyo can't ensure that its output is working under the browser environment. For example, a package using the file system or any node-only capability, won't be able to run on a browser. Also, Browserify is quite opinionated on the use of ES6 features like &lt;a href="https://github.com/browserify/browserify/issues/1186" rel="noopener noreferrer"&gt;import/export&lt;/a&gt;. It means you can't use any syntax not already supported by the node.js' last version.&lt;/p&gt;

&lt;p&gt;I really love how a so complex process can be used so easily. Whether you like or not the &lt;a href="https://www.npmjs.com/package/is-even" rel="noopener noreferrer"&gt;extreme modularity of NPM&lt;/a&gt;, Lyo allow you to harness this power.&lt;/p&gt;

&lt;p&gt;See you all next month.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Awesome projects under 1000 stars (2) - Gridland</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Mon, 01 Oct 2018 11:43:52 +0000</pubDate>
      <link>https://dev.to/gmartigny/awesome-projects-under-1000-stars-2---gridland-398c</link>
      <guid>https://dev.to/gmartigny/awesome-projects-under-1000-stars-2---gridland-398c</guid>
      <description>&lt;h1&gt;
  
  
  &lt;a href="https://github.com/doublespeakgames/gridland" rel="noopener noreferrer"&gt;Gridland&lt;/a&gt;
&lt;/h1&gt;

&lt;p&gt;This month, I wanted to do thing a little differently. I mean, I never said this thread have to be serious and that's my post after all.&lt;br&gt;
So this time, I present you GridLand. A very addictive and fun time waster game.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqm33nqtwk6hs51g783jo.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fqm33nqtwk6hs51g783jo.png" alt="Quiet start"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wrapped around a simple "match 3" game, Gridland allow you to build and upgrade buildings in order to improve your abilities.&lt;br&gt;
Each time you match enough squares, you earn a new resources to be spend on your camp. With enough resources, you little avatar will grow your camp.&lt;/p&gt;

&lt;p&gt;But don't match loosely, indeed, each moves make time pass a little and when night comes ... like most games ... monsters are unleashed.&lt;br&gt;
At night, your grid of resources turn into a grid of monsters and defenses.&lt;br&gt;
Game-play change a bit too. The careful "match as many as day last" turn into a frantic "give me a freakin' sword instead of spawning dozens of monsters !".&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3whgsbbp6zmg9ly5lcri.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F3whgsbbp6zmg9ly5lcri.gif" alt="yeah, I know there's a sword match on the left ..."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, if I'm showing this today, it's not just because the game is fun. It's because the whole game's code is open-sourced on github.&lt;br&gt;
Like many projects, there's a huge lack in documentation 🙄. However, the code is very well formatted and architectured.&lt;br&gt;
You can find (and learn from) every game development traditional parts: event-manager, game-state save, localisation, audio, entities ...&lt;br&gt;
It's all basic Javascript, so even if you're not a master developer, you can understand and pick good bits from the code.&lt;/p&gt;

&lt;p&gt;Start by playing around a little before diving into code.&lt;br&gt;
First it will reduce spoilers. Then You will have an idea on how the game works and what to expect from each files.&lt;/p&gt;

&lt;p&gt;Here some advice :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Matching more than 3 tiles has a great bonus, try to do it as much as possible&lt;/li&gt;
&lt;li&gt;Don't use magic to turn night into day, you need that XP from fights&lt;/li&gt;
&lt;li&gt;You can prioritize building by clicking on them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And some dev tips :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The event-manager is simple, but very useful&lt;/li&gt;
&lt;li&gt;the &lt;a href="https://github.com/doublespeakgames/gridland/blob/master/www/js/app/gamestate.js" rel="noopener noreferrer"&gt;gamestate.js&lt;/a&gt; file handle saving, which is pain to do right&lt;/li&gt;
&lt;li&gt;Check &lt;a href="https://requirejs.org/" rel="noopener noreferrer"&gt;Require.js&lt;/a&gt; for those strange &lt;code&gt;define(['...', '...'], function(&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See you all next month.&lt;/p&gt;

&lt;p&gt;ps: The next game from DoubleSpeak studio called "&lt;a href="https://github.com/doublespeakgames/adarkroom" rel="noopener noreferrer"&gt;a dark room&lt;/a&gt;" is amazing. Try it as well.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Awesome projects under 1000 stars (1) - Badgen</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Wed, 05 Sep 2018 14:05:23 +0000</pubDate>
      <link>https://dev.to/gmartigny/awesome-projects-under-1000-stars-1-366i</link>
      <guid>https://dev.to/gmartigny/awesome-projects-under-1000-stars-1-366i</guid>
      <description>&lt;p&gt;Discovering new projects is not an easy task. Thousands pops every days and a happy few become renown. This leaves a huge chunk of work forgotten by everyone, sometimes for good reasons (useless, copy-pasta, under-maintained ...) and sometimes for no reason whatsoever.&lt;/p&gt;

&lt;p&gt;With this thread of article I aim to shine some light over an interesting project once a month.&lt;/p&gt;

&lt;p&gt;As it's the very first post, I lay some basic rules for myself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Any project in the web-sphere is eligible (library, tool, website ...)&lt;/li&gt;
&lt;li&gt;Only open-source hosted on github (I want to promote OOS, but I don't have the time to parse many source)&lt;/li&gt;
&lt;li&gt;Project under 1000 stars are considered, but the lower the better&lt;/li&gt;
&lt;li&gt;I handpick and test every project for a while before giving any appreciation&lt;/li&gt;
&lt;li&gt;Project should be stable, maintained and over 1 month old&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm welcoming with great pleasure any suggestions in the comments. I'll look at them all and surely write about it if it respects the initial rules.&lt;/p&gt;

&lt;p&gt;Without further ado, I present you&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;a href="https://github.com/amio/badgen" rel="noopener noreferrer"&gt;badgen&lt;/a&gt; and &lt;a href="https://github.com/amio/badgen-service" rel="noopener noreferrer"&gt;badgen-service&lt;/a&gt;
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Yes two for the price of one !&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Badgen can be used as a online service or as a javascript library.&lt;/p&gt;

&lt;p&gt;I'm sure you've already seen a repository badge like:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fbadgen.net%2Fbadge%2Fdev%2Fhello%2520world" 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%2Fbadgen.net%2Fbadge%2Fdev%2Fhello%2520world" alt="example badge"&gt;&lt;/a&gt;&lt;br&gt;
Well, it's never been easier and faster to render one using badgen.&lt;/p&gt;

&lt;p&gt;Built to be a faster alternative to &lt;a href="https://shields.io/#/" rel="noopener noreferrer"&gt;shields.io&lt;/a&gt;, badgen deliver with awesome speed. The syntaxe to build badge is really clear and hackable. You can even use any arbitrary end-point returning a JSON formatted response.&lt;/p&gt;

&lt;p&gt;You can check all examples on the &lt;a href="https://badgen.net/" rel="noopener noreferrer"&gt;badgen website&lt;/a&gt;, but here's a handful of them for a taste with corresponding URL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static values: &lt;a href="https://badgen.net/badge/dev/to/black" rel="noopener noreferrer"&gt;/badge/dev/to/black&lt;/a&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fbadgen.net%2Fbadge%2Fdev%2Fto%2Fblack" alt="static"&gt;
&lt;/li&gt;
&lt;li&gt;Github stars: &lt;a href="https://badgen.net/github/stars/thepracticaldev/dev.to"&gt;/github/stars/thepracticaldev/dev.to&lt;/a&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fbadgen.net%2Fgithub%2Fstars%2Fthepracticaldev%2Fdev.to" alt="github star"&gt;
&lt;/li&gt;
&lt;li&gt;NPM dependents: &lt;a href="https://badgen.net/npm/dependents/left-pad" rel="noopener noreferrer"&gt;/npm/dependents/left-pad&lt;/a&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fbadgen.net%2Fnpm%2Fdependents%2Fleft-pad" alt="github star"&gt;
&lt;/li&gt;
&lt;li&gt;Code coverage: &lt;a href="https://badgen.net/codeclimate/coverage/thepracticaldev/dev.to"&gt;/codeclimate/coverage/thepracticaldev/dev.to&lt;/a&gt;
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fbadgen.net%2Fcodeclimate%2Fcoverage%2Fthepracticaldev%2Fdev.to" alt="code coverage"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Serving a JSON with a "subject", "status" and "color" field allow you to build custom dynamic badge. Here's a stupid example loosely showing what I should be doing right now.&lt;br&gt;
I create a &lt;a href="https://runkit.com/gmartigny/5b8fa7a29cf9530012642696/" rel="noopener noreferrer"&gt;runkit&lt;/a&gt; script outputing the right data. Then use this end-point in the badgen URL. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://badgen.net/https/untitled-ljtss6i6xow1.runkit.sh" rel="noopener noreferrer"&gt;/https/untitled-ljtss6i6xow1.runkit.sh&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fbadgen.net%2Fhttps%2Funtitled-ljtss6i6xow1.runkit.sh" 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%2Fbadgen.net%2Fhttps%2Funtitled-ljtss6i6xow1.runkit.sh" alt="doing now"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most awesome thing, in my opinion, is the reactivity of the main maintainer. The project is very active and you get answer to your issue or PR in a matter of hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus points&lt;/strong&gt;: the code is clear and well put together (even if it lack documentation) and can be a nice learning point.&lt;/p&gt;

&lt;p&gt;Go check it out and see you all next month.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>github</category>
      <category>showdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Should a library log its version number ?</title>
      <dc:creator>Guillaume Martigny</dc:creator>
      <pubDate>Mon, 20 Aug 2018 15:00:33 +0000</pubDate>
      <link>https://dev.to/gmartigny/should-a-library-log-its-version-number--nnf</link>
      <guid>https://dev.to/gmartigny/should-a-library-log-its-version-number--nnf</guid>
      <description>&lt;p&gt;Most libraries, &lt;a href="https://github.com/pixijs/pixi.js/blob/0fce8934edd87dab83b8734205c004c784e87545/src/core/utils/index.js#L262"&gt;log their version number&lt;/a&gt; (and some other data) when you import them. Sometimes, you can disable this behavior, sometimes you can't.&lt;/p&gt;

&lt;p&gt;I don't find it awfully bothering, but I wonder what everyone think about it.&lt;/p&gt;

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