Saya ngga suka pakai framework... untuk situs asal-asalan hehe.
Ya tentunya jika membuat situs yang berskala dan terorganisasi, framework pasti sangat direkomendasikan.
Ada Jutaan Cara Untuk Melakukan Satu Hal
Bagaimana cara ngerender situsnya?
Bagaimana cara memanajemeni reaktivitas (state) lintas aplikasi?
Templating apa yang akan digunakan?
SPA atau MPA??
DOM atau V-DOM???
Styling????
FETCHING DATA?!?!?!
BUBUR DIADUK ATAU TIDAK?!!?!!?!!
Sebuah kegilaan tersendiri; Itulah mengapa sepertinya selalu ada framework web baru setiap minggu.
Lagi, saya tidak menolak framework. Sifat alaminya yang ribet, butuh banyak dependency, opinionated, dan segala macam, adalah keunggulan dari sebuah framework — menyempitkan banyaknya solusi dan hanya memilih yang dirasa cocok dan terbaik untuk paradigma mereka.
Tetapi ada rasa yang "menyegarkan" ketika saya bisa bebas untuk sejenak melakukan apa yang saya mau tanpa memikirkan efek jangka panjangnya. Kalau semisalnya nanti ada masalah atau ada implementasi yang harus diubah, ya ubah saja gitu, ngga dikengkang dilema, dan saya rasa situs blog pribadi adalah tempatnya.
Makin tahun, makin tumbuh di otak saya pemikiran bahwa "apapun yang saya implementasi, harus bisa digunakan orang lain juga," saya ngga bisa menjabarkannya, namun pada dasarnya saya punya tendensi untuk memecahbelah application logic. Contohnya kode implementasi gateway harus terpisah dengan kode REST agar gateway bisa digunakan berkali-kali dengan membuat instansi baru, sama halnya dengan REST.
Generator Website Statis / JAMstack
Saya sangat menyukai ide bahwa sebuah situs harus bebas JavaSript — maksudnya sebuah situs hanya akan mengirimkan JavaScript yang dibutuhkan ke klien, jadi sebagian besar (atau bahkan semua) logika aplikasi berada di sisi server.
Saya ingin membaca artikel yang memiliki judul dan konten, jadi berikan kepada saya hal itu saja, sebuah file HTML yang memiliki title, isi konten, dan segala macamnya tanpa mengharuskan browser saya menjalannya JavaScript apapun.
Tentunya menimbulkan banyak limitasi, reaktivitas dan state contohnya. Tetapi kembali lagi, ada jutaan cara untuk melakukan satu hal, seperti yang dilakukan Astro semisalnya.
Cloudflare Pages
Mirip dengan GitHub Pages dan Netlify, sebuah platform untuk mendeploy situs JAMstack yang minim konfigurasi. Tentunya dengan embel-embel dan fiturnya Cloudflare, seperti serverless function di edge network mereka juga integrasi dan tooling yang berorientasi kepada para developer.
Hanya perlu mengunggah berkas-berkas untuk situs statis kalian.
Jadi sekarang pertanyaannya tinggal bagaimana cara mengubah direktori dengan struktur seperti ini:
src/
├── content/
│ ├── post/
│ │ ├── 001.md
│ │ ├── 002.md
│ │ └── 003.md
│ └── public/
│ ├── css/
│ ├── imgs/
│ └── favicon.ico
├── template/
│ ├── index.html
│ └── post.html
└── build.js
Menjadi seperti ini:
bin/
├── post/ # parsing markdown dan pengaplikasian template
│ ├── 001.html
│ ├── 002.html
│ └── 003.html
├── public/ # tidak ada perubahan
│ ├── css/
│ ├── imgs/
│ └── favicon.ico
└── index.html # halaman utama dan daftar post
Markup dan Templating
Saya putuskan untuk menggunakan Markdown untuk markupnya, GitHub Flavored Markdown lebih tepatnya, karena saya sudah sering menulis dokumentasi menggunakan markdown dan GitHub Wiki sebagai penampungnya.
Untuk parser, karena saya menggunakan JavaScript, saya pilih Marked, saya tidak terlalu ingat kenapa saya pilih Marked, kalau tidak salah karena waktu itu proyek saya menggunakan CommonJS sehingga package lain yang menggunakan ES Module tidak bisa saya gunakan karena masalah kompatibilitas.
Templating saya tidak terlalu peduli, jadi saya buat semacam templating saya sendiri
<h1>%%title%%</h1>
<p><span class="dim">//</span> %%date%% %%description%%<p>
...
<div class="content">
%%content%%
</div>
Tinggal mencari token yang dikelilingi "%%" dan menggantinya dengan atribut {data}
const keys = Object.keys(data)
let raw = read(file)
for (let i = 0; i < keys.length; i++)
{
raw = raw.replaceAll(`%%${keys[i]}%%`, data[keys[i]])
}
raw.replace("%%content%%", body)
Dan {data} adalah objek atribut yang ada di frontmatter
---
title: "post4.md"
date: "25/05/2024"
description: "apa yaa"
---
# Halo
const filePath = path.join(DIR, fileName)
const { attributes, body } = matter(read(filePath))
...
/* tulis file ke ~/bin/post/ */
writeFileSync(`${BIN}/post/${fileName.replace(".md", ".html")}`, template("post.html", attributes, marked.parse(body)))
list += `${attributes.date} – ./post/${path}${attributes.title}`
Mungkin belum ideal penggunaanya apabila dibanding dengan framework pada umumnya, tapi hei, biarin saja, kalau rugi juga saya sendiri :3
Pemolesan
Terakhir, direktori public/
dan s/
ingin saya langsung salin ke bin/
tanpa terlalu diapa-apakan, sekadar opimisasi dan minifying bila memungkinkan.
Ada package bernama fs-extra yang memiliki sebuah method untuk menyalin keseluruhan dari sebuah direktori, jadi saya gunakan saja.
copySync("../content/public", "../../bin/public")
copySync("../s/", "../../bin/s")
Saya juga buatkan logger untuk informasi, peringantan, dan kawan-kawannya.
Deploying
Ada beberapa cara untuk mendeploy situsnya, salah satunya dengan integrasi GitHub.
Setiap ada push commit di remote Cloudflare akan memfetch repository tersebut, saya konfigurasikan untuk menggunakan ~/bin/
sebagai direktori akar.
Dan voila! Situs telah diluncurkan. Masih ada banyak hal yang bisa dikonfigurasi, seperti tampilan 404 dan redirects, selengkapnya ada di dokumentasi tentunya.
Okee baii, glhf <3