Lompat ke konten
dokumentasi.id
Commit 6ea47ab
v2
Star3,1 rb

4

Alur Build Vite dan Nunjucks

npm run build menjalankan dua tahap terpisah: satu build library untuk app.js, lalu satu build Vite utama yang merender seluruh halaman Nunjucks, menyalin aset, dan mengompilasi SCSS. Setelah vite build selesai, script yang sama langsung menjalankan prettify pada HTML hasil build (package.json:5-14).

Dua build di satu berkas konfigurasi

vite.config.js memanggil fungsi build() milik Vite tepat di top level, sebelum konfigurasi diekspor. Build itu memakai configFile: false, emptyOutDir: false, outDir ke dist/assets/compiled/js, serta lib dengan name: 'app', formats: ['umd'], fileName: 'app', dan entry: './src/assets/js/app.js' (vite.config.js:88-105). Hasilnya satu berkas dist/assets/compiled/js/app.js.

Nilai emptyOutDir: false dipakai di kedua build. Karena itu berkas hasil build library tidak terhapus ketika build utama menulis ke dist (vite.config.js:152-175).

Build utama berasal dari nilai defineConfig (vite.config.js:109-142). Di sana root diarahkan ke src, base diatur './' agar path di HTML hasil build relatif, outDir menunjuk dist, dan manifest: true meminta Vite menulis manifest build. Pengaturan Rollup-nya ada di vite.config.js:152-175: target: "chrome58", input berisi seluruh halaman, entryFileNames menaruh chunk JS di assets/compiled/js/[name].js, dan assetFileNames menghitung folder tujuan dari ekstensi berkas.

Daftar halaman dibentuk getFiles(). Fungsi itu membaca akar src, menyaring berkas berakhiran .html, lalu memakai nama berkas tanpa .html sebagai kunci (vite.config.js:15-26). Objek hasilnya dipakai dua kali: sebagai input Rollup dan sebagai dasar kunci variabel template.

Setiap halaman adalah berkas Nunjucks yang menyetel title dan filename, lalu extends berkas layout (src/index.html:1-4). Isi blok dan pewarisannya dibahas di Sistem Layout dan Blok Nunjucks.

Urutan kerja vite build

sequenceDiagram
    autonumber
    participant CLI as npm run build
    participant CFG as vite.config.js
    participant LIB as build library
    participant NJK as vite-plugin-nunjucks
    participant CPY as viteStaticCopy
    participant RLP as Rollup build utama
    participant PRT as prettier

    CLI->>CFG: jalankan vite build
    CFG->>LIB: build entry src/assets/js/app.js sebagai umd
    Note over CFG,LIB: dipanggil pada top level tanpa await
    LIB-->>CFG: dist/assets/compiled/js/app.js
    CFG-->>CLI: export default defineConfig
    CLI->>RLP: root src dan outDir dist
    RLP->>NJK: getFiles sebagai input dan getVariables sebagai variables
    NJK-->>RLP: HTML ter-render dengan blok terisi
    RLP->>CPY: salin src/assets/static dan copyModules
    CPY-->>RLP: assets/static dan assets/extensions
    RLP-->>CLI: dist/*.html dan assets/compiled
    CLI->>PRT: npm run prettify
    PRT-->>CLI: dist/*.html terformat
%% fig: Siklus satu perintah vite build
%% desc: Perintah npm run build memuat konfigurasi, memicu build library app.js, menjalankan build utama yang merender Nunjucks dan menyalin aset, lalu memformat HTML hasilnya.
Fig. 1: Siklus satu perintah vite buildPerintah npm run build memuat konfigurasi, memicu build library app.js, menjalankan build utama yang merender Nunjucks dan menyalin aset, lalu memformat HTML hasilnya.

Pemanggilan build() pada vite.config.js:88-105 tidak memakai await, jadi ia berjalan sebagai efek samping saat berkas konfigurasi dimuat. Setelah itu Vite memakai objek hasil defineConfig untuk build utama dengan root di src.

Saat build utama berjalan, plugin nunjucks merender setiap entri getFiles() memakai templatesDir: root dan variables: getVariables(env.mode) (vite.config.js:125-141). Di titik yang sama viteStaticCopy menyalin aset statis, font hasil kompilasi, bootstrap-icons.svg, dan seluruh target copyModules (vite.config.js:113-124).

Variabel yang disuntikkan ke template

getVariables membuat satu entri per halaman dengan kunci <nama berkas>.html. Isinya web_title, sidebarItems, horizontalMenuItems, dan isDev: mode === 'development' (vite.config.js:28-40). Dua daftar menu itu berasal dari impor JSON di kepala konfigurasi dan diuraikan lebih lanjut di Data Navigasi Sidebar dan Menu Horizontal. Cabang filename.includes('layouts') menyiapkan kunci layouts/<nama>.html, meski getFiles() hanya mengumpulkan berkas .html di akar src (vite.config.js:15-26).

Nilai isDev menentukan script mana yang dimuat halaman. Pada mode development halaman memuat assets/js/app.js dengan type="module", sedangkan pada build ia memuat assets/compiled/js/app.js (src/layouts/master.html:35-39). Artinya vite biasa bekerja dengan sumber mentah, sedangkan vite build dan vite build --watch memakai hasil kompilasi.

Isi app.js tipis: ia memanggil featherIcons.replace() lalu mengimpor ./mazer (src/assets/js/app.js:1-8). Di mazer.js bundle Bootstrap dipasang ke window.bootstrap dan komponen sidebar diimpor dari ./../static/js/components/sidebar (src/assets/js/mazer.js:1-8). Keduanya ter-bundle menjadi satu app.js format UMD.

Peta masukan ke artefak dist

graph LR
  SRC["src/*.html hasil getFiles"] --> NJK["vite-plugin-nunjucks"]
  NJK --> HTML["dist/*.html"]
  HTML --> PRETTY["prettier --write"]
  JS["src/assets/js/app.js"] --> LIB["build library umd"]
  LIB --> APP["dist/assets/compiled/js/app.js"]
  SCSS["assets/scss/app.scss"] --> CSS["assets/compiled/css/*.css"]
  STATIC["src/assets/static"] --> COPY["viteStaticCopy"]
  MOD["node_modules modulesToCopy"] --> COPY
  COPY --> EXT["assets/extensions dengan nama modul"]
style SRC fill:#f59e0b,color:#000
style JS fill:#f59e0b,color:#000
style SCSS fill:#f59e0b,color:#000
style MOD fill:#f59e0b,color:#000
style LIB fill:#f59e0b,color:#000
style NJK fill:#8b5cf6,color:#fff
style STATIC fill:#8b5cf6,color:#fff
style COPY fill:#8b5cf6,color:#fff
style HTML fill:#2d7d46,color:#fff
style APP fill:#2d7d46,color:#fff
style CSS fill:#2d7d46,color:#fff
style EXT fill:#2d7d46,color:#fff
style PRETTY fill:#2d7d46,color:#fff
%% fig: Peta masukan build ke artefak dist
%% desc: Setiap jenis masukan berakhir di folder dist yang berbeda, dari HTML hasil render sampai ekstensi yang disalin apa adanya.
Fig. 2: Peta masukan build ke artefak distSetiap jenis masukan berakhir di folder dist yang berbeda, dari HTML hasil render sampai ekstensi yang disalin apa adanya.

Tahapan yang sama bila dibaca sebagai daftar:

#Yang dieksekusiKeluaran
1build() library app.js (vite.config.js:88-105)dist/assets/compiled/js/app.js
2plugin nunjucks merender tiap entri getFiles() (vite.config.js:125-141)dist/*.html
3viteStaticCopy menyalin aset dan ekstensi (vite.config.js:113-124)dist/assets/static, dist/assets/extensions
4Rollup membundel entri halaman dan CSS yang dirujuknya (vite.config.js:152-175)assets/compiled/js/[name].js, assets/compiled/css/*.css
5prettier --write 'dist/*.html' lewat npm run prettify (package.json:5-14)HTML rapi di dist

Tabel modulesToCopy menentukan cakupan salinan: nilai true hanya menyalin subfolder dist paket, nilai false menyalin seluruh isi paket. copyModules mengubah peta itu menjadi target viteStaticCopy dengan dest: 'assets/extensions' dan rename berisi nama modul (vite.config.js:42-86).

Dua hal kecil yang mudah terlewat dari konfigurasi. Pertama, publicDir diisi 'static' relatif terhadap root src, sedangkan direktori src/static tidak ada, sehingga aset statis tetap masuk lewat viteStaticCopy (vite.config.js:109-142). Kedua, assetFileNames memakai a.name.split('.')[1] untuk menentukan folder, dan memindahkan woff, woff2, serta ttf ke fonts/ (vite.config.js:152-175). Seluk-beluk berkas SCSS yang menjadi masukan tahap 4 dibahas di Arsitektur SCSS dan Variabel Tema.

Jebakan yang perlu diingat

⚠️ Kedua build memakai emptyOutDir: false (vite.config.js:88-105). Berkas lama di dist tidak dibersihkan, jadi hasil build sebelumnya bisa tertinggal dan ikut masuk ke dist.zip lewat npm run zip (package.json:5-14).

⚠️ dist/* diabaikan git (.gitignore:13-13), dan CONTRIBUTING.md meminta agar berkas hasil build tidak ikut di-commit; semua perubahan dilakukan di src (CONTRIBUTING.md:9-17).

⚠️ Pemanggilan build() di vite.config.js:88-105 tidak di-await, sehingga urutannya bergantung pada penyelesaian promise saat konfigurasi dimuat. Bila app.js hasil library terasa tidak konsisten, hapus dist/assets/compiled/js/app.js lalu jalankan npm run build ulang.

Untuk keperluan demo dan rilis, hasil dist inilah yang dipakai; lihat Deploy Demo dan Rilis. Perintah pengembangan sehari-hari ada di Instalasi dan Menjalankan Lokal.