Sebagai "singa pengepungan" front-end, Webpack sudah sangat familiar. Webpack dapat melakukan terlalu banyak hal. Ia dapat mengemas semua sumber daya (termasuk JS, TS, JSX, gambar, font, CSS, dll.) dan menempatkannya dalam dependensi. . , memungkinkan Anda mereferensikan dependensi untuk menggunakan sumber daya sesuai kebutuhan Anda. Webpack telah melakukan pekerjaan luar biasa dalam menerjemahkan banyak sumber daya file di front-end dan menganalisis ketergantungan modul yang kompleks. Kita juga dapat menyesuaikan pemuat dan memuat sumber daya kita sendiri dengan bebas. Datang dan lihatlah hari ini.
1. Apa yang dibutuhkan?
Ketika berbicara tentang require, hal pertama yang terlintas dalam pikiran mungkin adalah import. Import adalah standar sintaksis es6
– require adalah panggilan runtime, jadi require secara teoritis dapat digunakan di mana saja dalam kode –
import adalah waktu kompilasi panggilan, jadi harus ditempatkan di awal file;
Saat kita menggunakan Webpack untuk mengkompilasi, kita akan menggunakan babel untuk menerjemahkan impor ke dalam require AMD dan CMD juga menggunakan metode require sebagai referensi.
Misalnya:
var add = require('./a.js');Secara sederhana,
add(1,2)
require sebenarnya adalah sebuah fungsi, dan ./a.js
yang direferensikan hanyalah parameter dari fungsi tersebut.
2. Apa yang dimaksud dengan ekspor?
Di sini kita dapat menganggap ekspor sebagai sebuah objek. Anda dapat melihat penggunaan spesifik ekspor MDN.
Mari kita lihat dulu struktur kode setelah pengemasan. Kita dapat menemukan bahwa persyaratan dan ekspor akan muncul setelah pengemasan.
Tidak semua browser dapat menjalankan ekspor yang diperlukan. Anda harus menerapkan persyaratan dan ekspor sendiri untuk memastikan pengoperasian normal kode. Kode yang dikemas adalah fungsi yang dijalankan sendiri. Parameternya memiliki informasi ketergantungan dan kode file. Badan fungsi yang dieksekusi mengeksekusi kode melalui eval.
Gambar desain keseluruhannya adalah sebagai berikut:
Langkah 1: Tulis file konfigurasi kami.
File konfigurasi mengonfigurasi entri paket dan keluaran paket kami untuk mempersiapkan file yang dihasilkan berikutnya.
const jalur = memerlukan("jalur"); modul.ekspor = { entri: "./src/index.js", keluaran: { jalur: path.resolve(__dirname, "./dist"),//Output alamat file setelah pengemasan memerlukan jalur absolut, sehingga jalur diperlukan nama file:"main.js" }, mode: "pengembangan"
Langkah 2: Gagasan keseluruhan analisis modul
: Singkatnya, ini adalah menggunakan file fs untuk membaca file entri dan mendapatkan jalur file yang bergantung pada impor melalui AST Jika file yang bergantung masih memiliki ketergantungan, terus berulang hingga analisis ketergantungan jelas, dipertahankan dalam peta.
Rincian terperinci : Beberapa orang mungkin bertanya-tanya mengapa AST digunakan karena AST dilahirkan dengan fungsi ini. ImportDeclaration-nya dapat membantu kita dengan cepat memfilter sintaks impor string setelah dibaca. Dengan menulis The awesome regex berguna untuk mendapatkan jalur ketergantungan file, tetapi tidak cukup elegan.
file index.js
import { str } from "./a.js"; console.log(`${str} Webpack`)
file a.js
impor { b} dari "./b.js" ekspor const str = "halo"
file b.js
ekspor const b="bbb"
analisis modul Webpack : gunakan @babel/parser AST untuk mengonversi string yang dibaca dari file menjadi pohon AST, dan @babel/traverse untuk sintaks Analisis dan gunakan ImportDeclaration untuk memfilter impor dan menemukan dependensi file.
const konten = fs.readFileSync(entryFile, "utf-8"); const ast = parser.parse(konten, { sourceType: "modul" }); const dirname = jalur.dirname(entryFile); ketergantungan const = {}; melintasi(ast, { Deklarasi Impor({ simpul }) { //Menyaring impor const newPathName = "./" + path.join(dirname, node.source.value); tanggungan[node.source.value] = newPathName; } }) const { kode } = transformFromAst(ast, null, { preset: ["@babel/preset-env"] }) kembali { entriFile, tanggungan, kode }
Hasilnya sebagai berikut:
Gunakan rekursi atau loop untuk mengimpor file satu per satu untuk analisis ketergantungan. Perhatikan di sini bahwa kami menggunakan loop for untuk menganalisis semua dependensi. Alasan mengapa loop dapat menganalisis semua dependensi adalah karena panjang modul berubah dependensi baru, modul.panjangnya akan berubah.
for (misalkan i = 0; i < this.modules.length; i++) { const item = ini.modul[i]; const { tanggungan } = item; jika (tanggungan) { for (biarkan j pada tanggungan) { this.modules.push(this.parse(tanggungan[j])); } } }
Langkah 3: Tulis fungsi WebpackBootstrap + buat file output.
Tulis fungsi WebpackBootstrap : Hal pertama yang perlu kita lakukan di sini adalah fungsi WebpackBootstrap. Setelah kompilasi, impor kode sumber kita akan diurai ke dalam kebutuhan tidak mengenali require, maka kita harus mendeklarasikannya terlebih dahulu. Bagaimanapun, require adalah sebuah metode. Saat menulis fungsi, Anda juga perlu memperhatikan isolasi cakupan untuk mencegah polusi variabel. Kita juga perlu mendeklarasikan ekspor dalam kode kita untuk memastikan bahwa ekspor sudah ada saat kode dijalankan.
Hasilkan file keluaran : Kami telah menulis alamat file yang dihasilkan di file konfigurasi, dan kemudian menggunakan fs.writeFileSync untuk menulisnya ke folder keluaran.
berkas(kode) { const filePath = path.join(ini.output.path, this.output.nama file) const kode baru = JSON.stringify(kode); // Hasilkan konten file bundel const bundle = `(fungsi(modul){ fungsi memerlukan(modul){ jalur fungsiMemerlukan(relativePath){ kembali memerlukan(modul[modul].tanggungan[relativePath]) } const ekspor={}; (fungsi(membutuhkan,ekspor,kode){ evaluasi(kode) })(pathRequire,ekspor,modul[modul].kode); mengembalikan ekspor } memerlukan('${ini.entri}') })(${Kode Baru})`; // WebpackBoostrap // Hasilkan file. Letakkan di direktori dist fs.writeFileSync(filePath,bundle,'utf-8') }
Langkah 4: Analisis urutan eksekusi
Kita dapat menjalankan hasil paket di konsol browser. Jika berfungsi normal, hello Webpack akan dicetak.
Melalui analisis di atas, kita harus memiliki pemahaman dasar tentang proses umum Webpack. Menggunakan AST untuk mengurai kode hanyalah cara demonstrasi, bukan implementasi sebenarnya dari Webpack memiliki metode parsing AST sendiri selalu berubah. Ekosistem Webpack sangat lengkap. Anak-anak yang tertarik dapat mempertimbangkan tiga pertanyaan berikut: