Setelah kasir kafénya dipecah menjadi dua berkas, Budi menaruh seluruh rumus harga ke satu berkas khusus matematika.mjs. Satu module itu perlu menawarkan lebih dari satu hal: konstanta tarif pajak, fungsi penghitung diskon, dan fungsi penghitung pajak. Inilah kegunaan utama named export — satu module boleh menawarkan banyak nilai, masing-masing dengan nama yang jelas, dan pengimpor bebas memilih hanya nama yang dibutuhkan.
Chapter ini membahas dua gaya penulisan named export, cara mengimpornya, serta beberapa aturan yang perlu dipegang agar module tetap mudah dibaca. Seperti chapter sebelumnya, setiap contoh diuji nyata dengan node di terminal.
Menawarkan Banyak Nilai dengan Export Bernama #
Named export adalah pengikatan (binding) yang ditawarkan module dengan sebuah nama. Pengimpor wajib menyebut nama yang sama di dalam kurung kurawal — itulah yang membuatnya “bernama”. Berkas matematika.mjs berikut memakai kedua gaya penulisan sekaligus: satu export inline dan satu daftar export di akhir berkas:
// matematika.mjs — rumus harga untuk kasir kafe
export const PAJAK = 0.11;
function hitungDiskon(total, persen) {
return Math.round(total * (persen / 100));
}
function hitungPajak(total) {
return Math.round(total * PAJAK);
}
export { hitungDiskon, hitungPajak };Perhatikan bahwa PAJAK diexport langsung pada deklarasi (gaya inline), sedangkan kedua fungsi dideklarasikan terlebih dahulu tanpa kata export, lalu ditawarkan bersama melalui satu baris daftar export di akhir berkas. Kedua gaya menghasilkan jenis export yang sama; kita membahas pertimbangan memilihnya sebentar lagi.
Mengimpor yang Dibutuhkan Saja #
Berkas utama.mjs memakai ketiga nilai tersebut untuk menghitung tagihan pesanan seharga Rp50.000 dengan diskon 20 persen:
// utama.mjs — memakai konstanta dan dua rumus dari matematika.mjs
import { PAJAK, hitungDiskon, hitungPajak } from './matematika.mjs';
const total = 50000;
const setelahDiskon = total - hitungDiskon(total, 20);
console.log(hitungDiskon(total, 20));
console.log(setelahDiskon);
console.log(hitungPajak(setelahDiskon));
console.log(PAJAK);Output yang Dihasilkan:
10000
40000
4400
0.11Mari kita telaah baris-baris pentingnya:
- Baris 2 (
import { PAJAK, hitungDiskon, hitungPajak } ...): tiga nama diambil dalam satu pernyataanimport. Urutan penulisan di dalam kurung bebas — tidak harus mengikuti urutan di berkas sumber. - Baris 5–6 (
const setelahDiskon = total - hitungDiskon(total, 20);): fungsi hasil impor dipanggil seperti fungsi biasa.hitungDiskon(50000, 20)menghasilkan10000, sehinggasetelahDiskonbernilai40000. - Baris 8 (
console.log(hitungPajak(setelahDiskon));): pajak 11 persen dari40000menghasilkan4400. Fungsi pajak membaca konstantaPAJAKdari module asalnya — pengimpor tidak perlu mengetahui detail itu. - Baris 9 (
console.log(PAJAK);): konstanta hasil impor terbaca langsung dengan nilainya,0.11.
Nilai yang tidak diimpor tidak ikut keberatan: jika utama.mjs hanya membutuhkan hitungPajak, kita cukup menulis import { hitungPajak } from './matematika.mjs';. Module pengimpor tetap mengetahui sumbernya dengan jelas dari daftar nama.
Mengubah Nama Saat Mengimpor #
Kata kunci as juga bekerja di sisi impor. Bila nama asli kurang pas untuk konteks berkas pengimpor — misalnya utama.mjs sudah memiliki fungsi hitungPajak sendiri untuk kebutuhan lain — kita dapat menamai ulang nilai hasil impor tanpa menyentuh module sumber sama sekali:
import { hitungPajak as pajakItem } from './matematika.mjs';
console.log(pajakItem(20000));Output yang Dihasilkan:
2200Baris pertama mengambil named export hitungPajak dan menamainya pajakItem di berkas ini. Nama hitungPajak tetap utuh di matematika.mjs, dan berkas lain yang mengimpor dengan nama asli tidak terpengaruh — alias hanya hidup di berkas yang menuliskannya. Pajak 11 persen dari 20000 menghasilkan 2200, persis seperti yang dihitung fungsi aslinya.
Satu pembatasan yang perlu dipegang: setelah nama diganti, nama asli tidak lagi tersedia di berkas pengimpor. Menulis hitungPajak(...) di utama.mjs setelah impor di atas berarti mencari nama yang tidak terdaftar, dan hasilnya ReferenceError saat program berjalan. Alias juga menjadi jalan keluar ketika dua module berbeda menawarkan nama yang sama — salah satunya wajib diberi nama lokal baru, karena dua nama identik dalam satu berkas akan ditolak JavaScript. Mekanisme ini muncul lagi di chapter Imports yang merangkum keempat bentuk impor.
Dua Gaya Menulis Export #
Gaya inline dan gaya daftar menghasilkan named export yang identik, tetapi masing-masing punya kelebihan praktis:
| Gaya | Bentuk | Cocok ketika |
|---|---|---|
| Inline | export const PAJAK = 0.11; | Nilai memang dirancang sebagai bagian API sejak awal |
| Daftar di akhir | export { hitungDiskon, hitungPajak }; | Kita ingin satu tempat yang merangkum seluruh isi module |
Kedua gaya juga boleh dicampur dalam satu berkas — matematika.mjs di atas melakukannya. Pertimbangan yang sering dipakai: gaya inline membuat perubahan API terlihat bersamaan dengan perubahan kodenya saat meninjau riwayat berkas, sedangkan daftar di akhir memberi satu titik tinjauan tunggal. Apa pun yang dipilih tim, konsistensinya yang paling berharga — pembaca tidak perlu menebak di mana harus mencari daftar export.
Gaya daftar punya satu fitur tambahan yang tidak dimiliki gaya inline: mengubah nama saat menawarkan, dengan kata kunci as:
function hitungPajak(total) {
return Math.round(total * 0.11);
}
export { hitungPajak as pajakDari };Dengan baris terakhir itu, module menawarkan fungsi tersebut sebagai pajakDari, dan pengimpor menyebut pajakDari — bukan nama aslinya. Fitur ini berguna saat nama internal tidak sempurna untuk dipublikasikan, tanpa perlu mengganti nama di seluruh isi berkas.
Aturan yang Perlu Diingat #
Tiga aturan named export yang paling sering teruji dalam praktik:
- Nama harus unik dalam satu module. Dua deklarasi bernama sama akan ditolak JavaScript jauh sebelum urusan export — pesan
SyntaxError: Identifier '...' has already been declaredmuncul saat berkas dimuat. - Nama yang diimpor harus benar-benar ditawarkan. Mengimpor
hitungDiskadarimatematika.mjsmenghasilkanSyntaxError: The requested module './matematika.mjs' does not provide an export named 'hitungDiska'— galat ini muncul saat program dimuat, sebelum satu baris pun berjalan. - Nama setelah
asmenggantikan nama aslinya. Alias yang ditulis di sisi export menggantikan nama di sisi impor; alias yang ditulis di sisi impor menggantikan nama di berkas pengimpor. Keduanya tidak saling menimpa di module sumber. - Yang ditawarkan adalah pengikatan, bukan salinan nilai. Bila module menexport variabel
letdan mengubah nilainya, pengimpor yang membaca kembali akan melihat nilai terbaru. Sifat live binding ini kita buktikan dengan contoh yang berjalan di chapter Circular Dependencies.
Dengan named exports, satu module dapat menawarkan seluruh perangkat rumusnya secara rapi. Namun sebagian module memang dirancang di sekitar satu nilai utama saja — misalnya satu komponen atau satu fungsi utama — dan untuk pola itu JavaScript menyediakan bentuk export kedua: default exports, topik chapter berikutnya.