前端前線 2026 年 8 月 20 日

2026-08-20 — MicroLighter 2.1.0:用 CSS Custom Highlight API 打造 2KB 語法高亮器

primary=https://daverupert.com/2026/08/microlighter/ primary=https://github.com/davatron5000/microlighter primary=https://davatron5000.github.io/microlighter/custom-element.html

用 CSS Custom Highlight API 打造 2KB 語法高亮器:MicroLighter 2.1.0 發布

Dave Rupert(daverupert.com)· 2026-08-19

Dave Rupert 於 2026-08-19 釋出 MicroLighter 2.1.0,一款壓縮後僅 2.05KB、零相依的前端語法高亮器。與多數高亮方案在每個 token 外包一層 <span> 不同,MicroLighter 改用 CSS Custom Highlight API 的 ::highlight() 偽元素直接在繪製階段套色,不修改 DOM 結構。此版本同時把支援語言數擴充到 32 種,新增 Elixir 與 HEEx 文法。

背景

這個專案起因是 Rupert 自己的 Jekyll 部落格語法高亮壞掉。他沒有直接換用既有套件,而是採用 Bramus 在 2024 年提出的 CSS Custom Highlight API 技巧:用 JS 建立 Highlight 物件、以 Range 標出 token 範圍,再交給 CSS.highlights 註冊,最後靠 ::highlight(name) 選擇器上色。這個做法的代價::highlight() 偽元素只能改文字相關的視覺屬性,無法設定斜體、粗體或換字型,因為它不參與 box 排版。

核心改動

安裝與使用維持一般高亮套件的慣例,語言仍以 class="language-*" 標記:

npm install microlighter

import { highlightAll } from "microlighter";
import "microlighter/themes/github.css";
await highlightAll();
<pre><code class="language-javascript">const answer = 42;</code></pre>

詞法辨識沿用 TextMate 文法格式(VS Code 也採用此格式),每個語言的文法各自獨立成模組,依需求延遲載入以壓低初始體積。版本演進可從 commit 紀錄看出節奏:

版本日期變更
2.0.208-17既有維護性修正
2.0.308-18修正測試中的 polling 問題
2.1.008-19新增 Elixir、HEEx 文法,語言數達 32

目前涵蓋的語言依用途分類:

  • Web:HTML、CSS、SCSS、JavaScript、TypeScript、TSX、Svelte、Vue、HEEx
  • Systems:C、C++、Rust、Go、組合語言
  • Application:Java、C#、Kotlin、Swift、Objective-C、Dart、PHP、Elixir
  • Scripting:Python、Ruby、Bash、Perl、PowerShell、Lua、R
  • Data/Config:JSON、YAML、TOML、SQL、Markdown、GraphQL、Dockerfile、Git diff

影響範圍

套件核心只負責 tokenize 與上色,行號與複製按鈕被拆到獨立的 Web Component <micro-lighter>,額外約 1KB:

<micro-lighter language="javascript" controls="copy" line-numbers>
  <pre><code>customElements.define("spicy-iframe", class extends HTMLElement {});</code></pre>
</micro-lighter>

此元件以 Shadow DOM 封裝,但透過 ::part(copy-button)::part(line-numbers) 開放外部樣式覆寫。套件以 MIT 授權釋出,package.json 標示 engines.node >= 18,主入口為 dist/index.js

原始來源:Dave Rupert 部落格公告GitHub 原始碼Custom Element 文件


End of article
0
Would love your thoughts, please comment.x
()
x