Sebelum spesifikasi CommonJs diusulkan, Javascript tidak memiliki sistem modul, yang berarti sulit bagi kami untuk mengembangkan aplikasi skala besar karena pengorganisasian kode akan lebih sulit.
Pertama-tama, CommonJS tidak unik untuk Node. CommonJS adalah spesifikasi modul yang mendefinisikan cara mereferensikan dan mengekspor modul. Nodejs hanya mengimplementasikan spesifikasi ini. Spesifikasi modul CommonJS terutama dibagi menjadi tiga bagian: referensi modul, definisi modul, dan identifikasi modul .
modul Referensi modul
berarti kita dapat memperkenalkan modul lain melalui require
.
const { tambahkan } = memerlukan('./tambah'); const result = add(1,2);
Module mendefinisikan
file sebagai modul, dan modul akan menyediakan dua variabel, yaitu modul dan ekspor. module adalah modul itu sendiri, ekspor adalah konten yang akan diekspor, dan ekspor adalah atribut modul, yaitu ekspor adalah modul.ekspor. Konten yang diimpor oleh modul lain melalui require adalah konten dari module.exports.
// tambahkan.js ekspor.tambahkan = (a, b) => { kembalikan a+b; }
Identifikasi modul
Identifikasi modul adalah konten yang dibutuhkan. Misalnya require('./add')
, maka identifikasi modulnya adalah ./add
.
Mekanisme impor dan ekspor modul yang dibangun melalui CommonJS memungkinkan pengguna dengan mudah membangun aplikasi berskala besar tanpa harus mempertimbangkan variabel polusi.
Implementasi modul simpul
Node mengimplementasikan spesifikasi CommonJs dan menambahkan beberapa fitur yang diperlukan. Node terutama melakukan tiga hal berikut untuk mengimplementasikan spesifikasi CommonJs:
Penempatan file
analisis jalur
, kompilasi dan eksekusi
analisis jalur
Ketika require() dijalankan, parameter yang diterima oleh require adalah pengidentifikasi modul, dan node melakukan analisis jalur melalui pengidentifikasi modul. Tujuan dari analisis jalur adalah untuk menemukan jalur dimana modul ini berada melalui pengenal modul. Pertama-tama, modul node dibagi menjadi dua kategori, yaitu modul inti dan modul file. Modul inti adalah modul yang disertakan dengan node, dan modul file adalah modul yang ditulis oleh pengguna. Pada saat yang sama, modul file dibagi menjadi modul file dalam bentuk jalur relatif, modul file dalam bentuk jalur absolut, dan modul file dalam bentuk non-jalur (seperti ekspres).
Ketika node menemukan modul file, ia akan mengkompilasi, mengeksekusi, dan menyimpan modul dalam cache. Prinsip umumnya adalah menggunakan jalur lengkap modul sebagai kunci dan konten yang dikompilasi sebagai nilainya untuk kedua kalinya. Kemudian lakukan analisis jalur, lokasi file, kompilasi dan eksekusi langkah-langkah ini.
//Diagram modul cache: const cachedModule = { '/Usr/file/src/add.js': 'Konten yang dikompilasi dari add.js', 'http': 'Kompilasi konten modul http yang disertakan dengan Node', 'express': 'Konten yang dikompilasi dari modul file kustom non-jalur ekspres' // ... }
Bila ingin mencari modul yang diimpor berdasarkan kebutuhan, urutan pencarian modul adalah memeriksa terlebih dahulu apakah modul sudah ada di cache. Jika tidak ada di cache, periksa modul inti, lalu cari modul file. Diantaranya, modul file dalam bentuk path lebih mudah ditemukan. Path file lengkap dapat diperoleh berdasarkan path relatif atau absolut. Relatif sulit untuk menemukan modul file khusus dalam bentuk non-jalur. Node akan mencari file dari folder node_modules.
Di mana direktori node_modules? Misalnya, file yang sedang kita jalankan adalah /Usr/file/index.js
; * /Usr/file/index.js; */ const { tambahkan } = memerlukan('tambah'); const result = add(1, 2);
Pada modul ini, kami telah memperkenalkan modul add. Add ini bukan modul inti atau modul file dalam bentuk path.
Modul memiliki atribut path. Jalur untuk menemukan modul add ada di atribut path. Kita dapat mengetikkan atribut ini untuk melihatnya:
/** * /Usr/file/index.js; */ console.log(module.paths);
Kita dapat mencetak nilai jalur dengan mengeksekusi node index.js di direktori file. Nilai dalam path adalah array, sebagai berikut:
[ '/Usr/file/node_modules', '/Usr/node_modules', '/node_modules', ]
Artinya, Node akan mencari secara berurutan dari direktori di atas untuk melihat apakah direktori tersebut berisi modul add. Prinsipnya mirip dengan rantai prototipe. Pertama, mulailah mencari di folder node_modules di direktori yang levelnya sama dengan file yang sedang dijalankan. Jika direktori node_modules tidak ditemukan atau tidak ada, lanjutkan pencarian ke level atas.
Analisis jalurlokasi file
dan lokasi file digunakan bersama-sama. Pengidentifikasi file bisa tanpa akhiran, atau direktori atau paket dapat ditemukan melalui analisis jalur.
Analisis ekstensi file
const { add } = require('./add');
Misalnya pada kode di atas, pengidentifikasi file tidak memiliki ekstensi , dan .node secara berurutan.
Analisis direktori dan paket
sama dengan kode di atas. Apa yang ditemukan melalui ./add
mungkin bukan file, tetapi mungkin direktori atau paket (nilai apakah itu direktori atau paket dengan menilai apakah ada paket. file json di folder tambah). Saat ini langkah-langkah untuk memposisikan file adalah sebagai berikut:
Jika tidak ada bidang utama di package.json, indeks juga akan digunakan sebagai file, dan kemudian analisis ekstensi akan dilakukan untuk menemukan file dengan akhiran yang sesuai .
Kompilasi modul
Modul utama yang kita temui dalam pengembangan adalah modul json dan modul js.
kompilasi modul json
Ketika kita membutuhkan modul json, Node sebenarnya akan membantu kita menggunakan fs.readFilcSync untuk membaca file json yang sesuai, mendapatkan string json, dan kemudian memanggil JSON.parse untuk mengurai untuk mendapatkan objek json, dan kemudian menetapkannya ke modul tersebut diekspor, lalu diberikan sesuai kebutuhan.
kompilasi modul js
Ketika kita membutuhkan modul js, seperti
//index.js const { tambahkan } = memerlukan('./tambahan');
// tambahkan.js ekspor.tambahkan = (a, b) => { kembalikan a+b; }
Apa yang terjadi saat ini? Mengapa kita bisa menggunakan modul variabel, mengekspor, dan memerlukan langsung di modul. Hal ini dikarenakan Node membungkus isi modul terlebih dahulu dan terakhir pada saat mengkompilasi modul js.
Misalnya, modul add.js akan dikemas ke dalam struktur yang mirip dengan ini ketika dikompilasi:
(function(require, ekspor, module) { ekspor.tambahkan = (a, b) => { kembalikan a+b; } kembali modul.ekspor; })(require, module.exports, module)
Artinya, file js yang kita tulis akan dikemas ke dalam suatu fungsi. Yang kita tulis hanyalah konten dalam fungsi ini, dan proses pengemasan Node selanjutnya disembunyikan dari kami. Fungsi ini mendukung penerusan beberapa parameter, termasuk kebutuhan, ekspor, dan modul.
Setelah file js dikompilasi, file tersebut akan dieksekusi. Node akan meneruskan parameter yang sesuai ke fungsi ini dan kemudian menjalankannya, dan mengembalikan nilai module.exports ke fungsi yang diperlukan.
Di atas adalah proses dasar Node untuk mengimplementasikan spesifikasi CommonJs.