<?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: Armedi</title>
    <description>The latest articles on DEV Community by Armedi (@armedi).</description>
    <link>https://dev.to/armedi</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%2F234078%2F9ae48491-b4ba-4123-9244-96efcedb3f80.jpeg</url>
      <title>DEV Community: Armedi</title>
      <link>https://dev.to/armedi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/armedi"/>
    <language>en</language>
    <item>
      <title>Menggunakan TypeScript Template Literal Type</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Mon, 03 May 2021 07:56:48 +0000</pubDate>
      <link>https://dev.to/armedi/menggunakan-typescript-template-literal-type-5glm</link>
      <guid>https://dev.to/armedi/menggunakan-typescript-template-literal-type-5glm</guid>
      <description>&lt;p&gt;&lt;em&gt;Template Literal Type&lt;/em&gt; telah tersedia sejak TypeScript versi 4.1 yang dirilis pada November 2020 lalu. Fitur ini sangat powerful, hingga ada yang membuat &lt;a href="https://github.com/codemix/ts-sql"&gt;implementasi SQL&lt;/a&gt; hanya dengan &lt;em&gt;TypeScript type annotation&lt;/em&gt;. &lt;em&gt;Template Literal Type&lt;/em&gt; ini menjadi tipe data literal keempat di TypeScript setelah string, number, dan boolean.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic
&lt;/h3&gt;

&lt;p&gt;Sintaks untuk &lt;em&gt;template literal type&lt;/em&gt; sama persis dengan string template literal, tapi digunakan pada deklarasi tipe data.&lt;/p&gt;

&lt;p&gt;Misalkan kamu membuat sebuah React component sebagai berikut:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Yh4qd_IJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ah1zb4QfF0ajwpjDYI7o5tA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Yh4qd_IJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ah1zb4QfF0ajwpjDYI7o5tA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tipe data Position adalah &lt;em&gt;string union&lt;/em&gt; yang merepresentasikan kombinasi posisi vertikal dan horizontal. Bayangkan kalau ada puluhan kombinasi yang harus ditulis satu per satu, tentu akan menjadi pekerjaan yang melelahkan. Dari contoh ini saja bisa dilihat ada cukup banyak pengulangan yang harus dituliskan untuk membuat kombinasi yang lengkap.&lt;/p&gt;

&lt;p&gt;Contoh diatas Jika di-&lt;em&gt;refactor&lt;/em&gt; dengan menggunakan &lt;em&gt;template literal type,&lt;/em&gt; maka akan menjadi&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zfg6lqoL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ajm6zeYLpeT_A2tyVdgT3FQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zfg6lqoL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ajm6zeYLpeT_A2tyVdgT3FQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dengan menggunakan &lt;em&gt;Template Literal Type&lt;/em&gt; kita bisa dengan mudah membuat kombinasi antara tipe VerticalPosition dengan HorizontalPosition menjadi tipe data Position.&lt;/p&gt;

&lt;h3&gt;
  
  
  Template Literal Inference
&lt;/h3&gt;

&lt;p&gt;Fitur powerful dari &lt;em&gt;template literal type&lt;/em&gt; datang dari kemampuan untuk meng-&lt;em&gt;infer&lt;/em&gt; tipe data dan digabungkan dengan &lt;em&gt;conditional type&lt;/em&gt;. Misalkan sebuah fungsi melakukan manipulasi terhadap &lt;em&gt;string&lt;/em&gt; seperti mengubah dari &lt;em&gt;snake_case&lt;/em&gt; menjadi &lt;em&gt;camelCase&lt;/em&gt;. Fungsi ini menerima input berupa &lt;em&gt;string&lt;/em&gt; dan menghasilkan output &lt;em&gt;string&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hozYOBZ5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AGeSvIIgSfPiK65SDPT0xVA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hozYOBZ5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AGeSvIIgSfPiK65SDPT0xVA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dengan menggunakan &lt;em&gt;template literal type&lt;/em&gt; dan juga &lt;em&gt;type inference&lt;/em&gt;, kita bisa membuat fungsi yang menghasilkan tipe data &lt;em&gt;output&lt;/em&gt; yang lebih spesifik:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JEgbWT_t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A5qTgfqtVStlceEe-ITyvqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JEgbWT_t--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A5qTgfqtVStlceEe-ITyvqg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lalu apa gunanya tipe data literal untuk &lt;em&gt;output&lt;/em&gt; seperti diatas?&lt;/p&gt;

&lt;p&gt;Misalnya kamu memiliki fungsi yang mengubah properti sebuah object dari &lt;em&gt;snake_case&lt;/em&gt; menjadi &lt;em&gt;camelCase&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5A5cWdXg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AC-4z_lKP0aFkrOOWKG3QDQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5A5cWdXg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AC-4z_lKP0aFkrOOWKG3QDQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pada contoh diatas, object camelCasedProperties yang merupakan output dari fungsi camelCaseProperties tidak &lt;em&gt;type safe&lt;/em&gt;. Berbeda halnya jika menggunakan &lt;em&gt;template literal type&lt;/em&gt;, maka output dari fungsi camelCaseProperties menjadi &lt;em&gt;fully typed&lt;/em&gt;, dan &lt;em&gt;code completion&lt;/em&gt; dari editor pun menjadi tersedia.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5cSameWN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A_wMeQRRlj8vBOm2TvtMZMw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5cSameWN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A_wMeQRRlj8vBOm2TvtMZMw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Daftar Referensi:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html"&gt;https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ghoullier/awesome-template-literal-types"&gt;https://github.com/ghoullier/awesome-template-literal-types&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/phenomnominal/i-need-to-learn-about-typescript-template-literal-types-51po"&gt;https://dev.to/phenomnominal/i-need-to-learn-about-typescript-template-literal-types-51po&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://michalzalecki.com/typescript-template-literal-types/"&gt;https://michalzalecki.com/typescript-template-literal-types/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://davidtimms.github.io/programming-languages/typescript/2020/11/20/exploring-template-literal-types-in-typescript-4.1.html"&gt;https://davidtimms.github.io/programming-languages/typescript/2020/11/20/exploring-template-literal-types-in-typescript-4.1.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://effectivetypescript.com/2020/11/05/template-literal-types/"&gt;https://effectivetypescript.com/2020/11/05/template-literal-types/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
    </item>
    <item>
      <title>React Proxy-State dengan Valtio</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Sat, 28 Nov 2020 07:16:07 +0000</pubDate>
      <link>https://dev.to/armedi/react-proxy-state-dengan-valtio-2lda</link>
      <guid>https://dev.to/armedi/react-proxy-state-dengan-valtio-2lda</guid>
      <description>&lt;p&gt;Dari pengalaman saya mengajar fullstack web development, banyak sekali murid yang bilang bahwa mereka lebih enjoy menggunakan Vue daripada React. Dan salah satu penyebabnya adalah karena manipulasi state di React tidak senyaman di Vue (Ini menurut beberapa orang yang pernah saya tanya).&lt;/p&gt;

&lt;p&gt;Berangkat dari hal itu, sekitar 3 bulan yang lalu saya menulis artikel tentang bagaimana menggunakan library Vue reactivity di React&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/armedi" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C3KTG_vi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--P6KIIe04--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/234078/9ae48491-b4ba-4123-9244-96efcedb3f80.jpeg" alt="armedi image"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/armedi/menggunakan-vue-reactivity-pada-komponen-react-2j08" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Menggunakan Vue Reactivity pada Komponen React&lt;/h2&gt;
      &lt;h3&gt;Armedi ・ Sep 11 '20 ・ 5 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#vue3&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#vuecompositionapi&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#vueinreact&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Ide dasarnya adalah tentang bagaimana menggunakan state yang mutable pada React. Dan waktu itu saya menggunakan library &lt;a href="https://www.npmjs.com/package/@vue/reactivity"&gt;@vue/reactivity&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@vue/reactivity&lt;/code&gt; ini pada dasarnya menggunakan &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy"&gt;Proxy&lt;/a&gt; untuk &lt;em&gt;change detection&lt;/em&gt;. Yaitu proses bagaimana perubahan state dideteksi dan kemudian men-&lt;em&gt;trigger update&lt;/em&gt; pada UI menyesuaikan dengan state terbaru.&lt;/p&gt;

&lt;p&gt;Dan jujur saja ketika library ini saya pakai di React, code yang dibuat tidak menjadi lebih sederhana dan lebih mudah dipahami dibandingkan menggunakan bawaan dari React seperti &lt;code&gt;useState&lt;/code&gt; hook. Tapi idenya sendiri (&lt;em&gt;mutable state&lt;/em&gt; di React) saya yakin sangat sangat legit.&lt;/p&gt;

&lt;p&gt;Nah di artikel ini saya akan bahas sebuah library baru yang lagi ngehits.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pmndrs"&gt;
        pmndrs
      &lt;/a&gt; / &lt;a href="https://github.com/pmndrs/valtio"&gt;
        valtio
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      💊 Valtio makes proxy-state simple  for React and Vanilla
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Pada waktu tulisan ini dibuat, &lt;code&gt;valtio&lt;/code&gt; baru berumur sepuluh hari semenjak versi 0.1 dirilis namun telah memperoleh sebanyak &lt;strong&gt;1,2k stars&lt;/strong&gt; di github. Suatu pertanda baik bahwa library ini punya masa depan yang sangat cerah, hehe.&lt;/p&gt;

&lt;p&gt;Di bawah ini adalah contoh resmi dari githubnya valtio. Di sini kamu liat betapa simpelnya cara penggunaannya&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/valtio-simple-counter-qqljs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Benar gampang kan?&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useProxy&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;valtio&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;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;number&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="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Figure&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;snapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;figure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;State valtio bebas kamu mau mutate dimana saja, dan bahkan sudah support Suspense.&lt;/p&gt;

&lt;p&gt;Langsung aja kamu bisa cek githubnya di &lt;a href="https://github.com/pmndrs/valtio"&gt;https://github.com/pmndrs/valtio&lt;/a&gt; untuk melihat fitur-fitur keren apa aja yang tersedia.&lt;/p&gt;

&lt;p&gt;Semoga berguna!!!&lt;/p&gt;

</description>
      <category>react</category>
      <category>valtio</category>
      <category>proxy</category>
    </item>
    <item>
      <title>Logical Assignment Operators di Javascript</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Sat, 14 Nov 2020 05:53:41 +0000</pubDate>
      <link>https://dev.to/armedi/logical-assignment-operators-di-javascript-fpo</link>
      <guid>https://dev.to/armedi/logical-assignment-operators-di-javascript-fpo</guid>
      <description>&lt;p&gt;Ada beberapa operator baru yang sangat praktis digunakan untuk mempersingkat kodingan Javascript kamu. &lt;a href="https://github.com/tc39/proposal-logical-assignment"&gt;Proposal&lt;/a&gt;nya sudah sampai tahap stage 4 yang artinya akan dimasukkan pada versi ECMAScript berikutnya (ES2021). Ini juga berarti sekarang sudah bisa digunakan karena sudah support oleh browser-browser modern versi terupdate tanpa menggunakan transpiler. Tapi tentu saja untuk kompatibilitas yang lebih tinggi disarankan kamu tetap menggunakan transpiler seperti &lt;a href="https://babeljs.io/"&gt;Babel&lt;/a&gt; atau menggunakan &lt;a href="https://www.typescriptlang.org/"&gt;Typescript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ada 3 operator yang masuk dalam &lt;a href="https://github.com/tc39/proposal-logical-assignment"&gt;proposal logical assignment&lt;/a&gt; ini:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logical OR assignment &lt;strong&gt;&lt;code&gt;||=&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Logical AND assignment &lt;strong&gt;&lt;code&gt;&amp;amp;&amp;amp;=&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Logical nullish assignment &lt;strong&gt;&lt;code&gt;??=&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Logical OR assignment &lt;strong&gt;&lt;code&gt;||=&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Operator ini berguna untuk case mengganti value sebuah variable jika valuenya adalah &lt;em&gt;falsy&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Misal untuk mengganti value variable &lt;code&gt;a&lt;/code&gt; jika value sebelumnya adalah &lt;em&gt;falsy&lt;/em&gt;, tanpa logical OR assignment kamu melakukannya lebih kurang dengan cara-cara seperti ini:&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;// cara 1&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new value&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;// cara 2&lt;/span&gt;
&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new value&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;Dengan logical OR assignment menjadi lebih singkat:&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;a&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new value&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;Kode diatas akan ditranspilasi oleh &lt;a href="https://babeljs.io/repl#?browsers=&amp;amp;build=&amp;amp;builtIns=false&amp;amp;spec=false&amp;amp;loose=false&amp;amp;code_lz=IYAgPmC8IEQHYFMDuIBuwA2BXBMg&amp;amp;debug=false&amp;amp;forceAllTransforms=false&amp;amp;shippedProposals=false&amp;amp;circleciRepo=&amp;amp;evaluate=false&amp;amp;fileSize=false&amp;amp;timeTravel=false&amp;amp;sourceType=module&amp;amp;lineWrap=false&amp;amp;presets=env&amp;amp;prettier=false&amp;amp;targets=&amp;amp;version=7.12.3&amp;amp;externalPlugins="&gt;Babel&lt;/a&gt; menjadi:&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;a&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&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;h2&gt;
  
  
  Logical AND assignment &lt;strong&gt;&lt;code&gt;&amp;amp;&amp;amp;=&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Operator ini adalah kebalikan dari operator sebelumnya. Yaitu untuk case mengganti value sebuah variable jika valuenya adalah &lt;em&gt;truthy&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Tanpa logical AND assignment, untuk mengganti value variable &lt;code&gt;a&lt;/code&gt; jika value sebelumnya adalah &lt;em&gt;truthy&lt;/em&gt; kamu melakukannya lebih kurang dengan cara-cara seperti ini:&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;// cara 1&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;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new value&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;// cara 2&lt;/span&gt;
&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new value&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;Syntax diatas bisa dipersingkat dengan menggunakan logical AND assignment:&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;a&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new value&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;Hasil transpilasinya oleh &lt;a href="https://babeljs.io/repl#?browsers=&amp;amp;build=&amp;amp;builtIns=false&amp;amp;spec=false&amp;amp;loose=false&amp;amp;code_lz=IYAgZGC8IEQHYFMDuIBuwA2BXBMg&amp;amp;debug=false&amp;amp;forceAllTransforms=false&amp;amp;shippedProposals=false&amp;amp;circleciRepo=&amp;amp;evaluate=false&amp;amp;fileSize=false&amp;amp;timeTravel=false&amp;amp;sourceType=module&amp;amp;lineWrap=false&amp;amp;presets=env&amp;amp;prettier=false&amp;amp;targets=&amp;amp;version=7.12.3&amp;amp;externalPlugins="&gt;Babel&lt;/a&gt; menjadi:&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;a&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new value&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;h2&gt;
  
  
  Logical nullish assignment &lt;strong&gt;&lt;code&gt;??=&lt;/code&gt;&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Kalau sebelumnya operator logical OR assignment berguna untuk mengecek nilai falsy yang di dalamnya termasuk &lt;code&gt;null&lt;/code&gt; dan &lt;code&gt;undefined&lt;/code&gt;, operator ini spesifik untuk case value &lt;code&gt;null&lt;/code&gt; atau &lt;code&gt;undefined&lt;/code&gt; saja.&lt;/p&gt;

&lt;p&gt;Tanpa menggunakan logical nullish assignment, untuk mengecek value &lt;code&gt;null&lt;/code&gt; atau &lt;code&gt;undefined&lt;/code&gt; dan menggantinya dengan value baru, kamu melakukannya lebih kurang dengan cara-cara berikut ini:&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;// cara 1&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;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new value&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;// cara 2&lt;/span&gt;
&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new value&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;Akan menjadi lebih singkat dengan menggunakan logical nullish assignment:&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;a&lt;/span&gt; &lt;span class="p"&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;new value&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;Kode diatas akan ditranspilasi oleh &lt;a href="https://babeljs.io/repl#?browsers=&amp;amp;build=&amp;amp;builtIns=false&amp;amp;spec=false&amp;amp;loose=false&amp;amp;code_lz=IYAg_GC8IEQHYFMDuIBuwA2BXBMg&amp;amp;debug=false&amp;amp;forceAllTransforms=false&amp;amp;shippedProposals=false&amp;amp;circleciRepo=&amp;amp;evaluate=false&amp;amp;fileSize=false&amp;amp;timeTravel=false&amp;amp;sourceType=module&amp;amp;lineWrap=false&amp;amp;presets=env&amp;amp;prettier=false&amp;amp;targets=&amp;amp;version=7.12.3&amp;amp;externalPlugins="&gt;Babel&lt;/a&gt; menjadi:&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;var&lt;/span&gt; &lt;span class="nx"&gt;_a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;_a&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="k"&gt;void&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;_a&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new value&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;h5&gt;
  
  
  Referensi:
&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Progressive Image Loading dengan BlurHash</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Sat, 31 Oct 2020 06:55:24 +0000</pubDate>
      <link>https://dev.to/armedi/progressive-image-loading-dengan-blurhash-1nda</link>
      <guid>https://dev.to/armedi/progressive-image-loading-dengan-blurhash-1nda</guid>
      <description>&lt;p&gt;&lt;a href="https://blurha.sh"&gt;BlurHash&lt;/a&gt; adalah sebuah representasi dari placeholder gambar dalam bentuk string singkat (sekitar 20-30an karakter per gambar).&lt;/p&gt;

&lt;p&gt;Kebanyakan dari website yang biasa kita akses biasanya menggunakan background dengan warna tertentu sebagai placeholder hingga image selesai di-load, dan biasanya juga menggunakan placeholder yang sama untuk semua image. Paling sering biasanya yang digunakan adalah background dengan warna abu-abu.&lt;/p&gt;

&lt;p&gt;Dengan menggunakan BlurHash, kamu bisa membuat placeholder yang unik untuk setiap image. Karena BlurHash sendiri adalah dalam bentuk string singkat seperti ini &lt;code&gt;LEHV6nWB2yk8pyo0adR*.7kCMdnj&lt;/code&gt;, jadi bisa ditempelkan langsung ke file html jika menggunakan static html atau bisa dikirim dengan API bersamaan dengan link gambar aslinya jika gambar yang ingin di-load bersifat dinamis.&lt;/p&gt;

&lt;p&gt;Dari hash tersebut kemudian di-decode menjadi gambar blur yang merepresentasikan aslinya&lt;/p&gt;

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

&lt;p&gt;Di akun &lt;a href="https://github.com/woltapp/blurhash"&gt;github&lt;/a&gt; resminya, terdapat berbagai implementasi untuk berbagai platform. Saya sendiri membuat &lt;a href="https://github.com/armedi/rescript-blurhash"&gt;implementasi&lt;/a&gt; yang bisa digunakan pada file html biasa tanpa harus ada javascript sama sekali.&lt;/p&gt;

&lt;p&gt;Cara menggunakannya sangat simpel, cukup dengan memasang script berikut di html&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/rescript-blurhash@0.3.2/dist/production.min.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;p&gt;kemudian di setiap image tambahkan attribute &lt;code&gt;data-blurhash&lt;/code&gt; seperti ini&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://blurha.sh/assets/images/img1.jpg"&lt;/span&gt;
   &lt;span class="na"&gt;data-blurhash=&lt;/span&gt;&lt;span class="s"&gt;"LEHV6nWB2yk8pyo0adR*.7kCMdnj"&lt;/span&gt;
   &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"width: 269px; height: 173px"&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;Maka otomatis gambar akan menampilkan placeholder berupa versi blurnya terlebih dahulu hingga gambar tersebut selesai di-load.&lt;/p&gt;

&lt;p&gt;Oh iya, untuk melakukan encoding kamu bisa menggunakan website resmi &lt;a href="https://blurha.sh/"&gt;blurhash&lt;/a&gt; atau menggunakan salah satu dari berbagai implementasinya tadi.&lt;/p&gt;

&lt;p&gt;Sebagai demo saya menggunakan gambar kategori produk dari &lt;a href="https://www.tokopedia.com/"&gt;tokopedia&lt;/a&gt; dimana aslinya tokopedia menggunakan placeholder background berwarna abu-abu. Demo bisa kamu lihat dengan klik &lt;a href="https://bl.ocks.org/armedi/raw/0e41317e31ce8567dc47c27126cd9166/"&gt;link ini&lt;/a&gt;. Untuk melihat bagaimana blurhash diload mungkin kamu perlu &lt;a href="https://developers.google.com/web/tools/chrome-devtools/network#throttle"&gt;mensimulasikan slow network&lt;/a&gt; pada devtools di browser terlebih dahulu dan kemudian lakukan hard reload.&lt;/p&gt;

&lt;p&gt;Kodenya bisa kamu liat &lt;a href="https://gist.github.com/armedi/0e41317e31ce8567dc47c27126cd9166"&gt;disini&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--icUiD-kM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m3mv7waccalqftmtg1vl.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--icUiD-kM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/m3mv7waccalqftmtg1vl.gif" alt="BlurHash"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blurhash</category>
      <category>progressiveimageloading</category>
    </item>
    <item>
      <title>ReasonReact, Part 1: Development Setup</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Sat, 10 Oct 2020 10:15:18 +0000</pubDate>
      <link>https://dev.to/armedi/reasonreact-part-1-development-setup-ghm</link>
      <guid>https://dev.to/armedi/reasonreact-part-1-development-setup-ghm</guid>
      <description>&lt;p&gt;Beberapa hari yang lalu saya membaca sebuah artikel tentang sebuah bahasa pemrograman "baru", lebih tepatnya sih nama baru untuk sebuah project lama. Nama dari bahasa baru ini adalah &lt;a href="https://rescript-lang.org/"&gt;ReScript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Project ini sebelumnya bernama BuckleScript yang &lt;a href="https://www.bloomberg.com/company/press/open-source-at-bloomberg-introducing-bucklescript/"&gt;dirilis oleh Bloomberg&lt;/a&gt; pada pertengahan tahun 2016 lalu. Bucklescript ini merupakan compiler yang menghasilkan kode javascript dari sumber OCaml.&lt;/p&gt;

&lt;p&gt;Pada tahun 2016 juga Facebook merilis &lt;a href="https://reasonml.github.io/"&gt;ReasonML&lt;/a&gt;, sebuah syntax baru untuk OCaml yang didesain agar terlihat familiar bagi developer javascript. Kemudian di tahun berikutnya lahir lah &lt;a href="https://reasonml.github.io/reason-react/"&gt;ReasonReact&lt;/a&gt;, binding untuk React dalam bahasa ReasonML.&lt;/p&gt;

&lt;p&gt;Setelah membaca artikel tadi, akhirnya saya pun mencoba ReasonReact. Cukup lama juga keinginan untuk mencoba ini hanya sampai sebatas niat yang tidak pernah terealisasikan 😄.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apa keuntungan menggunakan ReasonReact dibandingkan React.js?
&lt;/h3&gt;

&lt;p&gt;Simpelnya adalah eliminasi bugs. Contoh realnya adalah Facebook yang &lt;a href="https://reasonml.github.io/blog/2017/09/08/messenger-50-reason"&gt;mengurangi bug dengan sangat drastis&lt;/a&gt; pada messenger.com setelah migrasi ke Reason.&lt;/p&gt;

&lt;p&gt;Kok bisa?&lt;/p&gt;

&lt;p&gt;Karena &lt;a href="https://reasonml.github.io/docs/en/what-and-why#why-use-reason"&gt;&lt;em&gt;powerful type system&lt;/em&gt;&lt;/a&gt; dapat meminimalisir kesalahan yang mungkin dibuat oleh developer. Hal yang sama sebenarnya kenapa sekarang untuk project dengan skala menengah ke atas banyak yang akan memilih typescript dibandingkan plain javascript. Hanya saja Reason lebih baik dibandingkan Typescript dalam hal &lt;em&gt;type system&lt;/em&gt;-nya.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inisiasi ReasonReact
&lt;/h2&gt;

&lt;p&gt;Untuk quick start bisa menggunakan command yang tertera pada dokumentasinya ini&lt;/p&gt;

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

&lt;p&gt;Tapi saya merasa kalau setup yang diberikan pada starter template agak kurang. Karena:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ada dua command yang harus dijalankan di dua sesi terminal: &lt;code&gt;npm start&lt;/code&gt; dan &lt;code&gt;npm run server&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tool yang dipakai untuk hot reload menggunakan cara yang sudah deprecated.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E3PaPTJn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/a15fyhmwkddooz7wcsgf.png" alt="deprecation"&gt;
&lt;/li&gt;
&lt;li&gt;Untuk tool seperti PostCSS harus ditambahkan pada pipeline terpisah.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Bagian selanjutnya dari artikel ini tidak terlalu penting untuk kamu baca 😁. Kamu bisa lanjut dengan setup standard, atau menggunakan template yang sudah saya buatkan di repositori berikut ini:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/armedi"&gt;
        armedi
      &lt;/a&gt; / &lt;a href="https://github.com/armedi/reason-react-snowpack"&gt;
        reason-react-snowpack
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Starter template for building SPA with ReasonReact, Tailwind CSS, and Snowpack for development
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
ReasonReact with Snowpack Template&lt;/h1&gt;
&lt;p&gt;Included in this template:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;snowpack for development&lt;/li&gt;
&lt;li&gt;webpack for production build&lt;/li&gt;
&lt;li&gt;tailwind css&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Project setup&lt;/h2&gt;
&lt;div class="snippet-clipboard-content position-relative"&gt;
&lt;pre&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;
&lt;div class="zeroclipboard-container position-absolute right-0 top-0"&gt;
  
    
    

    
    

  
&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;
Compiles and hot-reloads for development&lt;/h3&gt;
&lt;div class="snippet-clipboard-content position-relative"&gt;
&lt;pre&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;
&lt;div class="zeroclipboard-container position-absolute right-0 top-0"&gt;
  
    
    

    
    

  
&lt;/div&gt;
&lt;/div&gt;
&lt;h3&gt;
Compiles and minifies for production&lt;/h3&gt;
&lt;div class="snippet-clipboard-content position-relative"&gt;
&lt;pre&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;
&lt;div class="zeroclipboard-container position-absolute right-0 top-0"&gt;
  
    
    

    
    

  
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/armedi/reason-react-snowpack"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Hasil akhir dari percobaan pertama saya menggunakan ReasonReact bisa dilihat di repositori berikut pada branch &lt;code&gt;reason-react&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/armedi"&gt;
        armedi
      &lt;/a&gt; / &lt;a href="https://github.com/armedi/kuy.app"&gt;
        kuy.app
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  Setup Snowpack
&lt;/h2&gt;

&lt;p&gt;Nah selanjutnya dari skeleton yang sudah ada kita akan buat agar bisa menutupi tiga hal yang saya sebutkan diatas.&lt;/p&gt;

&lt;p&gt;Tool yang akan dipakai adalah &lt;a href="https://www.snowpack.dev/"&gt;Snowpack&lt;/a&gt;. Untuk penggunaan development, Snowpack lebih cepat dan ringan dibanding Webpack atau Rollup karena proses yang &lt;em&gt;unbundled&lt;/em&gt; (source files dan dependencies di-&lt;em&gt;serve&lt;/em&gt; tanpa di-&lt;em&gt;bundle&lt;/em&gt;)&lt;/p&gt;

&lt;p&gt;Langkah pertama hapus file dan package yang tidak diperlukan.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm uninstall moduleserve

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; src watcher.js UNUSED_webpack.config.js index.html indexProduction.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kemudian install package-package berikut&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; snowpack @snowpack/plugin-react-refresh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Untuk starting point halaman web, buat file index.html pada folder public&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; public

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;public/index.html

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

&lt;/div&gt;



&lt;p&gt;lalu isi dengan&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;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&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;ReasonReact&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="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/__src__/index.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;Setelah itu buat file konfigurasi snowpack&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;snowpack.config.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;kemudian isi dengan&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;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="na"&gt;mount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;public&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/__src__&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;plugins&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;@snowpack/plugin-react-refresh&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@snowpack/plugin-run-script&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bsb -make-world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$1 -w -ws _&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Selanjutnya buat file src/Index.re sebagai entry point untuk kode Reason&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; src

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;src/Index.re
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;isi dengan&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[@bs.val] external document: Js.t({..}) = "document";

ReactDOMRe.render(
  React.string("Hello ReasonReact!"),
  document##getElementById("root"),
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terakhir, update package.json dan bsconfig.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"snowpack dev"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&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 json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;bsconfig.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"package-specs"&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;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"in-source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="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;Oke, sekarang development environment ReasonReact kita sudah siap digunakan&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>react</category>
      <category>reason</category>
      <category>reasonreact</category>
    </item>
    <item>
      <title>Serverless dengan Cloudflare Workers</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Sat, 03 Oct 2020 06:38:07 +0000</pubDate>
      <link>https://dev.to/armedi/serverless-dengan-cloudflare-workers-568g</link>
      <guid>https://dev.to/armedi/serverless-dengan-cloudflare-workers-568g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;It’s a movement that is defined by empowering developers to single-handedly build apps that handle production level traffic. They don’t have to actively manage scaling their infrastructure. They don't have to provision servers, or pay for resources that go unused. They can just focus on building. &lt;a href="https://www.serverless.com/learn/manifesto/"&gt;https://www.serverless.com/learn/manifesto/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kalau bicara soal &lt;em&gt;traffic handling&lt;/em&gt;, semua developer pasti kenal dengan nama &lt;a href="//cloudflare.com/"&gt;Cloudflare&lt;/a&gt;. Misalnya untuk urusan CDN, data &lt;a href="https://trends.builtwith.com/cdn/Cloudflare"&gt;builtwith.com&lt;/a&gt; menunjukkan bahwa Cloudflare memegang market share terbesar dengan digunakan oleh 45,14% dari top 10k websites. Cloudflare sendiri mengklaim melayani lebih dari 25 juta &lt;em&gt;internet properties&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Dalam bidang serverless computing Cloudflare memiliki &lt;a href="https://workers.cloudflare.com"&gt;Cloudflare Workers&lt;/a&gt; yang men-support secara penuh bahasa pemrograman javascript. &lt;br&gt;
Dibandingkan dengan AWS Lambda, atau Google Cloud Functions, memang product yang ditawarkan oleh Cloudflare ini kalah populer.&lt;/p&gt;

&lt;p&gt;Tapi ada keunikan sendiri yang membedakannya dengan AWS atau Google. Uniknya adalah code javascript tidak &lt;em&gt;running&lt;/em&gt; diatas Node.js, tapi menggunakan &lt;a href="https://developers.cloudflare.com/workers/learning/how-workers-works#isolates"&gt;V8 Isolates&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Dengan model ini tidak ada yang namanya &lt;a href="https://mikhail.io/serverless/coldstarts/aws/"&gt;&lt;em&gt;cold start&lt;/em&gt;&lt;/a&gt;, yaitu ketika request pertama akan memperoleh response yang lambat karena instance membutuhkan waktu untuk "bangun" dari sebelumnya dalam kondisi "tidur" ketika tidak ada request yang masuk dalam rentang waktu tertentu. Dan juga tidak ada pemilihan lokasi seperti di AWS misalnya memilih lokasi &lt;code&gt;ap-southeast-1&lt;/code&gt; untuk data center Singapore.&lt;/p&gt;

&lt;p&gt;Kenapa tidak perlu memilih lokasi? Karena code akan &lt;em&gt;running&lt;/em&gt; di lokasi terdekat dengan user, atau biasa disebut dengan istilah &lt;a href="https://en.wikipedia.org/wiki/Edge_computing"&gt;Edge Computing&lt;/a&gt;. Misalnya jika user datang dari pulau Jawa, maka akan otomatis di-&lt;em&gt;serve&lt;/em&gt; oleh data center Cloudflare yang ada di Jakarta.&lt;/p&gt;

&lt;p&gt;Untuk artikel ini saya membuat ulang url-shortener yang telah saya buat dua minggu yang lalu dengan Netlify redirects.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/armedi" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C3KTG_vi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--P6KIIe04--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/234078/9ae48491-b4ba-4123-9244-96efcedb3f80.jpeg" alt="armedi image"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/armedi/menggunakan-netlify-sebagai-url-shortener-28jc" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Menggunakan Netlify sebagai url shortener&lt;/h2&gt;
      &lt;h3&gt;Armedi ・ Sep 20 '20 ・ 3 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#netlify&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#redirects&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Kali ini menggunakan Cloudflare Worker. Saya tambahkan juga user interface di website &lt;a href="https://kuy.app"&gt;https://kuy.app&lt;/a&gt; sehingga sekarang bisa digunakan oleh siapa saja.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;Dokumentasi lebih detil terdapat di &lt;a href="https://developers.cloudflare.com/workers/learning/getting-started"&gt;Gettting Started&lt;/a&gt; resmi Cloudflare Workers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dash.cloudflare.com/sign-up/workers"&gt;Buat akun&lt;/a&gt; Cloudflare, kemudian di dashboard cloudflare &lt;a href="https://support.cloudflare.com/hc/en-us/articles/201720164-Creating-a-Cloudflare-account-and-adding-a-website"&gt;tambahkan website baru&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install Workers CLI&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @cloudflare/wrangler
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Buat project baru dengan template starter
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   wrangler generate my-worker
   &lt;span class="nb"&gt;cd &lt;/span&gt;my-worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Di dalam folder &lt;code&gt;my-worker&lt;/code&gt; akan terdapat file konfigurasi &lt;code&gt;wrangler.toml&lt;/code&gt; untuk konfigurasi account_id. Dapatkan account_id kamu di dashboard Cloudflare, lalu update file wrangler.toml&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;   &lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"hello"&lt;/span&gt;
   &lt;span class="py"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"javascript"&lt;/span&gt;
   &lt;span class="py"&gt;account_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;your cloudflare account_id&amp;gt;"&lt;/span&gt;
   &lt;span class="py"&gt;workers_dev&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
   &lt;span class="py"&gt;route&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Untuk menjalankan di environment development
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   wrangler dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Development server akan berjalan default di &lt;a href="http://localhost:8787"&gt;http://localhost:8787&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Menghandle Request dengan Cloudflare Worker
&lt;/h3&gt;

&lt;p&gt;Menulis code javascript untuk Cloudflare Workers tidak sama dengan menulis code untuk Node.js, tapi seperti menulis code untuk Service Worker.&lt;/p&gt;

&lt;p&gt;Request yang masuk ke workers akan diterima sebagai event &lt;code&gt;fetch&lt;/code&gt;. Lalu untuk response yang dikirim ke user, dibuat menggunakan object &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Response"&gt;Response&lt;/a&gt; standard dari Web API.&lt;/p&gt;

&lt;p&gt;Hello World dengan Cloudflare Workers:&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;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fetch&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;event&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;respondWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;headers&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;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="s1"&gt;text/plain&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Detil dari request terdapat pada properti &lt;code&gt;event.request&lt;/code&gt; yang juga merupakan object &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Request"&gt;Request&lt;/a&gt; standard dari Web API.&lt;/p&gt;

&lt;p&gt;Jika body request yang masuk adalah berupa data JSON, bisa diparse dengan method &lt;code&gt;.json()&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="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fetch&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;event&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="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;respondWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello world!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;headers&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;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="s1"&gt;text/plain&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&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;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;body&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="c1"&gt;// echo user request&lt;/span&gt;
      &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;respondWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Response&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;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;headers&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;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="s1"&gt;application/json&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Publish ke Cloudflare Workers
&lt;/h2&gt;

&lt;p&gt;Untuk mem-publish gunakan command berikut&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wrangler publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;Nah untuk code yang berkaitan dengan metode url shortening bisa langsung dilihat saja di repository github berikut:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/armedi"&gt;
        armedi
      &lt;/a&gt; / &lt;a href="https://github.com/armedi/kuy.sh"&gt;
        kuy.sh
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Untuk &lt;em&gt;data persistence&lt;/em&gt;, di sini saya menggunakan &lt;a href="https://dashboard.fauna.com/"&gt;faunaDB&lt;/a&gt; yang juga sangat cocok digunakan pada environment serverless.&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>cloudflareworkers</category>
    </item>
    <item>
      <title>Menggunakan Netlify sebagai url shortener</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Sun, 20 Sep 2020 04:18:23 +0000</pubDate>
      <link>https://dev.to/armedi/menggunakan-netlify-sebagai-url-shortener-28jc</link>
      <guid>https://dev.to/armedi/menggunakan-netlify-sebagai-url-shortener-28jc</guid>
      <description>&lt;p&gt;Kamu pasti sudah kenal dengan layanan url shortener seperti &lt;a href="https://bitly.com/"&gt;bit.ly&lt;/a&gt;. Sangat berguna sekali untuk sharing link promosi atau info menarik dengan url yang singkat seperti bit.ly/aBcdE. Lumayan bisa menghemat karakter daripada harus copy paste url aslinya yang panjang.&lt;/p&gt;

&lt;p&gt;Tapi barangkali kamu ingin menggunakan fitur branded link dari bit.ly dengan domain sendiri (misalnya toko.onl/smartphone), namun masih berpikir dua kali karena melihat harga termurahnya adalah $29 per bulan dan harus dibayar langsung untuk 1 tahun sebesar $348.&lt;/p&gt;

&lt;p&gt;Solusi yang jauh lebih murah adalah dengan menggunakan &lt;a href="https://docs.netlify.com/routing/redirects/"&gt;Netlify redirects&lt;/a&gt; yang bisa dipakai gratis. Kamu hanya perlu menyediakan domain saja. Harganya sih variatif, beberapa ada yang bisa diperoleh dengan merogoh kocek kurang dari $10.&lt;/p&gt;

&lt;h5&gt;
  
  
  Step 1: Buat &lt;em&gt;site&lt;/em&gt; baru di Netlify
&lt;/h5&gt;

&lt;p&gt;Hubungkan site yang dibuat dengan repositori di github, agar kamu bisa pakai fitur &lt;a href="https://docs.netlify.com/site-deploys/create-deploys/#deploy-with-git"&gt;Continous Deployment&lt;/a&gt; dari Netlify.&lt;/p&gt;

&lt;h5&gt;
  
  
  Step 2: Sediakan domain
&lt;/h5&gt;

&lt;p&gt;Karena tujuannya buat dipakai sebagai url shortener, sebaiknya beli domain dengan jumlah karakter kurang dari 5 karakter.&lt;/p&gt;

&lt;h5&gt;
  
  
  Step 3: Konfigurasi DNS
&lt;/h5&gt;

&lt;p&gt;Paling gampang adalah dengan menggunakan DNS Netlify. &lt;a href="https://docs.netlify.com/domains-https/netlify-dns/"&gt;Ganti settingan DNS server domain&lt;/a&gt; kamu agar menggunakan DNS server Netlify. Kemudian gunakan domain itu sebagai domain utama untuk &lt;em&gt;site&lt;/em&gt; yang sebelumnya sudah kamu buat.&lt;/p&gt;

&lt;h5&gt;
  
  
  Step 4: Konfigurasi Netlify di local dan buat daftar &lt;em&gt;redirects&lt;/em&gt;
&lt;/h5&gt;

&lt;p&gt;Pada root project, buat sebuah file dengan nama &lt;code&gt;netlify.toml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Isinya cukup seperti ini saja&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[build]&lt;/span&gt;
  &lt;span class="py"&gt;publish&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Lalu masih di root project, buat sebuah file dengan nama &lt;code&gt;_redirects&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;_redirects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Di dalam file ini adalah pasangan short url dan destinasi yang diinginkan. Masing-masing satu baris untuk setiap pasangan url. Ini contoh url yang saya pakai&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/open-source        https://dev.to/armedi/merdeka-dengan-open-source-40d6
/vue-react          https://dev.to/armedi/menggunakan-vue-reactivity-pada-komponen-react-2j08
/alpinejs           https://dev.to/armedi/mencoba-alpine-js-tailwind-for-javascript-5hg6
/tailwindcss        https://dev.to/armedi/tailwind-css-dan-bagaimana-menggunakannya-dengan-create-react-app-7ba
/express-jsx        https://dev.to/armedi/menggunakan-jsx-sebagai-view-engine-express-js-d3o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h5&gt;
  
  
  Step 5: Commit dan push ke github
&lt;/h5&gt;

&lt;p&gt;Kalau sebelumnya sudah sukses menyambungkan repositori github dengan Netlify, maka sekarang Netlify sudah otomatis men-deploy. Proses deployment yang sedang berjalan bisa dipantau dari dashboard Netlify.&lt;/p&gt;

&lt;p&gt;Kalau sudah sukses, artinya sekarang kamu sudah berhasil memiliki url-shortener sendiri. Cek masing-masing short url yang kamu buat apakah sudah benar atau belum. Misalnya short url yang saya buat mengarah ke postingan artikel di dev.to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://kuy.sh/open-source"&gt;kuy.sh/open-source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//kuy.sh/vue-react"&gt;kuy.sh/vue-react&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//kuy.sh/alpinejs"&gt;kuy.sh/alpinejs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//kuy.sh/tailwindcss"&gt;kuy.sh/tailwindcss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="//kuy.sh/express-jsx"&gt;kuy.sh/express-jsx&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;
  
  
  Step 6: Otomasi
&lt;/h5&gt;

&lt;p&gt;Untuk penambahan url-url berikutnya, kalau dilakukan secara manual stepnya cukup banyak dan pasti membosankan&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Buka directory project&lt;/li&gt;
&lt;li&gt;Edit file &lt;code&gt;_redirects&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git commit&lt;/code&gt; perubahan yang dibuat&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git push&lt;/code&gt; ke repository di github&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Untuk mengotomasi itu semua, kita bisa bikin pakai javascript.&lt;/p&gt;

&lt;p&gt;Masih di root project, buat file &lt;code&gt;shorten&lt;/code&gt; (nama file bebas, tidak perlu pakai ekstensi .js)&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;shorten
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x shorten
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Kemudian agar script ini bisa diakses di terminal dari directory mana pun, kita akan buat symlink (command di bawah hanya berlaku di Linux dan Mac)&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nv"&gt;$PWD&lt;/span&gt;/shorten /usr/local/bin/shorten
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Isi scriptnya lebih kurang seperti ini&lt;/p&gt;


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



&lt;p&gt;Sekarang di terminal kamu bisa menyingkat url dengan menggunakan command seperti&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;shorten https://dev.to/armedi/menggunakan-netlify-sebagai-url-shortener-28jc /url-shortener

&lt;span class="c"&gt;# outputnya:&lt;/span&gt;
shorten https://dev.to/armedi/menggunakan-netlify-sebagai-url-shortener-28jc to /url-shortener
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dan sudah otomatis terdeploy di Netlify. Bisa diakses di &lt;a href="https://kuy.sh/url-shortener"&gt;kuy.sh/url-shortener&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kekurangan menggunakan Netlify redirect dibandingkan dengan bit.ly atau sejenis adalah tidak adanya report statistik, misal seberapa sering link diakses. Kalau kamu merasa penting adanya report, mungkin perlu mempertimbangkan untuk membeli layanan berbayar.&lt;/p&gt;

</description>
      <category>netlify</category>
      <category>redirects</category>
    </item>
    <item>
      <title>Menggunakan JSX sebagai view engine Express.js</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Sat, 12 Sep 2020 11:20:25 +0000</pubDate>
      <link>https://dev.to/armedi/menggunakan-jsx-sebagai-view-engine-express-js-d3o</link>
      <guid>https://dev.to/armedi/menggunakan-jsx-sebagai-view-engine-express-js-d3o</guid>
      <description>&lt;p&gt;JSX adalah sebuah ekstensi sintaks javascript. Walaupun dipopulerkan oleh React, tapi JSX tidak sama dengan React. Ada banyak framework lain yang menggunakannya seperti &lt;a href="https://preactjs.com/"&gt;Preact&lt;/a&gt;, &lt;a href="https://infernojs.org/"&gt;Inferno&lt;/a&gt;, dan &lt;a href="https://github.com/ryansolid/solid"&gt;Solid&lt;/a&gt;. Pada artikel kali ini, saya akan pakai JSX sebagai view engine untuk Express.js&lt;/p&gt;

&lt;h3&gt;
  
  
  Kenapa JSX?
&lt;/h3&gt;

&lt;p&gt;Karena pada dasarnya jsx adalah javascript, sehingga semua tools yang tersedia untuk javascript bisa kita pakai untuk membangun UI yang menarik. Kalau butuh satu function tinggal import atau bikin langsung di file yang sama.&lt;/p&gt;

&lt;p&gt;Berbeda sekali dibandingkan menggunakan template engine seperti pug, ejs, nunjucks, dkk. Yang masing-masingnya memiliki sintaks sendiri dan kalau mau menambahkan satu fungsi helper perlu diregistrasikan dulu ke enginenya atau didaftarkan sebagai local variable di express.&lt;/p&gt;

&lt;p&gt;Sebenarnya ada library yang sudah jadi yang menggunakan jsx di expressjs, tapi semuanya depends ke React. Saya ingin sesuatu yang sederhana dan hanya memproduksi plain html. Karena ga ketemu yang cocok, saya putuskan untuk mencoba membuatnya sendiri.&lt;/p&gt;

&lt;p&gt;Setelah membaca halaman &lt;a href="https://expressjs.com/en/advanced/developing-template-engines.html"&gt;&lt;em&gt;Developing template engines for Express&lt;/em&gt;&lt;/a&gt;, saya berkesimpulan sepertinya membuat custom template engine bukan hal yang sulit. Express hanya butuh  disediakan satu callback dengan signature &lt;code&gt;(filePath, options, callback) =&amp;gt; void&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;filePath&lt;/code&gt; adalah lokasi file yang diinvoke dengan &lt;code&gt;res.render&lt;/code&gt;. Misalnya jika diinvoke &lt;code&gt;res.render('index')&lt;/code&gt;, value filePath adalah &lt;code&gt;/absolute/path/to/index.jsx&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;options&lt;/code&gt; adalah value dari parameter kedua &lt;code&gt;res.render&lt;/code&gt; digabung dengan value lain yang disediakan oleh express.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;callback&lt;/code&gt; adalah function yang harus diinvoke dengan hasil rendering dalam bentuk string.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ada satu library bagus yang mengubah jsx element menjadi plain html string yang bisa dipakai sebagai dasar untuk percobaan membuat view engine expressjs. Yaitu &lt;a href="https://github.com/developit/vhtml"&gt;vhtml&lt;/a&gt; yang dibuat oleh creator &lt;a href="https://preactjs.com/"&gt;preact&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Untuk mentransformasi jsx menjadi javascript normal dengan &lt;code&gt;vhtml&lt;/code&gt; function call, kita perlu menggunakan babel dengan plugin &lt;a href="https://babeljs.io/docs/en/babel-plugin-transform-react-jsx"&gt;@babel/plugin-transform-react-jsx&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Berikutnya agar bisa mengimport css dan menggunakan css-in-js, saya tambahkan webpack dengan css-loader. Untuk css-in-js, saya menggunakan &lt;a href="https://github.com/callstack/linaria"&gt;linaria&lt;/a&gt; dengan &lt;a href="https://github.com/callstack/linaria/blob/master/docs/BUNDLERS_INTEGRATION.md#webpack"&gt;linaria/loader&lt;/a&gt; untuk webpack. Dan tentu saja tidak lupa tambahan konfigurasi untuk &lt;a href="https://dev.to/armedi/tailwind-css-dan-bagaimana-menggunakannya-dengan-create-react-app-7ba"&gt;tailwindcss&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Hasil jadi dari percobaan ini bisa diakses di &lt;a href="https://whatsmyip.fly.dev/"&gt;https://whatsmyip.fly.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Seperti inilah code untuk halaman home yang dibuat dengan jsx, dan menggunakan kombinasi linaria + tailwindcss untuk styling. &lt;/p&gt;


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



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


&lt;p&gt;Kenapa saya pakai linaria + tailwind, gak cuma tailwind aja? Karena hasil markup akhir terlihat lebih rapi dengan satu class saja, dan juga lebih gampang untuk mengkombinasikan tailwind dengan custom css yang kita tambahkan sendiri seandainya diperlukan.&lt;/p&gt;


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


&lt;p&gt;Source code lengkapnya tersedia di&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/armedi"&gt;
        armedi
      &lt;/a&gt; / &lt;a href="https://github.com/armedi/express-jsx"&gt;
        express-jsx
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;referensi:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/saltyshiomix/react-ssr"&gt;https://github.com/saltyshiomix/react-ssr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/reactjs/express-react-views"&gt;https://github.com/reactjs/express-react-views&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jsx</category>
      <category>express</category>
    </item>
    <item>
      <title>Tailwind CSS, dan Bagaimana Menggunakannya dengan create-react-app</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Sat, 05 Sep 2020 06:40:40 +0000</pubDate>
      <link>https://dev.to/armedi/tailwind-css-dan-bagaimana-menggunakannya-dengan-create-react-app-7ba</link>
      <guid>https://dev.to/armedi/tailwind-css-dan-bagaimana-menggunakannya-dengan-create-react-app-7ba</guid>
      <description>&lt;p&gt;Ada satu artikel menarik yang dipublikasikan oleh Adam Wathan (pembuat tailwindcss) pada awal bulan agustus lalu (&lt;a href="https://adamwathan.me/tailwindcss-from-side-project-byproduct-to-multi-mullion-dollar-business/"&gt;https://adamwathan.me/tailwindcss-from-side-project-byproduct-to-multi-mullion-dollar-business/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Berawal dari ketidakpuasannya terhadap solusi-solusi yang sudah ada, dia pun membuat framework css sendiri. Awalnya hanya untuk kebutuhan sendiri, tapi kemudian mengundang ketertarikan dari beberapa orang yang ingin berkolaborasi dan menggunakannya juga. Singkat cerita, diputuskanlah project ini menjadi &lt;em&gt;open source&lt;/em&gt; dengan nama Tailwind.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZPQUs5c3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/464/1%2AKPSx2tUY6Pdk9EFT7nL70Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZPQUs5c3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/464/1%2AKPSx2tUY6Pdk9EFT7nL70Q.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sebagai pendukung buat Tailwind CSS, sekitar enam bulan yang lalu tim tailwind merilis &lt;a href="https://tailwindui.com"&gt;Tailwind UI&lt;/a&gt; sebagai project komersil. Dalam waktu 5 bulan saja, pendapatan yang diperoleh hampir mencapai 2 juta dollar (lebih kurang 30 miliar rupiah). Suatu pencapaian yang hebat untuk sesuatu yang berawal dari &lt;em&gt;side project&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Oke, sekarang bagaimana cara pakainya pada aplikasi yang sudah di-&lt;em&gt;bootstrap&lt;/em&gt; dengan create-react-app tanpa harus &lt;em&gt;eject&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Cara yang umum saya temukan pada berbagai tutorial adalah dengan membuat proses tambahan yang terpisah, entah itu dengan postcss-cli atau tailwind cli. Cara ini tidak efisien, karena di dalam create-react-app sudah ada postcss yang harusnya bisa diintegrasikan dengan tailwind.&lt;/p&gt;

&lt;p&gt;Lalu ada juga cara dengan meng-&lt;em&gt;override&lt;/em&gt; konfigurasi standar create-react-app menggunakan tools seperti &lt;a href="https://github.com/timarney/react-app-rewired"&gt;react-app-rewired&lt;/a&gt; atau &lt;a href="https://github.com/gsoft-inc/craco"&gt;craco&lt;/a&gt;. Cara ini bagus, tapi kekurangannya adalah mengharuskan developer mempelajari API-nya terlebih dahulu. Satu hal yang menurut saya tidak perlu kalau perubahan konfigurasi yang dilakukan cukup sederhana, seperti menambahkan tailwind ke dalam postcss.&lt;/p&gt;

&lt;p&gt;Cara yang saya pakai adalah dengan menggunakan &lt;a href="https://github.com/ds300/patch-package"&gt;patch-package&lt;/a&gt; untuk &lt;em&gt;patching&lt;/em&gt; langsung konfigurasi webpack pada react-scripts.&lt;/p&gt;

&lt;p&gt;Pertama siapkan aplikasi react&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init react-app cra-tailwind
&lt;span class="nb"&gt;cd &lt;/span&gt;cra-tailwind
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Berikutnya install tailwind dan patch-package&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;tailwindcss patch-package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Kemudian buka konfigurasi webpack dari react-scripts yang bisa anda temukan di node_modules/react-scripts/config/webpack.config.js. Di dalam file ini cari fungsi getStyleLoader, di dalam fungsi ini akan ada konfigurasi postcss-loader.&lt;/p&gt;

&lt;p&gt;Pada list plugin postcss-loader tambahkan tailwindcss seperti ini:&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;// ...&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="nl"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postcss-loader&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="nl"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tailwindcss&lt;/span&gt;&lt;span class="dl"&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="c1"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Selanjutnya agar perubahan ini bisa direplikasi dan masuk ke &lt;em&gt;source control&lt;/em&gt; seperti git, kita akan menggunakan patch-package. Tambahkan command postinstall pada list scripts di package.json seperti berikut:&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;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-scripts start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-scripts build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-scripts test"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"react-scripts eject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"postinstall"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"patch-package"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Lalu karena kita sebelumnya sudah melakukan patching pada react-scripts, jalankan command ini di terminal&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx patch-package react-scripts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Outputnya lebih kurang seperti berikut&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;patch-package 6.2.2
• Creating temporary folder
• Installing react-scripts@3.4.3 with npm
• Diffing your files with clean files
✔ Created file patches/react-scripts+3.4.3.patch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;patch-package akan membuat folder patches yang di dalamnya berisikan semua &lt;em&gt;override&lt;/em&gt; yang sudah dilakukan. Pada case ini kita telah meng-&lt;em&gt;override&lt;/em&gt; react-scripts.&lt;/p&gt;

&lt;p&gt;Langkah terakhir, update file src/index.css dengan tailwind&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Sekarang untuk memastikan konfigurasi kita sudah berjalan dengan benar, saya coba tambahkan class text-red-500 untuk text di App.js. Hasilnya:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kIJSZd2F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AulP7AwmxuE-CgmVhXNKAOQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kIJSZd2F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AulP7AwmxuE-CgmVhXNKAOQ.png" alt=""&gt;&lt;/a&gt;teks sudah berubah menjadi warna merah&lt;/p&gt;

&lt;p&gt;Anda bisa menambahkan file tailwind.config.js untuk kustomisasi lebih lanjut. Konfigurasi minimal yang saya pakai adalah&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;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="na"&gt;purge&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;./src/&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;*/&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;*.js&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;./src/&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;*&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;*/&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s1"&gt;*.jsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;extend&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;variants&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Kode lengkap dari contoh ini bisa anda temukan di &lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/armedi"&gt;
        armedi
      &lt;/a&gt; / &lt;a href="https://github.com/armedi/cra-tailwind"&gt;
        cra-tailwind
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Semoga berguna!!!&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>opensource</category>
      <category>react</category>
    </item>
    <item>
      <title>Mencoba Alpine.js, Tailwind for Javascript</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Sun, 30 Aug 2020 05:45:11 +0000</pubDate>
      <link>https://dev.to/armedi/mencoba-alpine-js-tailwind-for-javascript-5hg6</link>
      <guid>https://dev.to/armedi/mencoba-alpine-js-tailwind-for-javascript-5hg6</guid>
      <description>&lt;p&gt;Di tengah popularitas &lt;em&gt;frontend libraries&lt;/em&gt; seperti &lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt;, &lt;a href="https://vuejs.org/"&gt;Vue&lt;/a&gt;, atau &lt;a href="https://svelte.dev/"&gt;Svelte&lt;/a&gt; yang sekarang sedang naik daun, ada satu &lt;em&gt;library&lt;/em&gt; yang relatif masih baru, yaitu &lt;a href="https://github.com/alpinejs/alpine"&gt;Alpine.js&lt;/a&gt;. Versi 1.0.0-nya rilis pada Desember 2019, belum genap setahun yang lalu.&lt;/p&gt;

&lt;p&gt;Barangkali pertanyaan yang muncul adalah apa kita masih perlu &lt;em&gt;library&lt;/em&gt; baru lagi? Bukannya sekarang udah kebanyakan library? Ya, selain tiga nama populer yang saya sebutkan diatas masih ada lagi nama-nama seperti &lt;a href="https://angular.io/"&gt;Angular&lt;/a&gt;, &lt;a href="https://emberjs.com/"&gt;Ember.js&lt;/a&gt;, &lt;a href="https://preactjs.com/"&gt;Preact&lt;/a&gt;, dan masih banyak lagi yang lainnya.&lt;/p&gt;

&lt;p&gt;Tidak ada salahnya mencoba dan mempelajari library baru. Bisa jadi cocok untuk dipakai pada kasus-kasus tertentu yang akan datang nantinya. Karena tidak semua &lt;em&gt;project&lt;/em&gt; harus dikerjakan dengan React atau Vue. Mungkin saja ada yang lebih cocok dengan solusi dari &lt;em&gt;library&lt;/em&gt; yang lebih sederhana, atau bahkan tanpa &lt;em&gt;library&lt;/em&gt; tambahan sama sekali.&lt;/p&gt;

&lt;p&gt;Sebagai pembeda dengan yang lain, Alpine.js menawarkan ukuran yang kecil (8 kB minified + gzipped), dan kemudahan penggunaan. Dengan Alpine.js, anda bisa membuat website interaktif tanpa harus menulis javascript sama sekali. Membuat dan memanipulasi state, semuanya bisa dilakukan langsung pada &lt;em&gt;markup&lt;/em&gt; html. Makanya di repositorinya disebut bahwa Alpine.js ini seperti &lt;a href="https://tailwindcss.com/"&gt;tailwind&lt;/a&gt; tapi untuk javascript.&lt;/p&gt;

&lt;p&gt;Sintaksnya sangat mirip dengan Vue. Anda yang sudah terbiasa menggunakan &lt;em&gt;v-bind&lt;/em&gt;, &lt;em&gt;v-model&lt;/em&gt;, dan &lt;em&gt;v-on&lt;/em&gt; di Vue, akan menemukan &lt;em&gt;directives&lt;/em&gt; yang sama di Alpine.js, tinggal mengganti v-* dengan x-*. Bedanya di Alpine.js deklarasi data juga dilakukan pada markup dengan menggunakan &lt;em&gt;directive&lt;/em&gt; x-data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;x-data=&lt;/span&gt;&lt;span class="s"&gt;"{ open: false }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click=&lt;/span&gt;&lt;span class="s"&gt;"open = true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Open Dropdown&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;x-show=&lt;/span&gt;&lt;span class="s"&gt;"open"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click.away=&lt;/span&gt;&lt;span class="s"&gt;"open = false"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Dropdown Body
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Contoh di atas saya ambil dari dokumentasi Alpine.js, dan saya yakin sintaksnya akan langsung dipahami oleh yang pernah mencoba Vue.&lt;/p&gt;

&lt;p&gt;Saya pun mencoba membuat sebuah web sederhana menggunakan Alpine.js untuk menampilkan list pokemon serta dilengkapi fitur pencarian berdasarkan nama dan tipe monster. Sumber data dari &lt;a href="https://pokeapi.co/"&gt;https://pokeapi.co/&lt;/a&gt; yang sudah saya &lt;em&gt;fetch&lt;/em&gt; terlebih dahulu dan diolah menjadi sebuah file json. Data pokemon ini dipilih karena populer dan jumlah itemnya cukup banyak (1048 item dari pokeapi.co), sehingga cocok kalau ditambahkan fitur pencarian.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dhfJeEDt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/926/1%2ASs6Fmj0f4XDz_I1P0pFTPg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dhfJeEDt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/926/1%2ASs6Fmj0f4XDz_I1P0pFTPg.png" alt=""&gt;&lt;/a&gt;markup + css (tailwind) + alpine, total hanya 12.8 kB&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/armedi"&gt;
        armedi
      &lt;/a&gt; / &lt;a href="https://github.com/armedi/pokedex-alpinejs"&gt;
        pokedex-alpinejs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Live _website-_nya bisa diakses di &lt;a href="https://pokedex-alpinejs.netlify.app/"&gt;https://pokedex-alpinejs.netlify.app/&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Kesimpulan
&lt;/h4&gt;

&lt;p&gt;Setelah sedikit bermain-main dan eksplorasi apa saja yang ditawarkan oleh Alpine.js, kesimpulan saya adalah library ini cocok dipakai untuk membuat halaman web yang membutuhkan sedikit tambahan interaktifitas seperti mengubah-ubah state &lt;em&gt;active tab&lt;/em&gt; atau untuk &lt;em&gt;toggling&lt;/em&gt; &lt;em&gt;on&lt;/em&gt; dan &lt;em&gt;off&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Untuk kebutuhan yang lebih kompleks dan aplikasi yang lebih besar, mungkin anda perlu mempertimbangkan untuk menggunakan library yang lebih advance seperti React atau Vue.&lt;/p&gt;

</description>
      <category>alpinejs</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Menggunakan Vue Reactivity pada Komponen React</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Sun, 23 Aug 2020 02:08:49 +0000</pubDate>
      <link>https://dev.to/armedi/menggunakan-vue-reactivity-pada-komponen-react-2j08</link>
      <guid>https://dev.to/armedi/menggunakan-vue-reactivity-pada-komponen-react-2j08</guid>
      <description>&lt;p&gt;Bagi anda yang berkecimpung di dunia &lt;em&gt;frontend web development&lt;/em&gt;, pasti sudah tidak asing dengan nama React atau Vue. Dua &lt;em&gt;library&lt;/em&gt; yang paling populer saat ini untuk membangun aplikasi web modern.&lt;/p&gt;

&lt;p&gt;Para penggemar framework Vue pun pastinya sudah tahu bahwa tidak lama lagi Vue akan merilis versi 3. Versi baru ini tidak hanya menambahkan fitur baru, tapi benar-benar &lt;em&gt;rewrite&lt;/em&gt; dari awal (Lebih lanjut: &lt;a href="https://increment.com/frontend/making-vue-3/"&gt;https://increment.com/frontend/making-vue-3/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Salah satu fitur baru di Vue 3 yang mungkin paling banyak disorot adalah &lt;a href="https://vue-composition-api-rfc.netlify.app"&gt;&lt;em&gt;Composition API&lt;/em&gt;&lt;/a&gt; (Tutorial cara menggunakan &lt;em&gt;Composition API&lt;/em&gt; pernah dibuat oleh teman saya Semmi Verian di &lt;a href="https://www.youtube.com/watch?v=8vpKtJqdJMI"&gt;video youtube&lt;/a&gt;-nya). Namun hal yang lebih menarik bagi saya pribadi adalah model reaktivitas baru yang sama sekali berbeda dengan versi sebelumnya.&lt;/p&gt;

&lt;p&gt;Lebih menariknya lagi, modul reaktivitas ini dibuat pada &lt;em&gt;package&lt;/em&gt; terpisah, yang artinya tentu saja bisa kita pakai pada aplikasi lain tanpa harus menggunakan framework Vue.&lt;/p&gt;

&lt;p&gt;Nah karena saya sama-sama menyukai React dan Vue, jadi saya memutuskan untuk mencoba modul &lt;a href="https://www.npmjs.com/package/@vue/reactivity"&gt;@vue/reactivity&lt;/a&gt; pada aplikasi yang dibuat menggunakan React.&lt;/p&gt;

&lt;p&gt;Tujuan akhir dari tulisan ini adalah membahas bagaimana kita bisa &lt;strong&gt;memutasi data&lt;/strong&gt; tanpa kehilangan reaktivitas dari React dengan menggunakan &lt;em&gt;package&lt;/em&gt; @vue/reactivity. Cara seperti ini bukanlah hal baru, tapi juga digunakan oleh library seperti &lt;a href="https://mobx-react.js.org/"&gt;mobx-react&lt;/a&gt; (dengan observable dari mobx).&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Mutable VS Immutable&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Mutability&lt;/em&gt; adalah perbedaan mendasar antara React dengan Vue. React memilih jalur full &lt;em&gt;immutable data&lt;/em&gt;, sedangkan Vue memilih jalur &lt;em&gt;mutable data.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Lalu apa perbedaannya?&lt;/p&gt;

&lt;p&gt;Sebelumnya kita bahas dulu sedikit tentang &lt;em&gt;declarative programming.&lt;/em&gt; Dengan library atau framework modern, &lt;em&gt;web&lt;/em&gt; &lt;em&gt;developer&lt;/em&gt; tidak lagi perlu memikirkan bagaimana meng-&lt;em&gt;update&lt;/em&gt; DOM. Cukup dengan mendeklarasikan apa yang dimau, selebihnya mengenai proses &lt;em&gt;update&lt;/em&gt; DOM dan bagaimana terjadinya akan diatur oleh &lt;em&gt;library&lt;/em&gt; yang dipakai (&lt;a href="https://dev.to/tylermcginnis/imperative-vs-declarative-programming-2hff-temp-slug-3677542"&gt;Artikel ini&lt;/a&gt; menjelaskannya dengan lebih baik).&lt;/p&gt;

&lt;p&gt;React atau Vue akan mendeteksi perubahan data, dan kemudian melakukan perubahan yang sesuai pada UI. Dan ini terjadi terus-menerus secara otomatis. Atau dalam kata lain, komponen UI bersifat reaktif terhadap perubahan data.&lt;/p&gt;

&lt;p&gt;Nah, di sini lah perbedaan antara &lt;em&gt;immutability&lt;/em&gt;-nya React dengan &lt;em&gt;mutability&lt;/em&gt; Vue. React dengan cara yang sangat sederhana mendeteksi perubahan data menggunakan &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"&gt;Object.is&lt;/a&gt;. Itulah mengapa kode di bawah tidak akan berjalan sesuai yang diharapkan.&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 react component&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;last&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Doe&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;handleChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Ketika anda melakukan mutasi terhadap data nameseperti kode diatas, React tidak akan melihat perubahan, sehingga &lt;em&gt;rerender&lt;/em&gt; pun tidak akan pernah terjadi. Karena &lt;em&gt;object&lt;/em&gt; name masih merupakan &lt;em&gt;object&lt;/em&gt; yang sama dengan sebelumnya.&lt;/p&gt;

&lt;p&gt;Vue menggunakan cara berbeda yang lebih kompleks untuk mendeteksi perubahan data (lebih jelasnya bisa disimak langsung di &lt;a href="https://v3.vuejs.org/guide/reactivity.html#how-vue-tracks-these-changes"&gt;dokumentasi resminya&lt;/a&gt;). Intinya adalah data pada Vue bisa dimutasi, dan dengan cerdas Vue akan mendeteksi perubahan kemudian melakukan update yang sesuai.&lt;/p&gt;
&lt;h4&gt;
  
  
  Let’s start playing
&lt;/h4&gt;

&lt;p&gt;Aplikasi yang akan kita buat adalah aplikasi &lt;em&gt;counter&lt;/em&gt; dengan fitur &lt;em&gt;increment&lt;/em&gt; dan &lt;em&gt;decrement&lt;/em&gt;, serta ada satu kolom input teks.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Scroll ke paling bawah jika anda mau langsung melihat source code dan hasil jadinya&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @vue/reactivity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Pertama kita akan buat sebuah fungsi HOC bernama &lt;strong&gt;setup&lt;/strong&gt; yang lebih kurang berfungsi sama dengan setup pada &lt;em&gt;composition API&lt;/em&gt; Vue. Penggunaanya akan seperti ini:&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;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vue/reactivity&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;setup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setupFn&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;Component&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;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setupProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setupFn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="c1"&gt;// our little trick here&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;setupProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// This is the react component&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;setup&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;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;first&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;})(&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Fungsi setup akan memasukkan &lt;em&gt;return value&lt;/em&gt; dari setupFn sebagai props pada komponen. Di sini kita gunakan useMemo agar invokasi hanya terjadi sekali ketika &lt;em&gt;mounting&lt;/em&gt; saja.&lt;/p&gt;

&lt;p&gt;Nah, sekarang bagaimana caranya untuk “memaksa” komponen agar rerender ketika props ini dimutasi?&lt;/p&gt;

&lt;p&gt;@vue/reactivity menyediakan fungsi &lt;strong&gt;effect&lt;/strong&gt; yang fungsinya adalah melakukan “sesuatu” (dengan meng-&lt;em&gt;invoke&lt;/em&gt; &lt;em&gt;callback&lt;/em&gt; yang diberikan) setiap kali value reaktif yang dipakai di dalam fungsi itu dimutasi. Fungsi effect ini akan kita tempatkan di dalam hooks useEffect React. Jangan lupa untuk menghentikan effect ketika komponen di-&lt;em&gt;unmout&lt;/em&gt; dengan me-&lt;em&gt;return&lt;/em&gt; sebuah fungsi untuk stop.&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;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stop&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vue/reactivity&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;setup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setupFn&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;Component&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;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setupProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setupFn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&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;reactiveEffect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;effect&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="c1"&gt;// here we can do something to trigger rerender&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reactiveEffect&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;setupProps&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;setupProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Untuk “memaksa” &lt;em&gt;rerender&lt;/em&gt; kita akan buat satu state yang &lt;em&gt;value&lt;/em&gt;-nya akan di-&lt;em&gt;update&lt;/em&gt; ketika terjadi mutasi data.&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;setup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setupFn&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;Component&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;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setupProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setupFn&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="p"&gt;[,&lt;/span&gt; &lt;span class="nx"&gt;setTick&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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;useEffect&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;reactiveEffect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;effect&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="c1"&gt;// Only one more thing to do here&lt;/span&gt;
      &lt;span class="nx"&gt;setTick&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tick&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;tick&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&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;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reactiveEffect&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;setupProps&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;setupProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Oke, tinggal satu langkah lagi&lt;/p&gt;

&lt;p&gt;Sebelumnya saya katakan bahwa fungsi effect akan meng-&lt;em&gt;invoke callback&lt;/em&gt; yang diberikan setiap kali &lt;em&gt;value&lt;/em&gt; reaktif yang dipakai di dalam fungsi itu dimutasi. Terus bagaimana caranya fungsi ini tau ada mutasi?&lt;/p&gt;

&lt;p&gt;Sangat sederhana sekali. Setiap value yang diakses di dalamnya akan secara otomatis di-&lt;em&gt;track.&lt;/em&gt; Ya, cukup diakses saja!&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;useEffect&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;reactiveEffect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;effect&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;setupProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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;setupProps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;setTick&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tick&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;tick&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&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;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reactiveEffect&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;setupProps&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Karena di dalam komponen kita akan menggunakan value count dan name.first, dua value ini perlu diakses terlebih dahulu di dalam fungsi effect agar komponen bisa melacak mutasi dan melakukan &lt;em&gt;rerender&lt;/em&gt; setiap kali ada perubahan.&lt;/p&gt;

&lt;p&gt;Oke, cara diatas sebenarnya sudah “benar”. Tapi akan mengakibatkan error no-unused-expressions pada linter, dan juga membuat fungsi setup hanya bisa dipakai untuk satu komponen ini saja.&lt;/p&gt;

&lt;p&gt;Sekarang mari kita generalisasi menjadi fungsi &lt;strong&gt;access&lt;/strong&gt; yang secara rekursif akan mengakses setiap properti di dalam object&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;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;reactive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stop&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@vue/reactivity&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;access&lt;/span&gt; &lt;span class="o"&gt;=&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="o"&gt;=&amp;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;isRef&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;access&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="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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&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="k"&gt;for&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;key&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&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;object&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;access&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="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;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setupFn&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;Component&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;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setupProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setupFn&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="p"&gt;[,&lt;/span&gt; &lt;span class="nx"&gt;setTick&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&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;useEffect&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;reactiveEffect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;effect&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;access&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setupProps&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;setTick&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tick&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;tick&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&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;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reactiveEffect&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;setupProps&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;setupProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Akhirnya sekarang di dalam komponen React kita bisa melakukan update data dengan cara memutasinya seperti dibawah ini. Perhatikan onChange pada input dan onClick pada button.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;
        &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Input your name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;first&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;count&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;onClick&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="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nx"&gt;Decrement&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;onClick&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="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nx"&gt;Increment&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Dari sini anda bisa lanjutkan bereksperimen untuk membuat &lt;em&gt;global state management&lt;/em&gt; menggunakan modul &lt;em&gt;reactivity&lt;/em&gt; dari Vue&lt;/p&gt;

&lt;p&gt;&lt;em&gt;source code&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/armedi"&gt;
        armedi
      &lt;/a&gt; / &lt;a href="https://github.com/armedi/vue-reactivity-in-react-example"&gt;
        vue-reactivity-in-react-example
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;&lt;em&gt;codesandbox&lt;/em&gt;:&lt;br&gt;
&lt;iframe src="https://codesandbox.io/embed/kww7z?initialpath=/src/App.jsx"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>react</category>
      <category>vue3</category>
      <category>vuecompositionapi</category>
      <category>vueinreact</category>
    </item>
    <item>
      <title>Merdeka dengan Open Source</title>
      <dc:creator>Armedi</dc:creator>
      <pubDate>Thu, 20 Aug 2020 02:28:38 +0000</pubDate>
      <link>https://dev.to/armedi/merdeka-dengan-open-source-40d6</link>
      <guid>https://dev.to/armedi/merdeka-dengan-open-source-40d6</guid>
      <description>&lt;p&gt;Belum lama ini saya memulai pekerjaan baru di &lt;a href="https://hyperjump.tech/"&gt;Hyperjump Technology&lt;/a&gt;. Ada 2 hal penting yang membuat saya pada akhirnya memutuskan memilih bergabung dengan Hyperjump dan menolak beberapa tawaran pekerjaan lain yang datang lebih dahulu:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Programming excellence&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Open source first&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tapi untuk tulisan ini saya akan bahas poin 2 saja&lt;/p&gt;

&lt;h3&gt;
  
  
  Open source first
&lt;/h3&gt;

&lt;p&gt;Kalimat di atas bukanlah sekedar slogan yang belum ada implementasinya.&lt;/p&gt;

&lt;p&gt;Bahkan dari sebelum berdirinya, pendiri perusahaan ini sudah sangat dikenal dalam komunitas &lt;em&gt;open source&lt;/em&gt; internasional sebagai punggawa proyek-proyek &lt;em&gt;open source&lt;/em&gt; besar yang dikenal luas di mancanegara.&lt;/p&gt;

&lt;p&gt;Hyperjump sendiri sebagai sebuah perusahaan telah mencetuskan beberapa proyek &lt;em&gt;open source&lt;/em&gt; yang bisa anda pantau di akun &lt;a href="https://github.com/hyperjumptech"&gt;&lt;em&gt;github&lt;/em&gt;&lt;/a&gt;-nya.&lt;/p&gt;

&lt;p&gt;Disini kami sangat didorong untuk tidak hanya sebagai pengguna &lt;em&gt;open source&lt;/em&gt; tapi melangkah lebih dari itu juga sebagai kontributor aktif dalam dunia &lt;em&gt;open source&lt;/em&gt;. Dengan &lt;em&gt;open source&lt;/em&gt;, tidak hanya kita bisa saling membantu dalam menyelesaikan masalah-masalah umum yang sering dihadapi, tapi juga dengan sendirinya kualitas kodingan akan meningkat. Karena pastinya tidak ada yang mau merilis sesuatu ke hadapan publik sebelum diyakini bahwa apa yang dibuat itu sudah cukup baik kualitasnya.&lt;/p&gt;

&lt;h3&gt;
  
  
  17 Agustus 2020
&lt;/h3&gt;

&lt;p&gt;Pada tanggal ini kita rakyat Indonesia merayakan hari kemerdekaan yang ke-75. Namun karena masih dalam pandemi &lt;em&gt;covid-19,&lt;/em&gt; suasana tahun ini tidaklah sesemarak tahun-tahun sebelumnya. Perlombaan-perlombaan yang menimbulkan keramaian pun sangatlah tidak dianjurkan.&lt;/p&gt;

&lt;p&gt;Dalam suasana inilah saya kemudian terpikir membuat sesuatu dengan semangat &lt;em&gt;open source&lt;/em&gt; dan kira-kira bisa berguna khususnya untuk programmer-programmer Indonesia.&lt;/p&gt;

&lt;p&gt;Kemudian saya terpikir ada satu hal kecil yang cukup sering saya lakukan, yaitu memformat tanggal ke bahasa Indonesia dalam bahasa pemrograman &lt;em&gt;javascript&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Solusi yang paling dikenal saat ini adalah &lt;a href="https://momentjs.com/"&gt;momentjs&lt;/a&gt;, &lt;em&gt;library&lt;/em&gt; ini juga salah satu &lt;em&gt;top package&lt;/em&gt; yang paling sering di-&lt;em&gt;download&lt;/em&gt; dari repositori npm. Tapi kalau hanya digunakan untuk memformat tanggal saja saya rasa ini &lt;em&gt;overkill.&lt;/em&gt; &lt;em&gt;Library&lt;/em&gt; ini berukuran cukup besar dengan sangat lengkapnya fitur yang tersedia. Kalau dipasang untuk frontend website, akan menambah &lt;em&gt;bundle size&lt;/em&gt; aplikasi yang dibuat secara cukup signifikan.&lt;/p&gt;

&lt;p&gt;Oleh karena itu, saya membuat sebuah &lt;em&gt;library&lt;/em&gt; baru dengan nama &lt;a href="https://www.npmjs.com/package/masa"&gt;&lt;strong&gt;masa&lt;/strong&gt;&lt;/a&gt;. Masa adalah hasil dari membaca &lt;em&gt;source code&lt;/em&gt; momentjs, dan kemudian saya sederhanakan (sebagiannya adalah &lt;em&gt;copy-paste&lt;/em&gt;) untuk satu fungsi saja, yaitu untuk memformat tanggal ke dalam bahasa Indonesia. Cara pakainya pun lebih kurang sama seperti cara pakai momentjs untuk memformat tanggal.&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;masa&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;masa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;masa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2020-08-17&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[hari] dddd, [tanggal] D MMMM YYYY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// hari Senin, tanggal 17 Agustus 2020&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Lebih lengkapnya mengenai cara penggunaan beserta &lt;em&gt;source code&lt;/em&gt;-nya bisa anda lihat di &lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3JOwpme--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/armedi"&gt;
        armedi
      &lt;/a&gt; / &lt;a href="https://github.com/armedi/masa"&gt;
        masa
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Semoga berguna!!!&lt;/p&gt;




</description>
      <category>merdeka</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
