Belajar Shiki Rehype Pretty Code - Pengelolaan Langs & Themes Custom
Episode 12 of 23

Belajar Shiki Rehype Pretty Code - Pengelolaan Langs & Themes Custom

Kalian akan belajar mengimpor grammar dan theme lokal, mendaftarkan hanya bahasa yang benar-benar dipakai, serta menekan ukuran bundle dengan pemilihan langs dan themes yang selektif dan lazy loading.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Shiki mengemas ratusan bahasa dan puluhan theme. Memuat semuanya akan membebani bundle, padahal kebanyakan proyek hanya memakai segelintir bahasa. Di episode ini kalian belajar mengelola langs dan themes agar bundle tetap ringan tanpa kehilangan kemampuan.

Episode 12 membahas cara mengimpor grammar dan theme lokal, mendaftarkan bahasa secara selektif, memakai alias bahasa, serta strategi lazy loading. Dengan pengelolaan yang tepat, build-time Shiki tetap cepat dan bundle statis kalian tidak membengkak.

Mengapa Membatasi Daftar Bahasa

Biaya Memuat Semua Grammar

Setiap grammar adalah file TextMate yang berisi ratusan aturan regex. Memuat semua grammar sekaligus memperlambat startup dan menambah ukuran bundle. Shiki menyadari hal ini dan menyediakan beberapa titik kontrol: dari bundle penuh, bundle web, hingga impor per-bahasa.

Sejak v4, bahasa dan theme dipisah menjadi package @shikijs/langs dan @shikijs/themes. Ini memungkinkan bundler memecah file per bahasa sehingga hanya yang dibutuhkan yang diunduh.

Memilih Entry Point yang Tepat

  • shiki/bundle/full memuat semua bahasa dan theme, cocok untuk tooling generik.
  • shiki/bundle/web memuat bahasa web populer seperti HTML, CSS, JavaScript, TypeScript, dan JSON.
  • shiki/core tidak memuat apa pun, semua harus diimpor manual.

Untuk blog atau dokumentasi, shiki/bundle/web biasanya sudah cukup. Pilih shiki/core hanya jika ukuran bundle sangat kritis.

Mengimpor Grammar dan Theme Lokal

Grammar Custom dari File

Grammar bukan hanya dari bundle; kalian bisa memuat .tmLanguage.json sendiri. Baca file lalu masukkan objek grammar ke array langs:

JSMuat grammar lokal
import { createHighlighter } from "shiki";
import { readFileSync } from "node:fs";
 
const grammar = JSON.parse(
  readFileSync("./grammars/my-lang.tmLanguage.json", "utf8"),
);
 
const highlighter = await createHighlighter({
  langs: [grammar],
  themes: ["github-dark-default"],
});

Objek grammar boleh membawa name, scopeName, dan embeddedLangs. Setelah terdaftar, kalian bisa memakai nama grammar sebagai bahasa di codeToHtml.

Theme Custom dari Objek

Theme adalah objek TextMate dengan properti name, type, dan settings. Kalian bisa menulisnya langsung atau membaca dari file JSON:

JSTheme custom
const myTheme = {
  name: "my-theme",
  type: "dark",
  settings: [
    {
      scope: ["comment"],
      settings: { foreground: "#8b949e" },
    },
  ],
};
 
const highlighter = await createHighlighter({
  langs: ["typescript"],
  themes: [myTheme],
});

Theme kustom berguna ketika brand kalian punya palet sendiri. Strukturnya standar TextMate, sehingga tool seperti VSCode bisa menghasilkan file ini.

Mendaftarkan Bahasa yang Dibutuhkan

Langs dan Themes Selektif di rehype-pretty-code

Di rehype-pretty-code, kalian mendaftarkan bahasa dan theme lewat opsi langs dan themes:

JSDaftar selektif
const options = {
  theme: "github-dark-default",
  langs: ["ts", "tsx", "js", "css", "json", "bash"],
  themes: ["github-dark-default", "github-light-default"],
};

Opsi langs menerima daftar id bahasa yang akan di-highlight di seluruh konten. Bahasa di luar daftar ini akan dirender tanpa warna, jadi pastikan daftarnya mencakup semua bahasa yang muncul di artikel kalian.

Alias Bahasa dengan langAlias

Beberapa penulis memakai alias singkat seperti js atau py. Shiki sudah mengenal alias umum, tetapi untuk nama kustom kalian bisa mendaftarkan langAlias:

JSDaftarkan alias
const highlighter = await createHighlighter({
  langs: ["javascript", "typescript"],
  langAlias: {
    mylang: "typescript",
  },
  themes: ["github-dark-default"],
});

Dengan langAlias, kalian bisa menulis fenced code block dengan meta bahasa mylang dan Shiki memetakannya ke TypeScript. Fitur ini membuat penulis tetap nyaman dengan istilah internal proyek.

Menekan Ukuran Bundle

Lazy Loading per Bahasa

Gunakan fungsi impor dinamis agar bundler memecah bahasa menjadi chunk terpisah yang hanya dimuat saat dibutuhkan:

JSImpor dinamis
import { createHighlighterCore } from "shiki/core";
import { createOnigurumaEngine } from "shiki/engine/oniguruma";
 
const highlighter = await createHighlighterCore({
  themes: [
    import("@shikijs/themes/github-dark-default"),
  ],
  langs: [
    import("@shikijs/langs/typescript"),
    () => import("@shikijs/langs/javascript"),
  ],
  engine: createOnigurumaEngine(import("shiki/wasm")),
});

Perhatikan shiki/core di sini tidak memuat bahasa atau theme apa pun. Setiap import dinamis menjadi chunk terpisah, sehingga hanya grammar yang benar-benar dipakai yang diunduh.

Mengukur Hasil Optimasi

Bandingkan ukuran bundle sebelum dan sesudah seleksi. Perintah bun run build akan menampilkan laporan size di terminal. Setelah selektif, ukuran chunk grammar biasanya turun drastis dibanding bundle penuh yang bisa mencapai megabyte dalam bentuk tidak terkompresi.

Penutup

Inti yang harus dibawa pulang:

  • Memuat semua grammar membebani bundle dan memperlambat startup.
  • shiki/bundle/full dan shiki/bundle/web menyediakan preset yang siap pakai.
  • Grammar dan theme custom diimpor sebagai objek lewat opsi langs dan themes.
  • langAlias memetakan nama bahasa kustom ke grammar yang sudah terdaftar.
  • shiki/core plus impor dinamis membuat tiap bahasa menjadi chunk terpisah.
  • Ukuran bundle perlu diukur untuk memvalidasi hasil optimasi.

Di episode 13 kalian akan belajar performa dan bundle optimization: mekanisme loading WASM Oniguruma, memilih engine seperti @shikijs/engine-oniguruma, perbedaan highlight di build-time dan client-side, serta caching grammar untuk menghindari render ulang yang mahal.

Belajar Shiki Rehype Pretty Code - Pengelolaan Langs & Themes Custom | Belajar Shiki Rehype Pretty Code