Lompat ke konten
dokumentasi.id
Commit bd74801
v1
Star10 rb

Kamu membaca versi lama. Halaman ini hanya bisa dibaca.

9

Build dan Distribusi

npm run build menjalankan dua tahap secara berurutan: ./script/build-esm.js lebih dahulu, lalu ./script/build-dist.sh. Keduanya dirangkai dengan &&, sehingga tahap kedua tidak dijalankan bila tahap pertama gagal package.json:245. Varian build+test hanya menambahkan npm run test di belakang rantai yang sama package.json:246.

Tahap pertama bekerja di dalam src/ dan menghasilkan berkas ESM serta satu berkas deklarasi tipe. Tahap kedua membaca hasil tahap pertama dan memanggil uglifyjs untuk mengisi dist/.

graph LR
  SRC["src/**/*.js (CommonJS)"]
  ESM["script/build-esm.js"]
  MJS["src/**/*.mjs + ua-parser-enums.d.ts"]
  DIST["script/build-dist.sh"]
  MIN["dist/ua-parser.min.js + .min.mjs"]
  PACK["dist/ua-parser.pack.js + .pack.mjs"]
  SRC --> ESM --> MJS --> DIST
  DIST --> MIN
  DIST --> PACK
  style SRC fill:#2d7d46,color:#fff
  style ESM fill:#f59e0b,color:#000
  style MJS fill:#8b5cf6,color:#fff
  style DIST fill:#f59e0b,color:#000
  style MIN fill:#8b5cf6,color:#fff
  style PACK fill:#8b5cf6,color:#fff
%% fig: Rantai build dari src ke dist
%% desc: build-esm.js mengubah sumber CommonJS menjadi .mjs, lalu build-dist.sh memanggil uglifyjs untuk menghasilkan empat berkas di dist.
Fig. 1: Rantai build dari src ke distbuild-esm.js mengubah sumber CommonJS menjadi .mjs, lalu build-dist.sh memanggil uglifyjs untuk menghasilkan empat berkas di dist.

Tahap 1: script/build-esm.js

Skrip ini tidak memakai parser JavaScript. Ia membaca berkas CommonJS dengan fs.readFileSync, menjalankan deret penggantian regex, lalu menulis hasilnya ke berkas tujuan dengan fs.writeFileSync script/build-esm.js:14-30. Deret replacement default untuk .mjs berisi empat pola berurutan: menambahkan as pada alias const yang diikuti require, mengubah require path relatif menjadi import ... from '.x.mjs', mengubah require paket menjadi import, dan mengubah module.exports = menjadi export script/build-esm.js:5-12.

Setiap berkas hasil diberi tiga baris header sebelum isi hasil transformasi: judul entri, baris // DO NOT EDIT THIS FILE!, dan path sumber asalnya script/build-esm.js:24-29. Header itu terlihat pada berkas hasil yang tersimpan di repository src/main/ua-parser.mjs:1-3.

Daftar target bersifat statis di dalam array files, dan setiap entri dijalankan lewat generateFile script/build-esm.js:32-91, script/build-esm.js:93. Delapan entri dihasilkan dari tujuh berkas sumber, karena src/enums/ua-parser-enums.js dipakai dua kali.

srcdestreplacement
src/main/ua-parser.jssrc/main/ua-parser.mjsempat pola khusus lalu default script/build-esm.js:37-42
src/bot-detection/bot-detection.jssrc/bot-detection/bot-detection.mjsdefault
src/browser-detection/browser-detection.jssrc/browser-detection/browser-detection.mjsdefault
src/device-detection/device-detection.jssrc/device-detection/device-detection.mjsdefault
src/enums/ua-parser-enums.jssrc/enums/ua-parser-enums.mjsdefault
src/enums/ua-parser-enums.jssrc/enums/ua-parser-enums.d.tsempat pola deklarasi tipe script/build-esm.js:68-78
src/extensions/ua-parser-extensions.jssrc/extensions/ua-parser-extensions.mjsdefault
src/helpers/ua-parser-helpers.jssrc/helpers/ua-parser-helpers.mjsdefault

Entri src/main/ua-parser.js menambahkan empat pola khusus sebelum pola default. Pola itu membuang pembungkus fungsi dan komentar jshint lama, menaikkan esversion ke 6, dan menutup berkas dengan export {UAParser}; script/build-esm.js:37-42. Entri src/enums/ua-parser-enums.js yang kedua menghasilkan berkas .d.ts dengan pola sendiri: = object.freeze( menjadi export ...: Readonly<, deklarasi biasa menjadi typeof, }); menjadi }>;, dan baris module.exports dihapus script/build-esm.js:68-78.

Karena konversi dilakukan dengan regex, hasilnya bergantung pada bentuk teks sumber: nama identifier dan urutan pola harus cocok persis dengan yang tertulis di src/.

Tahap 2: script/build-dist.sh

Skrip ini menetapkan enam variabel path lebih dahulu: tiga untuk .js dan tiga untuk .mjs, masing-masing SRC, MIN, dan PACK script/build-dist.sh:3-9. Empat pemanggilan uglifyjs kemudian menulis langsung ke dist/ dengan kombinasi flag berikut script/build-dist.sh:11-23.

KeluaranSumberFlag uglifyjs
dist/ua-parser.min.jssrc/main/ua-parser.js--comments "/^ UA/"
dist/ua-parser.min.mjssrc/main/ua-parser.mjs--comments "/^ UA/" --module
dist/ua-parser.pack.jssrc/main/ua-parser.js--comments "/^ UA/" --compress --mangle
dist/ua-parser.pack.mjssrc/main/ua-parser.mjs--comments "/^ UA/" --compress --mangle --module

Hanya varian pack yang memakai --compress --mangle; varian min mempertahankan nama identifier asli. Flag --module menandai keluaran sebagai ES module untuk sumber .mjs script/build-dist.sh:11-23. Opsi --comments "/^ UA/" mempertahankan banner lisensi, dan banner itu memang muncul di baris pertama artefak dist/ua-parser.min.js:1-3 serta dist/ua-parser.pack.js:1-3.

Biner uglifyjs berasal dari devDependency uglify-js versi ~3.19.3 package.json:275, sehingga npm install atau npm ci harus dijalankan sebelum tahap kedua bisa berhasil.

Pemetaan artefak ke konsumen

Isi dist/ tidak dipakai langsung oleh require atau import bawaan. Field main menunjuk src/main/ua-parser.js, field module menunjuk src/main/ua-parser.mjs, dan field browser menunjuk dist/ua-parser.pack.js package.json:195-199.

graph LR
  PKG["package.json"]
  REQ["require: src/main/ua-parser.js"]
  IMP["import: src/main/ua-parser.mjs"]
  BRW["browser: dist/ua-parser.pack.js"]
  PKG -->|"main"| REQ
  PKG -->|"module"| IMP
  PKG -->|"browser"| BRW
  style PKG fill:#f59e0b,color:#000
  style REQ fill:#336791,color:#fff
  style IMP fill:#8b5cf6,color:#fff
  style BRW fill:#8b5cf6,color:#fff
%% fig: Rute resolusi berkas per field package.json
%% desc: main dan module menunjuk berkas di src, sedangkan browser menunjuk artefak pack di dist.
Fig. 2: Rute resolusi berkas per field package.jsonmain dan module menunjuk berkas di src, sedangkan browser menunjuk artefak pack di dist.

Peta exports mengulang pola yang sama untuk tujuh subpath: require menunjuk .js di src/, import menunjuk .mjs di src/, dan types menunjuk .d.ts di src/ package.json:200-236. Field files yang dikirim ke registry berisi dist/*.?(m)js, dist/icons, dan src, sedangkan bin menunjuk ./script/cli.js package.json:237-242. Karena dist/icons termasuk, direktori itu perlu ada saat artefak didistribusikan. Rincian pemakaian tiap jalur masuk ada di Instalasi dan Penggunaan.

⚠️ Berkas hasil build disimpan di repository. Jangan mengedit src/**/*.mjs atau berkas di dist/ secara manual: header hasil build menyatakan // DO NOT EDIT THIS FILE! script/build-esm.js:24-29, dan pernyataan itu terlihat pada berkas .mjs yang di-commit src/main/ua-parser.mjs:1-3. Ubah src/main/ua-parser.js lalu jalankan npm run build.

⚠️ Workflow publish hanya menjalankan npm ci lalu npm publish --provenance --access public, tanpa npm run build .github/workflows/publish-npm.yml:28-29. Artefak yang terbit karena itu adalah berkas yang sudah di-commit, sehingga dist/ yang usang akan ikut terbit bila lupa di-build ulang.

Workflow CI menjalankan npm run build+test .github/workflows/ci-build-test.yml:41-44, dan script/test-all.sh juga membuka dengan npm run build script/test-all.sh:3-6. Keduanya meregenerasi artefak sebelum pengujian, jadi tidak ada langkah yang membandingkan hasil build dengan berkas yang di-commit. Rangkaian pengujian selengkapnya dibahas di Pengujian dan Kontribusi.