fullwork
v1.0.7
Published
Mini framework fullstack JavaScript dengan dua mode: Frontend (client-side, routing berbasis JSON) dan Fullstack (client-side + server-side, dengan API & koneksi database generik).
Maintainers
Readme
Fullwork
Mini framework fullstack JavaScript dengan dua mode:
- Frontend — starter kit client-side murni. Routing didefinisikan lewat JSON (
route.json+template.json), navigasi pakai History API (pushState), CSS di-inject ke<style>di<head>, dan JS developer di-import otomatis lewatMutationObserveryang mengawasi atributdata-jspada<main>. - Fullstack — semua fitur mode Frontend, ditambah server (modul bawaan Node.js:
http,fs,path), routing server-side per-route, API endpoint (api.json), dan koneksi database generik (MySQL/PostgreSQL/MongoDB/SQLite) yang diatur lewat.env.
Tanpa dependency eksternal untuk core-nya (kecuali driver database yang kamu pilih sendiri).
Instalasi & Membuat Project Baru
npx fullwork init nama-projectCLI akan bertanya secara interaktif:
- Nama project
- Mode:
FrontendatauFullstack
Setelah selesai:
cd nama-project
npm run devStruktur Folder
project-root/
config/ -> route.json, template.json, (api.json jika mode fullstack)
style/ -> file CSS (di-inject ke <style> di <head>)
page/ -> file HTML untuk slot "main" (konten per route)
layout/ -> file HTML untuk slot header/navbar/sidebar/footer
system/ -> kode internal framework (routing, render, server, dll) - jangan diedit
logic/ -> SEMUA file JS milik kamu (client-side & handler API)
index.html -> shell HTML dasar
.env -> (mode fullstack) konfigurasi environment, termasuk databaseKonsep Routing & Template
config/route.json
{
"/": {
"title": "Beranda",
"template": "default",
"page": "home.html",
"css": "home.css",
"js": "home.js",
"mode": "client"
}
}title— judul halaman (document.title)template— nama template daritemplate.jsonyang dipakaipage— file di folderpage/untuk slotmaincss— file di folderstyle/js— file di folderlogic/, di-import otomatis saatmainuntuk route ini direndermode— khusus mode Fullstack:"client"(default) atau"server". Menentukan apakah route ini dirender di browser (SPA) atau dirender penuh di server (SSR).
config/template.json
{
"default": {
"slots": ["header", "navbar", "footer"],
"header": "header.html",
"navbar": "navbar.html",
"sidebar": "sidebar.html",
"footer": "footer.html"
}
}slots— daftar slot tambahan yang dipakai template ini (pilih 1–4 dari:header,navbar,sidebar,footer). Slot yang tidak disebut di sini tidak dirender sama sekali.header/navbar/sidebar/footer— nama file di folderlayout/untuk masing-masing slot.- Slot
mainwajib selalu ada di semua template, jadi tidak perlu (dan tidak boleh) ditulis dislots. Isinya selalu mengikuti propertipagepadaroute.json, karenamainmemang berbeda-beda per route walau template-nya sama.
Struktur body yang dihasilkan
<body>
<header>
<nav>...</nav> <!-- navbar selalu di dalam header -->
</header>
<main data-js="home.js">...</main>
<aside>...</aside> <!-- sidebar, kalau dipakai -->
<footer>...</footer>
</body>Saat pindah route:
- Slot dengan file yang sama seperti sebelumnya → tidak dirender ulang.
- Slot baru yang sebelumnya tidak dipakai → dirender.
- Slot yang sebelumnya ada tapi sekarang tidak dipakai template baru → dihapus dari body.
- CSS di
<style>hanya diganti kalau nama file CSS-nya berbeda dari yang aktif.
Mekanisme JS (data-js + MutationObserver)
Setiap kali main dirender, system akan mengubah atribut data-js pada elemen <main> sesuai nilai js di route.json. Sebuah MutationObserver mengawasi perubahan atribut ini dan otomatis melakukan import() dinamis terhadap file yang bersangkutan dari folder logic/. Kamu tidak perlu memanggil import secara manual — cukup tulis file JS biasa di logic/.
Mode Fullstack
config/api.json
{
"/api/users": {
"method": "GET",
"route": "/",
"handler": "users-handler.getUsers",
"db": true
}
}- key — path endpoint API
method—GET/POST/PUT/DELETEroute— path diroute.jsonyang menjadi "pemilik" konteks endpoint inihandler— formatnamaFile.namaFungsi, merujuk kelogic/namaFile.jsyang meng-export fungsinamaFungsidb—truekalau handler ini butuh akses database (helper otomatis disiapkan lewatctx.db)
Setiap endpoint di api.json otomatis mendapat header CORS (Access-Control-Allow-Origin: *) dan penanganan preflight OPTIONS bawaan, jadi API bisa dipanggil dari origin lain (misalnya aplikasi mobile hasil bundling Capacitor/Cordova, atau frontend yang di-deploy terpisah dari backend-nya) tanpa perlu konfigurasi tambahan.
Contoh handler di logic/users-handler.js:
module.exports.getUsers = async function (req, res, ctx) {
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify({ users: [] }));
};Database generik (.env)
DB_TYPE=sqlite # mysql | postgres | mongodb | sqlite
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASS=
DB_NAME=fullwork_db
DB_URI=mongodb://localhost:27017/fullwork_db
DB_FILE=./data/database.sqlite
# Khusus koneksi postgres: set "true" kalau provider database mewajibkan SSL
# (contoh: Supabase, dan banyak provider database cloud lainnya).
DB_SSL=falseFramework tidak membundel driver database apa pun. Install sendiri sesuai DB_TYPE yang dipakai:
npm install mysql2 # DB_TYPE=mysql
npm install pg # DB_TYPE=postgres
npm install mongodb # DB_TYPE=mongodb
npm install better-sqlite3 # DB_TYPE=sqliteRoute server-side vs client-side
Set "mode": "server" pada entry di route.json supaya route tersebut dirender penuh di server (SSR) sebelum dikirim ke browser. Kalau tidak diset atau "mode": "client", route akan diserahkan ke sistem client-side (SPA) seperti mode Frontend biasa. Keduanya bisa dicampur dalam satu project yang sama.
Catatan
- Semua kode di folder
system/adalah bagian internal framework — sebaiknya jangan diedit langsung kecuali kamu memang ingin memodifikasi cara kerja framework. - Semua kode yang kamu tulis (baik untuk client maupun handler API) selalu ditaruh di folder
logic/. - Framework ini sengaja dibuat minim dependency supaya mudah dipahami dan dimodifikasi.
Lisensi
MIT
