Pengantar Modularisasi Harmonis

 

Pengantar Modularisasi Harmonis

“Coding like poetry should be short and concise.”  - Santosh Kalwar, Computer Scientist.

Singkat dan jelas, itulah tujuan yang ingin kita capai ketika menuliskan kode suatu program. Agar tujuan itu tercapai, Anda harus bisa memecah kode menjadi keping-keping. Tujuan dari memecah kode agar mudah dibaca dan ringkas. Modularisasi dapat membantu Anda untuk memecah kode program Anda sehingga lebih terstruktur, singkat, dan jelas. 

Berikut adalah objektif pembelajaran yang akan dicapai pada modul ini.

  • Menjelaskan sebuah masalah yang dapat dipecahkan dengan teknik modularisasi.
  • Membedakan antara default export dan named exports, begitu juga dengan default import dan named imports.
  • Mengidentifikasi "module" dalam konteks JavaScript.
  • Mengimplementasikan modularisasi untuk mengekspor function, variable, atau nilai lain di dalam sebuah module.
  • Menggunakan nilai function, variable, atau nilai lain yang diimpor dari sebuah module.

Mengenal Modularisasi

Program yang bertambah besar dan memiliki banyak fitur, kodenya pun akan menjadi kompleks. Idealnya, kode yang ditulis memiliki struktur yang jelas dan ringkas. Untuk menjaga kode tetap terstruktur dan ringkas ketika programnya semakin kompleks, butuh upaya yang besar. Salah satu cara agar kode program yang kompleks menjadi tetap terstruktur dan jelas adalah dengan menerapkan modularisasi

Modularisasi adalah cara kita untuk memecahkan kode program yang kompleks dan besar menjadi bentuk yang lebih sederhana dan ringkas. Implementasi dari modularisasi di JavaScript adalah dengan membuat berkas-berkas terpisah per bagian function/method yang disebut dengan modul. Kode yang ada di dalam Modul dapat digunakan oleh modul lainnya dengan cara export dan import.

dos-e8a6b3a18dc66aa3c9a8c681ffaedce020240730104435.jpeg

Manfaat dari modularisasi adalah dapat menyelesaikan masalah terkait struktur dan kode program. Modularisasi dapat mempermudah kita untuk memahami keseluruhan struktur program sehingga gampang untuk berkolaborasi. Modularisasi membuat struktur kode menjadi rapi, memahami struktur dan membaca kode program yang sudah kompleks pun menjadi lebih mudah. Selain itu, function/method yang ditulis dapat digunakan kembali di tempat lainnya (reusable). Misalnya, satu function dapat digunakan di dua fitur yang berbeda.

JavaScript awalnya tidak memiliki konsep modularisasi. JavaScript hanya mengenal scope yang sama dari function/method/variable. Namun, semenjak adanya ECMAScript 2015, JavaScript bisa menggunakan konsep modularisasi dan dapat menggunakan keyword import dan export.  

Import memungkinkan kita untuk memasukkan function/method/variable dari modul lain. Export memungkinkan kita untuk mengeluarkan function/method/variable ke modul lain agar dapat digunakan.

Apakah Anda kepo untuk mengetahui lebih detailnya? Yuk, lanjut ke materi selanjutnya!

Import

JavaScript memungkinkan kita untuk menggunakan function/method dari modul lainnya dengan dua syarat: 

  • Harus meng-import function/method tersebut.
  • Function/method tersebut sudah di-export (export akan dibahas di materi selanjutnya).

Import dapat dilakukan dengan menulis kata kunci import kemudian diikuti oleh nama function/method/variable. Perhatikan contoh berikut ini.

Contoh di atas akan menghasil tulisan “Ini adalah function export default”. Contoh tersebut dikatakan sebagai default import. Default import dapat bekerja jika di modul lainnya terdapat function/method/variable yang di-export default. 

Pada contoh di atas, export default-nya adalah myFunction. Default import juga memungkinkan kita untuk import function/method/variable yang namanya tidak harus sama dengan function/method/variable aslinya. Simak contoh berikut agar lebih terbayang.

Apa pun nama yang kita tulis ketika mengimpor function dari berkas anotherFile.mjs di main.mjs, function myFunction akan tetap terimport. Begitulah cara kerja default import. Lalu, bagaimana ketika kita ingin mengimpor dari suatu modul yang memiliki banyak function/method/variable yang di-export? Jawabannya adalah kita dapat menggunakan named import.

Berbeda dengan default import yang tidak memerlukan nama spesifik, named import memungkinkan kita mengimpor function/method/variable tertentu berdasarkan namanya. Saat menggunakan named import, pastikan nama fungsi yang ingin diimpor sesuai.

Ketika menggunakan named import, selain memastikan nama function sesuai, kita juga akan menuliskan nama function yang diimpor dalam kurung kurawal {}. Selain itu, kita juga dapat mengimpor lebih dari satu function/method/variable. Perhatikan contoh berikut ini.

Apa yang dilakukan pada contoh di atas sebenarnya sah-sah saja. Namun, ada cara lainnya yaitu menggunakan import *. Import * dapat dilakukan ketika function/method/variable yang ingin kita impor dari modul yang sama sangat banyak.

Jika function/method/variable yang ingin kita import sangat banyak, kita dapat menggunakan import *. Perhatikan contoh berikut.

Selain menggunakan tanda bintang (*), kita juga dapat menambahkan as variable (sebagai alias) untuk mengimpor seluruh variable yang berasal dari modul lainnya (pada contoh anotherfile.mjs). Apa perbedaan antara import {} dan import *?

import * memungkinkan kita untuk mengimpor seluruh module yang di export. Namun, kekurangannya adalah sulit untuk dibaca karena tidak eksplisit, sedangkan menggunakan import {} akan menjadi eksplisit sehingga kita bisa tahu apa saja function/method/variable yang ingin di-import.

Pada contoh sebelumnya, Anda telah melihat contoh penggunaan keyword as. Keyword tersebut digunakan pada import yang disebut dengan import alias. Import alias digunakan untuk mengubah nama dari function/method/variable yang berasal dari modul lain menjadi nama yang kita inginkan. Tujuan dari import alias adalah mempermudah ketika kita memiliki nama function/method/variable yang sama di beberapa modul. 

Misalnya, Anda memiliki function dengan nama myFunction di dua modul berbeda, yaitu user.mjs dan customer.mjs. Lalu, Anda ingin menggunakan kedua function tersebut di satu modul yaitu main.mjs.

Tanpa menggunakan import alias, Anda akan mendapatkan error seperti berikut.

dos-83d2a2e697ce4008bb56a8935c50f02320240730105404.jpeg

Error tersebut terjadi karena myFunction diimpor sebanyak dua kali. Untuk mengatasi hal tersebut, gunakanlah import alias.

Alih-alih menggunakan myFunction, kita mengubah namanya menjadi userFunction dan customerFunction. Import alias juga meningkatkan readability kode yang ditulis. Kita langsung tahu konteks dan maksud dari function/method/variable yang diimpor contohnya userFunction yang berasal dari modul user dan konteksnya adalah user. Menggunakan alias saat mengimpor tidak hanya menghindari konflik seperti kasus sebelumnya, tetapi juga meningkatkan keterbacaan kode.

Bagi sebagian orang, terutama bagi Anda yang pertama kali belajar pemrograman, Anda mungkin kesulitan untuk memahami import. Untuk memahami konsep ini, mari kita gunakan analogi sehari-hari yang mungkin lebih familiar.

  • Import: Bayangkan Anda sedang memasak di dapur, tetapi Anda kehabisan bahan tertentu. Anda tahu bahwa tetangga Anda memiliki bahan yang Anda butuhkan. Proses "import" ini mirip dengan meminjam bahan dari tetangga. Dalam pemrograman, "import" memungkinkan Anda menggunakan kode atau fungsi yang sudah dibuat oleh orang lain, sehingga Anda tidak perlu membuat semuanya dari awal.
  • Named Import: Ini seperti meminjam barang dan menyebutkan secara spesifik nama barangnya. Misalnya, Anda tahu tetangga Anda punya wajan, jadi, Anda pergi ke rumah tetangga dan mengatakan, "Boleh nggak saya meminjam wajannya?"
  • Default Import: Jika Anda tidak ingin menyebutkan secara spesifik apa yang Anda butuhkan dan hanya ingin meminjam sesuatu yang sering dipakai, Anda bisa mengatakan, "Bolehkah saya pinjam bahan utamanya?" Dalam hal ini, Anda meminjam bahan yang paling umum dipakai dari dapur tetangga tanpa menyebutkan nama tertentu.

Dari tadi kita sudah bahas import dan di contoh Anda mungkin sudah melihat penggunaan export. Nah, untuk pembahasan mengenai export akan kita bahas di materi selanjutnya. Yuk, teruskan perjalananmu untuk mengetahui modularisasi!

Export

Export adalah keyword yang kita gunakan untuk melabeli suatu function/method/variable agar dapat diakses dari luar modul saat ini. Export terdiri dari dua jenis, yaitu default export dan named export. Perhatikan contoh named export berikut ini.

  1. ekspor konstanta nama = 'John';
  2. ekspor konstanta email = 'john@gmail.com';
  3. ekspor konstanta usia = 25;

Cara tersebut merupakan cara export sebelum deklarasi dilakukan. Cara lainnya adalah export setelah deklarasi dilakukan seperti berikut ini.

  1. konstanta nama = 'John';
  2. const email = 'john@gmail.com';
  3. usia konstan = 25;
  4. ekspor { nama, email, usia };

Hasilnya akan tetap sama. Variable yang sudah diekspor (name, email, dan age) dapat digunakan di module lainnya. Cara mengimpor named export adalah dengan menuliskan nilainya di dalam sebuah kurung kurawal. Perhatikan contoh berikut ini.

  1. impor { nama, email, usia } dari './user.mjs';
  2. console.log(nama, email, usia);

Variable name, email, dan age akan diimpor dengan named import (yang sudah kita bahas di materi sebelumnya) sebelum digunakan. 

Terakhir, ada teknik yang disebut dengan default export. Default export adalah cara kita untuk mengekspor minimal satu function/method/variable di sebuah modul. Dengan menggunakan default export, modul lain yang ingin menggunakan nilainya tidak perlu tahu spesifik namanya karena secara default sudah ada function/method/variable yang diekspor. Perhatikan contoh berikut ini.

Mengimpor nilai dari default export tidak membutuhkan kurung kurawal seperti contoh sebelumnya. 

Contoh di atas akan mencetak dua tulisan Good morning! di Terminal/Console. Apakah dengan menggunakan default export kita hanya bisa mengekspor satu fungsi, metode, atau variabel saja? Tentu tidak. 

Secara teknis, kita bisa mengekspor lebih dari satu fungsi, metode, atau variabel, tetapi hal ini tidak disarankan ketika menggunakan export default. Sebaiknya, ketika menggunakan default export, satu modul satu nilai. Di JavaScript, satu modul hanya bisa memiliki satu default export. Tujuan dari hal ini adalah agar struktur kode lebih jelas dan memudahkan navigasi ketika ingin mencari suatu modul.

Selain itu, apakah kita bisa mengombinasikan antara default export dan named export? Tentunya itu bisa, tetapi bukan best practices karena tidak konsisten. Perhatikan contoh di bawah ini.

Interactive code akan menampilkan hasil seperti berikut.

  1. Hai, ini ekspor default dari anotherfile.mjs
  2. Sampai jumpa, ini bernama ekspor dari anotherfile.mjs

dos-1ef3995658689677877dd7fbe4fd8a1920240730110056.jpeg

Named export cocok digunakan ketika ingin mengekspor banyak nilai dari satu modul. Selain itu, named export mengharuskan kita untuk menulis nama function/method/variable secara spesifik ketika mengimpornya. Menulis nama secara spesifik membuat codebase menjadi konsisten.

Default export cocok digunakan untuk menghindari conflict ketika mengimpornya karena kita tidak perlu menulis function/method/variable sesuai dengan namanya. Selain itu, default export membuat struktur lebih jelas karena dalam satu module hanya ada satu nilai yang diekspor.

Menggunakan Module

Sebelumnya, kita sudah tahu konsep modularisasi di JavaScript. Anda mungkin sudah tahu juga cara menggunakan impor atau ekspor. Di materi ini, kita akan coba menggunakan module di JavaScript.

Mengekspor Variable

Misalnya, ada suatu module yang ditulis di berkas module.mjs. Di dalam berkas tersebut, kita akan menulis satu variabel yang akan kita ekspor. Untuk mengekspornya dapat dilakukan seperti berikut.

  1. export const name = 'Dicoding';

Selain mengekspor variable yang bertipe string, kita juga dapat mengekspor variable yang bertipe array.

  1. export const favoriteFood = ['pizza', 'pasta', 'sushi'];


Mengekspor Function

Cara untuk mengekspor function tak berbeda jauh dengan cara mengekspor variable.

  1. export const name = 'John';
  2. export const favoriteFood = ['pizza', 'pasta', 'sushi'];
  3.  
  4. export function sayHi(name) {
  5.   console.log(`Hi, ${name}!`);
  6. }

Agar tidak perlu menulis kata kunci export di setiap nilai yang ingin diekspor, Anda dapat mengekspor di akhir berkas seperti berikut.

  1. const name = 'John';
  2. const favoriteFood = ['pizza', 'pasta', 'sushi'];
  3.  
  4. function sayHi(name) {
  5.   console.log(`Hi, ${name}!`);
  6. }
  7.  
  8. export { name, favoriteFood, sayHi };

Nilai yang telah diekspor tersebut siap digunakan di mana pun.

Mengimpor Variable

Tadi kita sudah mengekspor beberapa nilai dan function di berkas module.mjs. Sekarang, tambahkan berkas baru bernama index.mjs yang akan kita gunakan untuk mengimpor dan menggunakan variable dan function yang telah diekspor sebelumnya.

  1. import { name, favoriteFood } from './module.mjs';

Setelah itu, kita dapat mencetak nilainya di Terminal.

  1. console.log(name);
  2. console.log(favoriteFood);

Selain mengimpor dengan named import, kita juga dapat mengimpornya menggunakan import alias. Tenang saja, hasilnya akan tetap sama.

  1. import { name, favoriteFood as food } from './module.mjs';
  2.  
  3. console.log(name);
  4. console.log(food);


Mengimpor Function

Untuk mengimpor function dapat dilakukan dengan cara berikut ini.

  1. import { name, favoriteFood as food, sayHi } from './module.mjs';
  2.  
  3. console.log(name);
  4. console.log(food);
  5. sayHi(name);

Karena kita mengimpor seluruh nilai yang ada di module tersebut, gunakanlah keyword * agar lebih ringkas.

  1. import * as user from './module.mjs';
  2.  
  3. console.log(user.name);
  4. console.log(user.favoriteFood);
  5. user.sayHi(user.name);

Memahami konsep modularisasi dapat membantu Anda untuk membuat program JavaScript yang lebih modular, terstruktur, dan modern. Terus semangat untuk menguasai bahasa JavaScript ini dengan terus menyimak modul-modul berikutnya!

Menggunakan Modularisasi ESM di Node.js

Karena ESModule adalah barang baru di dunia persilatan Node.js, kita perlu menambahkan konfigurasi dalam project Node.js. Kalau Anda mengikuti latihan di modul ini pada lokal komputer, Anda akan mengalami error ketika menggunakan import dan export. Mungkin beberapa dari Anda sudah menyadari akan hal ini dan telah mencari solusi error dengan berselancar di internet.

Sebenarnya, kita hanya membutuhkan konfigurasi sederhana. Berikut cara yang dapat kita terapkan jika ingin menggunakan ES Modul di Node.js.

Mengubah ekstensi berkas

Cara pertama yaitu mengubah ekstensi berkas dari .js menjadi mjs. Dengan mengubah format ini, kita memberitahu ke Node.js bahwa kita ingin menggunakan ESModule. Cara ini terbilang sangat sederhana. Namun, bagaimana jika berkas project Anda sangat banyak? Tidak mungkin Anda mengubahnya satu per satu karena pasti memakan waktu cukup lama dan tidak efisien.

Menambahkan konfigurasi di package.json

Cara berikut ini akan menyelesaikan masalah yang ada pada cara sebelumnya yaitu dengan menambahkan konfigurasi pada level package. Dengan menambahkan konfigurasi pada level package, kita tidak perlu lagi untuk mengganti ekstensi berkas menjadi .mjs dan cara inilah yang kami lakukan sepanjang modul ini.

  1. Buka berkas package.json atau jika belum memilikinya, Anda bisa membuatnya terlebih dahulu (dengan menggunakan perintah npm init -y)
  2. Setelah itu, tambahkan baris kode berikut ini
    1. "type": "module"
    Sehingga package.json akan tampak seperti gambar di bawah ini.
    dos-dbee8516aafdb66152c2f4ca738d2ead20240730111608.jpeg

Dua cara ini dapat membuat ESM bisa digunakan di Node.js. Anda bebas memilih cara mana pun sesuai kebutuhan di dalam project.

Menggunakan Modularisasi ESM di Browser

ESModule tak hanya dapat digunakan pada Node.js, tetapi juga di browser. Hal ini merupakan kabar gembira bagi Web Developer, khususnya Front-End Developer yang banyak berkecimpung di browser. Penasaran bagaimana caranya?

Caranya adalah dengan menambahkan type pada saat memanggil tag script seperti contoh berikut ini.

  1. <script src="./esmodule.js" type="module">

Dengan begitu, Anda dapat memuat berkas JavaScript sebagai ESModule pada berkas HTML dan dijalankan di browser. Perlu diingat bahwa tidak semua browser mendukung ESModule sehingga untuk menangani hal itu, tambahkan kode berikut ini.

  1. <script nomodule src="fallback.js"></script>

Atribut nomodule akan memberitahu browser untuk memuat berkas fallback.js jika tidak mendukung ESModule. 

Selain menulis JavaScript pada berkas terpisah dari HTML, Anda juga dapat menambahkan JavaScript dengan ESModule secara inline.

  1. <script type="module">
  2.   impor App dari "./app.js";
  3.   konsol.log(Aplikasi);
  4. </script>

Anda sudah mengetahui manfaat membagi kode menjadi bagian kecil dengan module dan cara untuk membaginya. Semoga dengan menguasai modularisasi, Anda dapat menyederhanakan struktur kompleks di aplikasi menjadi lebih ringkas dan sederhana.

Rangkuman Modularisasi Harmonis

Selamat! Anda sudah berada di penghujung modul Modularisasi Harmonis. Mari kita uraikan materi yang sudah Anda pelajari untuk menyegarkan ingatan Anda tentang materi tersebut.


Mengenal Modularisasi

Modularisasi adalah cara kita untuk memecahkan kode program yang kompleks dan besar menjadi bentuk yang lebih sederhana dan ringkas. Implementasi dari modularisasi di JavaScript adalah dengan membuat berkas-berkas terpisah per bagian function/method yang disebut dengan modul. Kode yang ada di dalam Modul dapat digunakan oleh modul lainnya dengan cara export dan import.


dos-d000dfb5d9a07f55eca75afa1383b0b920240801153620.jpeg

Manfaat dari modularisasi adalah dapat menyelesaikan masalah terkait struktur dan kode program. Modularisasi dapat mempermudah kita untuk memahami keseluruhan struktur program sehingga gampang untuk berkolaborasi. Modularisasi membuat struktur kode menjadi rapi, memahami struktur dan membaca kode program yang sudah kompleks pun menjadi lebih mudah. Selain itu, function/method yang ditulis dapat digunakan kembali di tempat lainnya (reusable). Misalnya, satu function dapat digunakan di dua fitur yang berbeda.

JavaScript awalnya tidak memiliki konsep modularisasi. JavaScript hanya mengenal scope yang sama dari function/method/variable. Namun, semenjak adanya ECMAScript 2015, JavaScript bisa menggunakan konsep modularisasi dan dapat menggunakan keyword import dan export.


Import

JavaScript memungkinkan kita untuk menggunakan function/method dari modul lainnya dengan dua syarat: 

  • Harus meng-import function/method tersebut.
  • Function/method tersebut sudah di-export (export akan dibahas di materi selanjutnya). 

Import dapat dilakukan dengan menulis kata kunci import kemudian diikuti oleh nama function/method/variable. Perhatikan contoh berikut ini.


Export

Export adalah keyword yang kita gunakan untuk melabeli suatu function/method/variable agar dapat diakses dari luar modul saat ini. Export terdiri dari dua jenis, yaitu default export dan named export. Perhatikan contoh named export berikut ini.

  1. ekspor konstanta nama = 'John';
  2. ekspor konstanta email = 'john@gmail.com';
  3. ekspor konstanta usia = 25;

Cara tersebut merupakan cara export sebelum deklarasi dilakukan. Cara lainnya adalah export setelah deklarasi dilakukan seperti berikut ini.

  1. konstanta nama = 'John';
  2. const email = 'john@gmail.com';
  3. usia konstan = 25;
  4. ekspor { nama, email, usia };


Mengekspor Variable

Misalnya, ada suatu module yang ditulis di berkas module.js. Di dalam berkas tersebut, kita akan menulis satu variabel yang akan kita ekspor. Untuk mengekspornya dapat dilakukan seperti berikut.

  1. export const name = 'Dicoding';

Mengekspor Function

Cara untuk mengekspor function tak berbeda jauh dengan cara mengekspor variable.

  1. export const name = 'John';
  2. export const favoriteFood = ['pizza', 'pasta', 'sushi'];
  3. export function sayHi(name) {
  4.   console.log(`Hi, ${name}!`);
  5. }


Mengimpor Variable

Tadi kita sudah mengekspor beberapa nilai dan function di berkas module.js. Sekarang, tambahkan berkas baru bernama index.js yang akan kita gunakan untuk mengimpor dan menggunakan variable dan function yang telah diekspor sebelumnya.

  1. import { name, favoriteFood } from './module.js';


Mengimpor Function

Untuk mengimpor function dapat dilakukan dengan cara berikut ini.

  1. import { name, favoriteFood as food, sayHi } from './module.js';
  2. console.log(name);
  3. console.log(food);
  4. sayHi(name);


Menggunakan Modularisasi ESM di Node.js

Karena ESModule adalah barang baru di dunia persilatan Node.js, kita perlu menambahkan konfigurasi dalam project Node.js. Kalau Anda mengikuti latihan di modul ini pada lokal komputer, Anda akan mengalami error ketika menggunakan import dan export. Mungkin beberapa dari Anda sudah menyadari akan hal ini dan telah mencari solusi error dengan berselancar di internet.

Sebenarnya, kita hanya membutuhkan konfigurasi sederhana. Berikut cara yang dapat kita terapkan jika ingin menggunakan ES Modul di Node.js.

Mengubah ekstensi berkas

Cara pertama yaitu mengubah ekstensi berkas dari .js menjadi mjs. Dengan mengubah format ini, kita memberitahu ke Node.js bahwa kita ingin menggunakan ESModule. Cara ini terbilang sangat sederhana. Namun, bagaimana jika berkas project Anda sangat banyak? Tidak mungkin Anda mengubahnya satu per satu karena pasti memakan waktu cukup lama dan tidak efisien.

Menambahkan konfigurasi di package.json

Cara berikut ini akan menyelesaikan masalah yang ada pada cara sebelumnya yaitu dengan menambahkan konfigurasi pada level package. Dengan menambahkan konfigurasi pada level package, kita tidak perlu lagi untuk mengganti ekstensi berkas menjadi .mjs dan cara inilah yang kami lakukan sepanjang modul ini.


Menggunakan Modularisasi ESM di Browser

ESModule tak hanya dapat digunakan pada Node.js, tetapi juga di browser. Hal ini merupakan kabar gembira bagi Web Developer, khususnya Front-End Developer yang banyak berkecimpung di browser. Penasaran bagaimana caranya?

Caranya adalah dengan menambahkan type pada saat memanggil tag script seperti contoh berikut ini.

  1. <script src="./esmodule.js" type="module">

Dengan begitu, Anda dapat memuat berkas JavaScript sebagai ESModule pada berkas HTML dan dijalankan di browser. Perlu diingat bahwa tidak semua browser mendukung ESModule sehingga untuk menangani hal itu, tambahkan kode berikut ini.

  1. <script nomodule src="fallback.js"></script>

Atribut nomodule akan memberitahu browser untuk memuat berkas fallback.js jika tidak mendukung ESModule.


Video Bekerja Secara Modular di JavaScript

Untuk memperdalam dan mempermudah pemahaman pada materi ini, Anda dapat menyimak video pembahasan berikut.

Bersambung ke: KUIS MODULAR HARMONIS


Comments