Mengapa `serve` menampilkan situs jelek sementara `publishSite` sempurna
Diterbitkan 22 April 2026
Apakah Anda pernah mengalami saat ketika situs lokal Anda terlihat tidak ada, tapi setelah dideploy online semuanya menjadi sempurna? Itu yang terjadi dengan plugin Gradle JBake saya. Tugas`serve`Menampilkan tombol berbentuk kotak, teks gelap di latar belakang hitam, dan CSS yang aneh tidak ada. Namun`publishSite`Menghasilkan situs yang sama, itu, sempurna. Penyebabnya bukan CSS, bukan peramban, bukan cache. Ini adalah satu baris kode Kotlin — dan kebiasaan buruk dengan argumen baris perintah.
- ketuk
-
[]
Adegan: empat screenshot, dua rendering
Itu terjadi setelah sistem crash. Saya telah membuat empat tangkapan layar untuk membandingkan rendering lokal (./gradlew serve`pada`localhost:8820) dengan rendering inline (`publishSite`pada GitHub Pages). Dua screenshot per halaman : bagian atas dan bagian bawah.
Render lokal
Atas halaman— Tombol Project dan Template adalahkecil, persegi panjang, ke warna standar (biru dan hijau). Kartu Start Writing memiliki sebuahlatar belakang hitam polos, tanpa kerangka.
Bawah halaman— Subjudul Artikel dan Sumber Daya Terbaru adalahhampir tidak dapat dibaca, terlalu gelap di latar hitam. Tanggal di bawah gambar blog ("17 October 2013", dst.) adalahtidak hadir.
Dirender secara online
Bagian atas halaman— Tombol-tombol yang sama adalahbesar, domba, hijau neon mencolok, teks dalam huruf besar. Kartu memiliki satubingkai putih melengkung dengan bayangan jatuh.
footer— Subjudul adalahmudah dibaca. Tanggal adalahterlihat. Kartu artikel memilikisudut melengkungdan judul-judul adalahtebal.
Refleks pertama: tema. Saya menggunakan sistem tema dinamis (terang, gelap, kontras tinggi) berdasarkan`localStorage`. Mungkin bahwa toko lokal memicu tema kontras tinggi? Tidak. Saya sudah menulis sebelumnya.https://cheroliv.com/blog/2025/0098_preloading_css_variable_post.html[sebuah artikel lengkap tentang pra-pemuatan tema], saya tahu cara kerjanya. Dan kemudian, bahkan dalam mode high-contrast, struktur CSS (tombol oval, bayangan) seharusnya ada di sana. Dia tidak ada di sana.
Refleks kedua: cache browser. Tidak, saya sudah menguji dengan profil bersih. Perbedaannya tetap ada.
Refleks ketiga :`serve`tidak menyajikan file yang sama seperti`publishSite`.
Diagnosa : serve tidak menunjuk ke direktori yang benar
Plugin Gradle saya`bakery`memiliki dua tugas utama:
-
bake: menghasilkan situs statis di`build/bake/` -
serve: menjalankan server web lokal -
publishSite: tunas`build/bake/`ke GitHub Pages
Divergensi hanya bisa datang dari`serve`. Si publishSite`mempublikasikan konten yang benar, itu adalah`build/bake/`adalah baik. Jika`serve`menampilkan hal lain, berarti ia tidak berfungsi`build/bake/.
Mari kita lihat kode. Di`SiteManager.kt`, tugas`serve`adalah didefinisikan seperti ini :
tasks.register("serve", JavaExec::class.java) { task ->
task.apply {
mainClass.set("org.jbake.launcher.Main")
classpath = jbakeRuntime
environment("GEM_PATH", jbakeRuntime.asPath)
jvmArgs(/* ... */)
args = listOf(
"-b", file(site.bake.srcPath).absolutePath,
"-s", layout.buildDirectory.get()
.asFile.resolve(site.bake.destDirPath)
.absolutePath
)
}
}
org.jbake.launcher.Main`adalah titik masuk CLI JBake 2.7.0. Ideanya: melewati-b`untuk folder sumber dan`-s`untuk folder tujuan, lalu jalankan mode server. Kecuali…
Penyebab utama: JBake CLI tidak berfungsi seperti itu
JBake 2.7.0 menunggu beberapaargumen posisiuntuk sumber dan tujuan, lalu flags opsional. Tanda tandanya adalah :
jbake <source> <destination> [options]
Namun di kode saya, saya menulis:
args = listOf("-b", "/path/to/site", "-s", "/path/to/build/bake")
JBake mengartikannya sebagai :
-
-b→ parse flag 'bake' (boolean), telah dikonsumsi -
/path/to/site→ menjadi argumen posisi 1 (sumber) -
-s→ mengurai flag "serve" (boolean), server dimulaisegera -
`/path/to/build/bake`menjadi sebuah argumen yang terasing, diabaikan atau salah ditafsirkan
Hasil : JBake sedang mengambil`/path/to/site`sebagai sumber,tidak mempertimbangkan destinasiyang disediakan (build/bake), dan menggunakan repertoar standar-nya (sering`./output`atau salinan sementara). File`css/styles.css`Build tersebut sehingga di-overwrite atau diabaikan, dan CSS default lama (tanpa variabel kustom, tanpa radius, tanpa bayangan) yang disajikan.
Dalam perbandingan,bake et publishSite`menggunakanplugin Gradle JBake resmi( )`jbake-gradle-plugin) yang menulis dengan rapi di`build/bake/`via Gradle API. Mereka tidak melewati CLI.
Solusi: argumen positional, bukan flag
Koreksi ini trivial — setelah tahu. Cukup meneruskan sumber dan destinasi sebagai argumen posisional, lalu`-s`akhirnya :
args = listOf(
file(site.bake.srcPath).absolutePath,
layout.buildDirectory.get()
.asFile.resolve(site.bake.destDirPath)
.absolutePath,
"-s"
)
Itu saja. Tiga baris diubah, bug telah diperbaiki.
Setelah publikasi lokal plugin ini ()publishToMavenLocal), un `./gradlew serve`Menjalankan JBake dengan sintaksis yang benar :
jbake /home/user/project/site /home/user/project/build/bake -s
Dan kali ini, server Jetty yang terintegrasi dengan JBake melayani konten dari`build/bake/`— sama dengan yang dipublikasikan secara online.
@startuml
!define RECTANGLE class
package "SEBELUM (bug)" {
RECTANGLE JBakeCLI1 {
+ args = ["-b", "situs", "-s", "membangun/memanggang"]
}
RECTANGLE Source1 {
+ site/
}
RECTANGLE Dest1 {
+ ??? (dossier temporaire)
}
RECTANGLE Jetty1 {
+ sert mauvais fichiers
}
JBakeCLI1 --> Source1 : lit
JBakeCLI1 -[#red]x Dest1 : destination ignorée
Jetty1 --> Dest1 : sert
}
package "SETELAH (perbaikan)" {
RECTANGLE JBakeCLI2 {
+ args = ["situs", "membangun/memanggang", "-s"]
}
RECTANGLE Source2 {
+ site/
}
RECTANGLE Dest2 {
+ build/bake/
}
RECTANGLE Jetty2 {
+ sert les bons fichiers
}
JBakeCLI2 --> Source2 : lit
JBakeCLI2 --> Dest2 : écrit dans
Jetty2 --> Dest2 : sert OK
}
@enduml
Pemeriksaan cepat dengan curl
Agar memastikan bahwa server menyajikan dengan baik konten yang benar, sebuah sederhana`curl`mengonfirmasi bahwa`index.html`mengandung`data-bs-theme="light"`dan bahwa`build/bake/css/styles.css`beratnya tepat 31 402 byte — identik dengan file yang dihasilkan oleh`bake`.
$ ./gradlew serve
# Dans un autre terminal :
$ curl -s http://localhost:8820/ | grep data-bs-theme
<html ... data-bs-theme="light" ...>
$ curl -I http://localhost:8820/css/styles.css
HTTP/1.1 200 OK
Content-Length: 31402
Content-Type: text/css
Render lokal sekarangpixel-identikke render dideploy.
Mengapa bug ini jahat?
Kamu tahu mengapa ini sulit ditangkap?
-
Tidak ada kesalahan eksplisitJBake tidak crash. Dia "berfungsi", hanya dengan sebuah direktori yang salah.
-
Build berfungsi:`./gradlew bake`membuat dengan benar file-file di`build/bake/`.
-
Penerapan berfungsi:`publishSite`mengunggah konten yang baik secara online
-
Hanya
serveyang rusak: tugas pengembangan, yang selalu digunakan untuk iterasi. -
Kebiasaan
-key value: sebagai seorang developer, kita dikondisikan oleh beberapa tahun CLI Unix (-o output`,-i input). JBake CLI adalah sebuah pengecualian — sumber dan destinasi bersifat posisi.
Kesimpulan
Jika Anda memelihara plugin Gradle yang membungkus JBake (atau alat CLI apa pun),baca dokumentasi argumenmeskipun Anda kira Anda mengenal mereka. Sebuah hipotesis implisit (-s= "set destination") dapat menguras waktu berjam-jam untuk debug visual.
Di sini, perbaikan itu secara harfiah adalah mengubah:
args = listOf("-b", src, "-s", dest) // ❌ BUG
en :
args = listOf(src, dest, "-s") // ✅ FIX
Tiga token telah dipindahkan, dan situs lokal saya kembali sama indah dengan situs produksi.
Pelajaran: ketika rendering berbeda antara lokal dan produksi tanpa alasan jelas, pertimbangkan dulu pipeline — bukan CSS, bukan browser, dan jauh lebih bukan framework. Seringnya langkah sebelum rendering yang menipu.