{"id":278,"date":"2022-04-17T06:37:51","date_gmt":"2022-04-17T06:37:51","guid":{"rendered":"https:\/\/sentraldigitalindonesia.co.id\/blog\/2022\/04\/17\/javascript-module-dan-keribetannya-mazipan-space\/"},"modified":"2022-04-17T06:39:10","modified_gmt":"2022-04-17T06:39:10","slug":"javascript-module-dan-keribetannya-mazipan-space","status":"publish","type":"post","link":"https:\/\/sentraldigitalindonesia.co.id\/blog\/2022\/04\/17\/javascript-module-dan-keribetannya-mazipan-space\/","title":{"rendered":"JavaScript Module dan keribetannya"},"content":{"rendered":"<div>\n<div>\n<p>Hal yang lucu ketika sebuah bahasa pemrograman sebesar JavaScript ternyata memiliki variasi dalam penerapan <em>module system<\/em>. Sebelum membaca lebih jauh, mari kita bahas bersama dahulu apa itu <em>module system<\/em> dan bagaimana seluk-beluknya di JavaScript hingga hari ini.<\/p>\n<h2>Apa itu module system?<\/h2>\n<p><strong>Module System<\/strong> adalah sebuah cara bagi bahasa pemrograman agar bisa menerapkan isolasi kode dari satu file terhadap file lain, serta memudahkan untuk menyertakan kode dari file lain ke dalam file yang membutuhkannya.<\/p>\n<p>Ini adalah sistem yang sudah sangat jamak di berbagai bahasa pemrograman. Bukan barang baru, bukan juga barang mewah. Module System biasanya sudah diatur oleh bahasa itu sendiri sehingga tidak diperlukan lagi persepsi tambahan dari komunitas dan berbagai pihak dalam menerapkan <em>module system<\/em> di dalam suatu bahasa.<\/p>\n<p>Sebelum masuk ke JavaScript, mari kita tengok ke bahasa bapaknya JavaScript, yakni Java. Agar kita bisa belajar bagaimana Java menerapkan <em>module system<\/em>.<\/p>\n<p>Di Java, untuk menggunakan kode dari file lain baik standar dari Java maupun dari pihak lain bisa semudah dengan menambahkan <code>import<\/code> terhadap <em>package<\/em> yang dibutuhkan, contoh kodenya:<\/p>\n<pre data-lang=\"java\"><code><span><span>import<\/span><span> java.util.ArrayList;<\/span><\/span>\n<span><\/span>\n<span><span>class<\/span><span> <\/span><span>ArrayListUtilization<\/span><span> {<\/span><\/span>\n<span><span>  <\/span><span>public<\/span><span> <\/span><span>static<\/span><span> <\/span><span>void<\/span><span> <\/span><span>main<\/span><span>(<\/span><span>String<\/span><span>[] <\/span><span>args<\/span><span>) {<\/span><\/span>\n<span><span>    <\/span><span>ArrayList<\/span><span><integer> myList <\/integer><\/span><span>=<\/span><span> <\/span><span>new<\/span><span> <\/span><span>ArrayList<\/span><span>&lt;&gt;(<\/span><span>3<\/span><span>);<\/span><\/span>\n<span><span>    myList.<\/span><span>add<\/span><span>(<\/span><span>3<\/span><span>);<\/span><\/span>\n<span><span>    myList.<\/span><span>add<\/span><span>(<\/span><span>2<\/span><span>);<\/span><\/span>\n<span><span>    myList.<\/span><span>add<\/span><span>(<\/span><span>1<\/span><span>);<\/span><\/span>\n<span><span>    System.out.<\/span><span>println<\/span><span>(myList);<\/span><\/span>\n<span><span>  }<\/span><\/span>\n<span><span>}<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Kalian bisa melihat potongan kode <code>import java.util.ArrayList;<\/code> pada baris paling atas, kode tersebut menandakan kalau di bawahnya kita akan menggunakan kode yang berasal dari <em>package<\/em> bersangkutan, dalam kasus ini ya <code>ArrayList<\/code>.<br \/>\nTidak perlu bingung atau khawatir bagaimana cara menghafal nama-nama <em>package<\/em> tersebut, di Java sebagian besar waktu koding bisa dipangkas karena dukungan IDE (<em>Integrated Development Environment<\/em>) yang memang sudah sangat baik.<\/p>\n<p>Cara <em>import<\/em> seperti di atas sudah menjadi standar di Java, tidak perlu lagi ada cara lain yang membuat hal sederhana malahan menjadi membingungkan.<\/p>\n<p>Berbicara soal bagaimana cara isolasi kode, dengan dukungan <strong>Class System<\/strong>-nya, di Java bukanlah barang susah.<br \/>\nIni ibarat kata, anak yang baru belajar Java pun seharusnya tahu bagaimana cara membuatnya.<br \/>\nMari kita lihat contoh kode berikut:<\/p>\n<pre data-lang=\"java\"><code><span><span>public<\/span><span> <\/span><span>class<\/span><span> <\/span><span>Person<\/span><span> {<\/span><\/span>\n<span><span>  <\/span><span>private<\/span><span> <\/span><span>String<\/span><span> firstName;<\/span><\/span>\n<span><span>  <\/span><span>private<\/span><span> <\/span><span>String<\/span><span> lastName;<\/span><\/span>\n<span><\/span>\n<span><span>  <\/span><span>public<\/span><span> <\/span><span>String<\/span><span> <\/span><span>getFirstName<\/span><span>() {<\/span><\/span>\n<span><span>    <\/span><span>return<\/span><span> firstName;<\/span><\/span>\n<span><span>  }<\/span><\/span>\n<span><\/span>\n<span><span>  <\/span><span>public<\/span><span> <\/span><span>String<\/span><span> <\/span><span>getLastName<\/span><span>() {<\/span><\/span>\n<span><span>    <\/span><span>return<\/span><span> lastName;<\/span><\/span>\n<span><span>  }<\/span><\/span>\n<span><span>}<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Kode di atas adalah contoh <strong>POJO<\/strong> (<em>Plain Old Java Object<\/em>) yakni objek entitas biasa tanpa ada tambahan logika bisnis di dalamnya.<br \/>\nDari kode tersebut di atas, kita sudah jelas tidak bisa mengakses properti <code>firstName<\/code> karena memang dibuat sebagai <em>private<\/em> sehingga hanya bisa diakses lewat internal Class itu sendiri.<br \/>\nUntuk mengambil nilai dari <code>firstName<\/code> maka dibuatlah <code>getters<\/code> untuk properti ini yakni <code>getFirstName<\/code> yang mana dibuat agar bisa diakses dari luar.<\/p>\n<p>Setelah berkaca pada Java, mari kita bawa arah tulisan ini agar spesifik pada bahasa yang menjadi idola para remaja yakni JavaScript.<\/p>\n<h2>Sebelum ada module system<\/h2>\n<p>JavaScript sudah ada sejak lama, namun karena memang sejak lama kode JavaScript biasanya tidak begitu besar, jadi dukungan <em>Module System<\/em> tidak ada sedari dulu sampai belakangan ini.<br \/>\nKalau tidak ada <em>Module System<\/em> apakah JavaScript tidak bisa melakukan dua hal yang kita bahas di atas sebelumnya?<br \/>\nJawabnya, tentu saja bisa. Tapi ya butuh perjuangan yang lebih susah pastinya.<\/p>\n<p>Jaman dulu, ketika JavaScript hanya bisa jalan di browser, satu-satunya cara untuk menyematkan suatu file ke dalam file lain adalah memanfaatkan kemampuan browser itu sendiri dalam memuat sebuah file JavaScript.<\/p>\n<p>Mari kita lihat kode berikut:<\/p>\n<pre data-lang=\"html\"><code><span><span><!--<\/span--><span>DOCTYPE<\/span><span> <\/span><span>html<\/span><span>&gt;<\/span><\/span>\n<span><span>&lt;<\/span><span>html<\/span><span> <\/span><span>lang<\/span><span>=<\/span><span>\"<\/span><span>en<\/span><span>\"<\/span><span>&gt;<\/span><\/span>\n<span><span>  &lt;<\/span><span>head<\/span><span>&gt;<\/span><\/span>\n<span><span>    &lt;<\/span><span>meta<\/span><span> <\/span><span>charset<\/span><span>=<\/span><span>\"<\/span><span>utf-8<\/span><span>\"<\/span><span> \/&gt;<\/span><\/span>\n<span><span>    &lt;<\/span><span>title<\/span><span>&gt;JavaScript<!--<\/span--><span>title<\/span><span>&gt;<\/span><\/span>\n<span><span>  <!--<\/span--><span>head<\/span><span>&gt;<\/span><\/span>\n<span><span>  &lt;<\/span><span>body<\/span><span>&gt;<\/span><\/span>\n<span><span>    &lt;<\/span><span>script<\/span><span> <\/span><span>src<\/span><span>=<\/span><span>\"<\/span><span>https:\/\/mazipan.space\/file-1.js<\/span><span>\"<\/span><span>&gt;<!--<\/span--><span>script<\/span><span>&gt;<\/span><\/span>\n<span><span>    &lt;<\/span><span>script<\/span><span> <\/span><span>src<\/span><span>=<\/span><span>\"<\/span><span>.\/file-2.js<\/span><span>\"<\/span><span>&gt;<!--<\/span--><span>script<\/span><span>&gt;<\/span><\/span>\n<span><span>  <!--<\/span--><span>body<\/span><span>&gt;<\/span><\/span>\n<span><span><!--<\/span--><span>html<\/span><span>&gt;<\/span><\/span>\n<span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/code><\/pre>\n<p>Kode diatas adalah cara kita dulu memanfaatkan browser untuk saling menyematkan satu file dengan file lainnya.<br \/>\nKita buat contoh misalnya di <code>file-1.js<\/code>, kita membuat fungsi sederhana seperti berikut:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>var<\/span><span> person <\/span><span>=<\/span><span> {<\/span><\/span>\n<span><span>  firstName<\/span><span>:<\/span><span> <\/span><span>'<\/span><span>Irfan<\/span><span>'<\/span><span>,<\/span><\/span>\n<span><span>  lastName<\/span><span>:<\/span><span> <\/span><span>'<\/span><span>Maulana<\/span><span>'<\/span><span>,<\/span><\/span>\n<span><span>};<\/span><\/span>\n<span><\/span>\n<span><span>function<\/span><span> <\/span><span>getFirstName<\/span><span>() {<\/span><\/span>\n<span><span>  <\/span><span>return<\/span><span> person.firstName;<\/span><\/span>\n<span><span>}<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Kita bisa menggunakan fungsi tersebut di <code>file-2.js<\/code> dengan cara:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>console.<\/span><span>log<\/span><span>(<\/span><span>getFirstName<\/span><span>());<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Hal di atas bisa mungkin terjadi, namun sangat rapuh.<br \/>\nIni dikarenakan cara ini bergantung pada beberapa hal, diantaranya:<\/p>\n<ol>\n<li>Saat kita menyematkan kode <code><script src=\"https:\/\/mazipan.space\/file-1.js\"><\/script><\/code>, kita harus memastikan bahwa kita tidak menambahkan atribut <code>async<\/code> karena akan membuat urutan muat menjadi tidak bisa diprediksi.<br \/>\nSementara pada kasus kode di atas, <code>file-1.js<\/code> haru dimuat terlebih dahulu sebelum kita bisa menggunakan di <code>file-2.js<\/code>.<\/li>\n<li>Fungsi <code>getFirstName<\/code> dalam <code>file-1.js<\/code> harus dalam keadaan ter-ekspose dan tidak tertutupi fungsi lain.<br \/>\nIni mungkin secara tidak sadar kita sudah melakukannya, karena semua fungsi yang didefinisikan pada alur paling luar di sebuah file JavaScript akan otomatis ter-ekspose ke object global atau <code>window<\/code> di browser.<\/li>\n<li>Property <code>person.firstName<\/code> di dalam <code>file-1.js<\/code> ini telanjang dan bisa diubah oleh siapapun.<\/li>\n<\/ol>\n<p>Dari ketiga hal di atas, sudah terbayang keribetan yang akan terjadi ketika jumlah file JavaScript mulai membengkak semakin banyak.<br \/>\nLantas apakah ada solusinya? Tentu saja ada.<br \/>\nMeskipun untuk masalah No. 1 mungkin belum ada solusinya, namun untuk masalah No.2 dan 3 bisa diselesaikan dengan implementasi <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Glossary\/IIFE\" target=\"_blank\" rel=\"noopener noreferrer\">IIFE (Immediately Invoked Function Expression)<\/a>.<\/p>\n<p>Dari kode <code>file-1.js<\/code> di atas, kita bisa mengubahnya dengan implementasi IIFE menjadi:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>var<\/span><span> person <\/span><span>=<\/span><span> (<\/span><span>function<\/span><span> () {<\/span><\/span>\n<span><span>  <\/span><span>var<\/span><span> firstName <\/span><span>=<\/span><span> <\/span><span>'<\/span><span>Irfan<\/span><span>'<\/span><span>;<\/span><\/span>\n<span><span>  <\/span><span>var<\/span><span> lastName <\/span><span>=<\/span><span> <\/span><span>'<\/span><span>Maulana<\/span><span>'<\/span><span>;<\/span><\/span>\n<span><span>  <\/span><span>return<\/span><span> {<\/span><\/span>\n<span><span>    <\/span><span>getFirstName<\/span><span>:<\/span><span> <\/span><span>function<\/span><span> () {<\/span><\/span>\n<span><span>      <\/span><span>return<\/span><span> firstName;<\/span><\/span>\n<span><span>    },<\/span><\/span>\n<span><span>  };<\/span><\/span>\n<span><span>})();<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Sehingga kita juga perlu mengubah cara pemanggilan pada <code>file-2.js<\/code> menjadi:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>console.<\/span><span>log<\/span><span>(person.<\/span><span>getFirstName<\/span><span>());<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Dengan cara ini kita memastikan bahwa fungsi lain tidak bisa mengubah secara langsung isi dari properti <code>firstName<\/code>.<br \/>\nSeperti dibahas sebelumnya, karena memang secara bahasa belum ada dukungan untuk <em>module system<\/em>, maka penggunaan IIFE ini pun menjadi sangat populer terutama untuk kalangan yang memang peduli dengan isolasi kode.<br \/>\nPada jaman kejayaan <code>jQuery<\/code>, sudah sangat umum kita melihat kode-kode semacam ini:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>\/\/ IIFE di jQuery<\/span><\/span>\n<span><span>(<\/span><span>function<\/span><span> (<\/span><span>$<\/span><span>) {<\/span><\/span>\n<span><span>  <\/span><span>var<\/span><span> <\/span><span>myPrivateFunction<\/span><span> <\/span><span>=<\/span><span> <\/span><span>function<\/span><span> () {};<\/span><\/span>\n<span><span>  <\/span><span>var<\/span><span> <\/span><span>init<\/span><span> <\/span><span>=<\/span><span> <\/span><span>function<\/span><span> () {<\/span><\/span>\n<span><span>    <\/span><span>myPrivateFunction<\/span><span>();<\/span><\/span>\n<span><span>  };<\/span><\/span>\n<span><span>  <\/span><span>$<\/span><span>(init);<\/span><\/span>\n<span><span>})(jQuery);<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Tentu dengan pemanfaatan berbagai macam Design Pattern yang mumpuni bisa tercipta pustaka kelas wahid layaknya <code>jQuery<\/code>, <code>Dojo<\/code>, <code>ExtJS<\/code>, <code>YUI<\/code> dan gerombolannya bermodalkan kemampuan JavaScript mengisolasi kode menggunakan IIFE.<\/p>\n<h2>AMD<\/h2>\n<p>AMD (<em>The Asynchronous Module Definition<\/em>) adalah cara pendefinisian module pada JavaScript yang memungkinkan suatu module atau file beserta dependensinya dimuat secara asinkron.<br \/>\nIni bukan merupakan <em>module system<\/em> standar yang dibuat oleh JavaScript sebagai bahasa, melainkan dikembangkan oleh komunitas yang diawali dengan kemunculan <a href=\"https:\/\/requirejs.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">RequireJS<\/a>.<\/p>\n<p>AMD idenya ingin memperbaiki cara browser memuat file JavaScript dan semua dependency-nya.<br \/>\nKarena implementasinya diatas browser dan dikirim dalam bentuk sebuah pustaka seperti <code>RequireJS<\/code> yang kita sebutkan sebelumnya maka tidak lagi diperlukan sebuah <em>build tools<\/em> untuk membangun aplikasi kompleks berdasarkan AMD ini.<br \/>\nKita tinggal menambahkan pustaka RequireJS dan mendefinisikan <em>module system<\/em> AMD, dan di atas browser, RequireJS akan melakukan permintaan asikron terhadap dependensi yang dibutuhkan.<\/p>\n<p>Berikut contoh kode dari website <code>RequireJS<\/code>:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>\/\/Calling define with module ID, dependency array, and factory function<\/span><\/span>\n<span><span>define<\/span><span>(<\/span><span>'<\/span><span>myModule<\/span><span>'<\/span><span>, [<\/span><span>'<\/span><span>dep1<\/span><span>'<\/span><span>, <\/span><span>'<\/span><span>dep2<\/span><span>'<\/span><span>], <\/span><span>function<\/span><span> (<\/span><span>dep1<\/span><span>, <\/span><span>dep2<\/span><span>) {<\/span><\/span>\n<span><span>  <\/span><span>\/\/Define the module value by returning a value.<\/span><\/span>\n<span><span>  <\/span><span>return<\/span><span> <\/span><span>function<\/span><span> () {};<\/span><\/span>\n<span><span>});<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Bagi yang pernah menggunakan <code>AngularJS<\/code> mungkin kode ini terasa familiar, meskipun sebenarnya <code>AngularJS<\/code> tidak melakukan pemuatan dependensi secara otomatis melainkan hanya mendefinisikan dependensi dengan cara yang mirip dengan <code>RequireJS<\/code>.<\/p>\n<p>AMD menjadi satu-satunya pilihan bagi pengguna JavaScript yang mendambakan <em>module system<\/em> pada saat itu. Dengan AMD kita bisa mengisolasi kode kita dari satu file dengan file lainnya karena hampir semua kode kita di definisikan di dalam fungsi pembungkus dari pustaka yang menerapkan sistem ini semacam RequireJS.<br \/>\nDitambah kemampuannya yang bisa otomatis memuat dependensi yang dibutuhkan langsung di browser, AMD pada akhirnya memiliki masanya sendiri pada waktu itu.<\/p>\n<p>Karena bukan <em>module system<\/em> resmi, maka bisa dimaklumi kalau cara ini tidak begitu populer di kalangan pengguna JavaScript, meskipun sampai saat ini masih ada sedikit penggunanya, bahkan di beberapa build tools modern sampai saat ini masih mendukung target kompilasi ke dalam <em>module system<\/em> AMD.<br \/>\nSaat ini pengguna AMD besar salah satunya adalah <a href=\"https:\/\/dojotoolkit.org\/documentation\/tutorials\/1.10\/hello_dojo\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">Dojo<\/a>.<\/p>\n<h2>CommonJS<\/h2>\n<p><a href=\"http:\/\/www.commonjs.org\/\">CommonJS (CJS)<\/a> ini lagi-lagi bukanlah <em>module system<\/em> standar yang diperkenalkan JavaScript sebagai bahasa.<br \/>\nIni merupakan <em>module system<\/em> yang dijadikan standar oleh Node.js ketika harus berurusan dengan kode-kode Node.js.<br \/>\nYa, memang untuk kode Server Side seperti Node.js, <em>module system<\/em> adalah barang wajib.<br \/>\nKarena pada saat itu belum ada <em>module system<\/em> yang bisa digunakan maka dari itu Node.js membuat standar sendiri untuk lingkungannya.<\/p>\n<p>CommonJS menurut saya pribadi adalah revolusi, JavaScript yang tadinya tidak pernah memikirkan soal standarisasi module system mau tidak mau harus mulai memikirkannya.<br \/>\nKalau tidak ya sudah pasti implementasi lain seperti CommonJS akan muncul di masa depan dengan pendekatan yang bisa jadi berbeda lagi.<br \/>\nMeskipun secara desain CommonJS memang tidak diperuntukkan untuk JavaScript secara umum yang bisa jalan di berbagai environment, melainkan hanya dikhususkan bagi pengguna JavaScript dengan lingkungan Node.js saja.<br \/>\nNamun seiring naiknya popularitas Node.js, semakin banyak pula orang maupun pembuat pustaka di luaran yang menerapkan CommonJS sebagai target build mereka.<\/p>\n<p>Satu sisi lain CommonJS juga bisa dilihat sebagai malapetaka bagi JavaScript, ketika hal yang bukan standar tapi sudah keburu populer karena memang dari sisi standarisasi belum menyediakan fiturnya.<br \/>\nCommonJS menjadi hal lumrah dan seolah menjadi standar dari JavaScript padahal hanya bisa jalan di Node.js.<br \/>\nHal semacam ini bisa jadi membingungkan bagi kalian yang baru belajar JavaScript atau Node.ja dan tidak tau sejarah sampai adanya CommonJS.<\/p>\n<p>Kode CommonJS bisa terlihat pada contoh berikut:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>const<\/span><span> fs <\/span><span>=<\/span><span> <\/span><span>require<\/span><span>(<\/span><span>'<\/span><span>fs<\/span><span>'<\/span><span>);<\/span><\/span>\n<span><\/span>\n<span><span>fs.<\/span><span>writeFile<\/span><span>(<\/span><span>'<\/span><span>pesan.txt<\/span><span>'<\/span><span>, <\/span><span>'<\/span><span>Sebuah pesan untuk seseorang<\/span><span>'<\/span><span>, <\/span><span>'<\/span><span>utf8<\/span><span>'<\/span><span>, (<\/span><span>err<\/span><span>) <\/span><span>=&gt;<\/span><span> {<\/span><\/span>\n<span><span>  <\/span><span>if<\/span><span> (err) <\/span><span>throw<\/span><span> err;<\/span><\/span>\n<span><span>  console.<\/span><span>log<\/span><span>(<\/span><span>'<\/span><span>Berhasil disimpan!<\/span><span>'<\/span><span>);<\/span><\/span>\n<span><span>});<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Setidaknya terdapat 2 cara untuk mendefinisikan sebuah modul CommonJS yakni dengan <code>exports<\/code> dan <code>module.exports<\/code>.<br \/>\nKeduanya sedikit agak berbeda, berikut dilihat dan dipelajari lewat contoh kode berikut:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>\/\/ file circle.js<\/span><\/span>\n<span><span>const<\/span><span> { PI } <\/span><span>=<\/span><span> <\/span><span>Math<\/span><span>;<\/span><\/span>\n<span><\/span>\n<span><span>exports<\/span><span>.<\/span><span>area<\/span><span> <\/span><span>=<\/span><span> (<\/span><span>r<\/span><span>) <\/span><span>=&gt;<\/span><span> PI <\/span><span>*<\/span><span> r <\/span><span>**<\/span><span> <\/span><span>2<\/span><span>;<\/span><\/span>\n<span><span>exports<\/span><span>.<\/span><span>circumference<\/span><span> <\/span><span>=<\/span><span> (<\/span><span>r<\/span><span>) <\/span><span>=&gt;<\/span><span> <\/span><span>2<\/span><span> <\/span><span>*<\/span><span> PI <\/span><span>*<\/span><span> r;<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Kita bisa menggunakan modul di atas dengan:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>const<\/span><span> circle <\/span><span>=<\/span><span> <\/span><span>require<\/span><span>(<\/span><span>'<\/span><span>.\/circle.js<\/span><span>'<\/span><span>);<\/span><\/span>\n<span><\/span>\n<span><span>const<\/span><span> area <\/span><span>=<\/span><span> circle.<\/span><span>area<\/span><span>(<\/span><span>4<\/span><span>);<\/span><\/span>\n<span><span>console.<\/span><span>log<\/span><span>(<\/span><span>`The area of a circle of radius 4 is <\/span><span>${<\/span><span>area<\/span><span>}<\/span><span>`<\/span><span>);<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Sedangkan menggunakan <code>module.exports<\/code> bisa dilihat dari kode berikut:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>module<\/span><span>.<\/span><span>exports<\/span><span> <\/span><span>=<\/span><span> <\/span><span>class<\/span><span> <\/span><span>Square<\/span><span> {<\/span><\/span>\n<span><span>  <\/span><span>constructor<\/span><span>(<\/span><span>width<\/span><span>) {<\/span><\/span>\n<span><span>    <\/span><span>this<\/span><span>.width <\/span><span>=<\/span><span> width;<\/span><\/span>\n<span><span>  }<\/span><\/span>\n<span><\/span>\n<span><span>  <\/span><span>area<\/span><span>() {<\/span><\/span>\n<span><span>    <\/span><span>return<\/span><span> <\/span><span>this<\/span><span>.width <\/span><span>**<\/span><span> <\/span><span>2<\/span><span>;<\/span><\/span>\n<span><span>  }<\/span><\/span>\n<span><span>};<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Dipanggil pada file lain dengan:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>const<\/span><span> Square <\/span><span>=<\/span><span> <\/span><span>require<\/span><span>(<\/span><span>'<\/span><span>.\/square.js<\/span><span>'<\/span><span>);<\/span><\/span>\n<span><span>const<\/span><span> mySquare <\/span><span>=<\/span><span> <\/span><span>new<\/span><span> <\/span><span>Square<\/span><span>(<\/span><span>2<\/span><span>);<\/span><\/span>\n<span><span>console.<\/span><span>log<\/span><span>(<\/span><span>`The area of mySquare is <\/span><span>${<\/span><span>mySquare.<\/span><span>area<\/span><span>()<\/span><span>}<\/span><span>`<\/span><span>);<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Karena dikembangkan oleh Node.js maka mindset dari <em>module system<\/em> ini memang <em>Server Side<\/em> dan bukan <em>Client Side<\/em>.<br \/>\nKarenanya pada masanya ada <em>bundler<\/em> semacam <a href=\"http:\/\/browserify.org\/\">Browserify<\/a> dan <a href=\"https:\/\/github.com\/systemjs\/systemjs\" target=\"_blank\" rel=\"noopener noreferrer\">SystemJS<\/a> yang populer untuk memastikan module CommonJS bisa berjalan di browser.<\/p>\n<h2>ESM<\/h2>\n<p><strong>ESM (ES Module)<\/strong> atau beberapa orang menyebutnya juga dengan <strong>ES Harmony<\/strong> merupakan format standar yang diberikan oleh ECMA seperti bisa dilihat pada <a href=\"https:\/\/tc39.es\/ecma262\/#sec-modules\" target=\"_blank\" rel=\"noopener noreferrer\">dokumen spesifikasi<\/a>.<br \/>\nKarena ESM merupakan standar yang diberikan oleh ECMA, maka mau tidak mau Node.js pun harus sudah mulai mendukung <em>module system<\/em> ini.<br \/>\nSyukurnya di versi teranyarnya (sedari versi 14 kalau tidak salah) Node.js sudah memasukkan dukungan terhadap ESM, sehingga tidak perlu lagi menambahkan <em>build tools<\/em> semacam webpack lagi kalau ingin koding dengan ESM di lingkungan Node.js.<\/p>\n<p>Berikut contoh kode ES Module:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>const<\/span><span> firstName <\/span><span>=<\/span><span> <\/span><span>'<\/span><span>Irfan<\/span><span>'<\/span><span>;<\/span><\/span>\n<span><span>const<\/span><span> lastName <\/span><span>=<\/span><span> <\/span><span>'<\/span><span>Maulana<\/span><span>'<\/span><span>;<\/span><\/span>\n<span><\/span>\n<span><span>export<\/span><span> <\/span><span>const<\/span><span> getFirstName() {<\/span><\/span>\n<span><span>  <\/span><span>return<\/span><span> firstName;<\/span><\/span>\n<span><span>};<\/span><\/span>\n<span><\/span>\n<span><span>export<\/span><span> <\/span><span>const<\/span><span> getLastName() {<\/span><\/span>\n<span><span>  <\/span><span>return<\/span><span> lastName;<\/span><\/span>\n<span><span>};<\/span><\/span>\n<span><\/span>\n<span><span>export<\/span><span> <\/span><span>default<\/span><span> <\/span><span>function<\/span><span>() {<\/span><\/span>\n<span><span>  <\/span><span>return<\/span><span> firstName <\/span><span>+<\/span><span> <\/span><span>'<\/span><span> <\/span><span>'<\/span><span> <\/span><span>+<\/span><span> lastName;<\/span><\/span>\n<span><span>};<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Dan bisa digunakan pada file lain dengan cara:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>import<\/span><span> fullName, { getFirstName, getLastName } <\/span><span>from<\/span><span> <\/span><span>'<\/span><span>.\/file-1<\/span><span>'<\/span><span>;<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<p>Ada artikel menarik dengan visualisasi yang bagus kalau kalian ingin memahami perihal ES Module ini, silahkan baca artikel \u201c<a href=\"https:\/\/hacks.mozilla.org\/2018\/03\/es-modules-a-cartoon-deep-dive\/\" target=\"_blank\" rel=\"noopener noreferrer\">ES modules: A cartoon deep-dive<\/a>\u201d.<\/p>\n<p>ESM juga telah didukung secara native di beberapa peramban modern dengan memberikan atribut tambahan <code>module<\/code> pada saat memuat berkas, baca kabarnya di artikel \u201c<a href=\"https:\/\/jakearchibald.com\/2017\/es-modules-in-browsers\/\" target=\"_blank\" rel=\"noopener noreferrer\">ECMAScript modules in browsers<\/a>\u201d.<\/p>\n<p>Berikut adalah contoh kode implementasi ESM di browser:<\/p>\n<pre data-lang=\"html\"><code><span><span>&lt;<\/span><span>script<\/span><span> <\/span><span>type<\/span><span>=<\/span><span>\"<\/span><span>module<\/span><span>\"<\/span><span>&gt;<\/span><\/span>\n<span><span>  <\/span><span>import<\/span><span> { addTextToBody } <\/span><span>from<\/span><span> <\/span><span>'<\/span><span>.\/utils.mjs<\/span><span>'<\/span><span>;<\/span><\/span>\n<span><\/span>\n<span><span>  <\/span><span>addTextToBody<\/span><span>(<\/span><span>'<\/span><span>Modules are pretty cool.<\/span><span>'<\/span><span>);<\/span><\/span>\n<span><span><!--<\/span--><span>script<\/span><span>&gt;<\/span><\/span>\n<span><\/span><\/span><\/code><\/pre>\n<pre data-lang=\"javascript\"><code><span><span>\/\/ utils.mjs<\/span><\/span>\n<span><span>export<\/span><span> <\/span><span>function<\/span><span> <\/span><span>addTextToBody<\/span><span>(<\/span><span>text<\/span><span>) {<\/span><\/span>\n<span><span>  <\/span><span>const<\/span><span> div <\/span><span>=<\/span><span> document.<\/span><span>createElement<\/span><span>(<\/span><span>'<\/span><span>div<\/span><span>'<\/span><span>);<\/span><\/span>\n<span><span>  div.textContent <\/span><span>=<\/span><span> text;<\/span><\/span>\n<span><span>  document.body.<\/span><span>appendChild<\/span><span>(div);<\/span><\/span>\n<span><span>}<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<h2>UMD<\/h2>\n<p><a href=\"https:\/\/github.com\/umdjs\/umd\/\" target=\"_blank\" rel=\"noopener noreferrer\">UMD (Universal Module Definition)<\/a> merupakan format yang dibuat sebagai adapter dikarenakan ada perbedaan <em>module system<\/em> pada kode Server dan kode Klien dan beberapa <em>module system<\/em> yang memang terlanjur populer karena dibawa oleh komunitas.<br \/>\nFormat ini sering digunakan sebagai <em>fallback<\/em> oleh beberapa <em>bundler<\/em> seperti Rollup dan Webpack.<\/p>\n<p>Contoh kode UMD bisa dilihat pada kode berikut:<\/p>\n<pre data-lang=\"javascript\"><code><span><span>(<\/span><span>function<\/span><span> (<\/span><span>root<\/span><span>, <\/span><span>factory<\/span><span>) {<\/span><\/span>\n<span><span>  <\/span><span>if<\/span><span> (<\/span><span>typeof<\/span><span> define <\/span><span>===<\/span><span> <\/span><span>'<\/span><span>function<\/span><span>'<\/span><span> <\/span><span>&amp;&amp;<\/span><span> define.amd) {<\/span><\/span>\n<span><span>    <\/span><span>define<\/span><span>([<\/span><span>'<\/span><span>jquery<\/span><span>'<\/span><span>, <\/span><span>'<\/span><span>underscore<\/span><span>'<\/span><span>], factory);<\/span><\/span>\n<span><span>  } <\/span><span>else<\/span><span> <\/span><span>if<\/span><span> (<\/span><span>typeof<\/span><span> <\/span><span>exports<\/span><span> <\/span><span>===<\/span><span> <\/span><span>'<\/span><span>object<\/span><span>'<\/span><span>) {<\/span><\/span>\n<span><span>    <\/span><span>module<\/span><span>.<\/span><span>exports<\/span><span> <\/span><span>=<\/span><span> <\/span><span>factory<\/span><span>(<\/span><span>require<\/span><span>(<\/span><span>'<\/span><span>jquery<\/span><span>'<\/span><span>), <\/span><span>require<\/span><span>(<\/span><span>'<\/span><span>underscore<\/span><span>'<\/span><span>));<\/span><\/span>\n<span><span>  } <\/span><span>else<\/span><span> {<\/span><\/span>\n<span><span>    root.Requester <\/span><span>=<\/span><span> <\/span><span>factory<\/span><span>(root.$, root._);<\/span><\/span>\n<span><span>  }<\/span><\/span>\n<span><span>})(<\/span><span>this<\/span><span>, <\/span><span>function<\/span><span> (<\/span><span>$<\/span><span>, <\/span><span>_<\/span><span>) {<\/span><\/span>\n<span><span>  <\/span><span>var<\/span><span> Requester <\/span><span>=<\/span><span> {};<\/span><\/span>\n<span><\/span>\n<span><span>  <\/span><span>return<\/span><span> Requester;<\/span><\/span>\n<span><span>});<\/span><\/span>\n<span><\/span><\/code><\/pre>\n<h2>Kesimpulan<\/h2>\n<p>Di JavaScript saat ini <em>module system<\/em> standar yang digunakan adalah ES Module.<br \/>\nKendati demikian, masih banyak kode yang menggunakan baik CommonJS, AMD bahkan manual menggunakan IIFE.<\/p>\n<p>Kita sebagai developer JavaScript mestinya mengetahui perbedaan <em>module system<\/em> yang kadung sudah terjadi ini, sehingga kedepannya kita bisa mengambil keputusan ketika harus memilih <em>module system<\/em> mana yang ingin didukung.<\/p>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Hal yang lucu ketika sebuah bahasa pemrograman sebesar JavaScript ternyata memiliki variasi dalam penerapan module system. Sebelum membaca lebih jauh, mari kita bahas bersama dahulu apa itu module system dan &hellip; <\/p>\n","protected":false},"author":1,"featured_media":279,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-278","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknologi"],"_links":{"self":[{"href":"https:\/\/sentraldigitalindonesia.co.id\/blog\/wp-json\/wp\/v2\/posts\/278","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sentraldigitalindonesia.co.id\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sentraldigitalindonesia.co.id\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sentraldigitalindonesia.co.id\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sentraldigitalindonesia.co.id\/blog\/wp-json\/wp\/v2\/comments?post=278"}],"version-history":[{"count":1,"href":"https:\/\/sentraldigitalindonesia.co.id\/blog\/wp-json\/wp\/v2\/posts\/278\/revisions"}],"predecessor-version":[{"id":280,"href":"https:\/\/sentraldigitalindonesia.co.id\/blog\/wp-json\/wp\/v2\/posts\/278\/revisions\/280"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sentraldigitalindonesia.co.id\/blog\/wp-json\/wp\/v2\/media\/279"}],"wp:attachment":[{"href":"https:\/\/sentraldigitalindonesia.co.id\/blog\/wp-json\/wp\/v2\/media?parent=278"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sentraldigitalindonesia.co.id\/blog\/wp-json\/wp\/v2\/categories?post=278"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sentraldigitalindonesia.co.id\/blog\/wp-json\/wp\/v2\/tags?post=278"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}