31 KiB
架构设计:Gitea GitHub Theme
项目概述
Gitea GitHub Theme 是一个构建时 CSS 生成框架,为 Gitea 自托管代码平台产出静态
.css
主题文件。项目以设计令牌和颜色定义为输入,通过分层管道转换,最终输出 30+ 个压缩后的 CSS 文件,覆盖 7 个主题系列(default、colorblind、tritanopia、pink、gitea、catppuccin、high-contrast)。
核心原则: 开发时享受完整的类型安全和 CSS-in-JS 开发体验,浏览器端交付纯静态 CSS,零运行时开销。
架构分层
┌──────────────────────────────────────────────────────────────┐
│ 主题配置层 │
│ theme.config.ts: 声明主题系列、颜色类型、显示名称、无障碍元信息 │
└──────────────────────────┬───────────────────────────────────┘
│
┌──────────────────────────▼───────────────────────────────────┐
│ 颜色定义层 │
│ ┌──────────┐ ┌──────────────┐ ┌───────────────────┐ │
│ │ primer/ │ │ themes/ │ │ themes/catppuccin │ │
│ │ (自动生成│ │ github.ts │ │ .ts │ │
│ │ 的 Primer│ │ gitea*.ts │ │ │ │
│ │ 设计令牌)│ │ │ │ │ │
│ └────┬─────┘ └──────┬───────┘ └─────────┬─────────┘ │
│ │ │ │ │
│ primer2GitHubColor defineTheme catppuccin2ThemeColor │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ GitHubColor Theme ThemeColor │
│ (colorType: │
│ "github") │
└──────────────────────────┬───────────────────────────────────┘
│
┌──────────────────────────▼───────────────────────────────────┐
│ 颜色转换层 │
│ src/palette/ │
│ ┌────────────┐ ┌────────────┐ ┌──────────────────┐ │
│ │ github.ts │ │ theme.ts │ │ gitea.ts │ │
│ │ GitHubColor│ │ ThemeColor │ │ GiteaColor │ │
│ │ → │ │ → │ │ → │ │
│ │ ThemeColor │ │ ThemeVars │ │ ThemeVars │ │
│ └────────────┘ └────────────┘ └──────────────────┘ │
│ │
│ 统一输出: ThemeVars (CSS 变量的扁平键值映射) │
└──────────────────────────┬───────────────────────────────────┘
│
┌──────────────────────────▼───────────────────────────────────┐
│ 核心框架层 │
│ src/core/ │
│ ┌──────────────┐ ┌──────────┐ ┌───────────────────┐ │
│ │ theme.ts │ │ css.ts │ │ chroma.ts │ │
│ │ createTheme()│ │ css() │ │ codemirror.ts │ │
│ │ defineTheme()│ │cssCombine│ │ meta.ts │ │
│ └──────┬───────┘ │cssStyle()│ └───────────────────┘ │
│ │ └────┬─────┘ │
│ │ │ │
│ vanilla-extract 适配器 (src/vanilla-extract.ts) │
│ ┌──────────────────────────────────────────────────┐ │
│ │ setAdapter() → 拦截 appendCss, │ │
│ │ registerClassName, registerComposition │ │
│ │ → 在构建时将全部 CSS 序列化为字符串 │ │
│ └──────────────────────────────────────────────────┘ │
└──────────────────────────┬───────────────────────────────────┘
│
┌──────────────────────────▼───────────────────────────────────┐
│ 样式覆写层 │
│ styles/ │
│ ┌──────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ public/ │ │ components/ │ │ templates/ │ │
│ │ (基础 │ │ (页面级别 │ │ (模板专属样式) │ │
│ │ 元素) │ │ 样式) │ │ │ │
│ └──────────┘ └──────────────┘ └──────────────────┘ │
│ common/ (可复用 CSS 片段: 按钮、标签、动画等) │
│ │
│ 每个文件使用 css`...` 模板字面量 │
│ → 在导出边界用 cssCombine() 拼接 → 单个 CSS 字符串 │
└──────────────────────────┬───────────────────────────────────┘
│
┌──────────────────────────▼───────────────────────────────────┐
│ 构建管道 │
│ src/vite-plugin/index.ts (Vite 插件) │
│ │
│ config() 钩子: │
│ 1. 动态导入 theme.config.ts │
│ 2. 解析所有主题条目 + 生成 auto 自动主题 │
│ │
│ generateBundle() 钩子: │
│ 1. 导入 styles/ → CSS 字符串 (public + components) │
│ 2. 对每个主题条目: │
│ a. compileCSS(createThemeMetaInfo + createTheme) │
│ b. lightningcss.transform() → 压缩 │
│ c. 追加样式覆写 (仅非 auto 主题) │
│ d. emitFile 输出 .css 资源 │
│ 3. 对 auto 主题: 生成 @import 声明 │
└──────────────────────────┬───────────────────────────────────┘
│
▼
dist/theme-github-*.css
核心设计模式
1. Vanilla-Extract 适配器劫持
解决的问题: Vanilla-extract 是一个零运行时 CSS-in-JS 库,在构建时通过其 Vite/esbuild 插件生成静态 CSS 文件。但 Gitea 主题需要单文件 CSS 输出,并且需要对主题生成过程进行编程控制(每个主题一个输出文件、自动生成 auto 主题等)。
方案: 绕过 vanilla-extract 的默认插件,直接使用其底层适配器 API。
export function compileCSS(compileFn: () => void): string {
// 1. 安装自定义适配器,将 CSS 对象捕获到数组
setAdapter({
appendCss: css => capturedCssObjs.push(css),
registerClassName: className => localClassNames.add(className),
registerComposition: composition => composedClassLists.push(composition),
// ... 其他回调实现为空操作
});
// 2. 设置文件作用域用于调试
setFileScope(getCallerInfo(1));
// 3. 执行调用方的 vanilla-extract API 调用
compileFn();
// 4. 拆除适配器
endFileScope();
removeAdapter();
// 5. 将捕获的 CSS 对象序列化为字符串
return transformCss({
localClassNames: Array.from(localClassNames),
composedClassLists,
cssObjs: capturedCssObjs,
}).join("\n");
}
工作原理:
compileCSS包装一个同步函数,该函数内部调用 vanilla-extract API(createGlobalTheme、globalStyle、globalKeyframes等)- 自定义适配器拦截所有 CSS 生成调用,将它们捕获到内存数组
- 函数执行完毕后,
transformCss()将捕获的对象序列化为 CSS 字符串 - 适配器被拆除,不留下任何全局副作用
安全性保证: 每次 compileCSS 调用完全自包含:安装 → 捕获 → 序列化 → 拆除。调用之间无状态泄漏。
关键洞察: Vanilla-extract 的 createGlobalThemeContract + createGlobalTheme 完全适配此模式——它们仅在
createGlobalTheme 调用期间产生 CSS,而该调用恰好发生在我们的捕获范围内。
2. 三条颜色输入管道
解决的问题: 不同的颜色主题来源有不同的数据结构。Primer 设计令牌(来自 GitHub)有数百个嵌套键。Catppuccin 有自己的调色板结构。Gitea 的原生格式使用扁平结构。需要同时支持这三种。
方案: 三条转换路径,全部汇聚到 ThemeVars:
Primer 令牌 ──→ GitHubColor ──→ ThemeColor ──→ ThemeVars
Catppuccin flavor ────────────→ ThemeColor ──→ ThemeVars
GiteaColor ──────────────────────────────────→ ThemeVars
每条路径有不同的复杂度要求:
| 路径 | 适用场景 | 复杂度 | 示例 |
|---|---|---|---|
github |
完整 Primer 令牌合规 | 高(数百个映射键) | Default、色盲、高对比度主题 |
theme |
15 个基础色定义自定义主题 | 低(自动派生 200+ CSS 变量) | Catppuccin、社区主题 |
gitea |
Gitea 原生颜色格式 | 中(直接映射) | Gitea 兼容主题 |
设计理由: theme
路径是"入门路径"——贡献者只需定义 15 个语义色(red、orange、yellow、……、white)加上 primary 和 secondary。框架自动计算:
- 7 级亮度变体(dark-1 到 dark-7、light-1 到 light-7)
- 9 级透明度变体(alpha-10 到 alpha-90)
- Badge 颜色及其 hover 状态
- 消息颜色(error/success/warning/info)
- ANSI 控制台颜色
- 方向感知(暗/亮主题下的缩放方向反转)
实现在 src/palette/theme.ts 的 theme2ThemeVars() 函数中。
3. CSS 变量命名约定
解决的问题: Gitea 期望特定命名模式的 CSS 变量(--color-primary-dark-1、--color-red-badge-bg
等)。我们在 TypeScript 中需要类型安全的访问方式(themeVars.color.primary.dark.num1)。
方案: 使用 vanilla-extract 的 createGlobalThemeContract 配合自定义 varMapper。
在 src/types/vars.ts 中:
function varMapper(prefix: string | null = null) {
return (value: string | null, path: string[]) => {
if (value === null) {
// 从路径自动生成名称: ["color","primary","dark","num1"] → "color-primary-dark-1"
path = path.filter(item => item !== "self"); // 移除 "self" 键
path = path.map(item => item.replace(/^num/, "")); // 去掉 "num" 前缀
value = path.join("-");
}
if (prefix) value = `${prefix}-${value}`;
return value;
};
}
由此创建了双向映射:
| TypeScript 访问 | CSS 变量 |
|---|---|
themeVars.color.primary.self |
--color-primary |
themeVars.color.primary.dark.num1 |
--color-primary-dark-1 |
themeVars.github.button.primary.bgColor.rest |
--github-button-primary-bgColor-rest |
syntaxVars.keyword |
--color-syntax-keyword |
customThemeVars.cloneMenuWidth |
--custom-clone-menu-width |
4. 构建时 CSS 语法校验
解决的问题: 模板字面量中的 CSS 可能包含语法错误,这些错误只有到浏览器运行时才会显现。
方案: css() 模板标签在构建时使用 lightningcss 校验 CSS 语法。
在 src/core/css.ts 中:
export function css(strings: TemplateStringsArray, ...values: CSSInterpolation[]): CSSString {
const result = strings.reduce((acc, s, i) => acc + s + String(values[i] ?? ""), "");
// 构建时校验: lightningcss 解析并报告语法错误
transform({ filename: getCallerInfo(1), code: Buffer.from(result) });
return result as CSSString;
}
如果开发者编写了无效 CSS,构建会立即失败,并附带指向问题模板字面量的 文件:行号
信息。这能捕捉到原本只能通过浏览器 DevTools 才能发现的错误。
权衡: 每次 css 模板调用都会执行一次
transform()。对于约 60 个样式文件,这会为初始构建增加约 200ms(一次性开销,后续由 Bun 的模块缓存加速)。
Vite 构建管道
构建由自定义 Vite 插件在 src/vite-plugin/index.ts 中编排:
阶段一:配置解析(config 钩子)
- 通过 Bun 原生 TypeScript + package exports 自引用(
@lutinglt/gitea-github-theme/theme.config.ts)动态导入theme.config.ts - 遍历每个主题系列,为每个主题变体生成条目(dark、light、soft-dark、frappe、macchiato 等)
- 当系列同时具有 dark 和 light 变体时,自动生成
auto主题条目 - 创建占位入口文件(Vite 需要至少一个输入)
阶段二:CSS 生成(generateBundle 钩子)
对每个 非 auto 主题:
- 调用
compileCSS(),传入一个函数,该函数内部:- 创建 Gitea 主题元信息(
createThemeMetaInfo)——设置--theme-color-scheme、--theme-display-name、--theme-colorblind-type - 创建主题 CSS 变量(
createTheme)——生成所有--color-*和--github-*变量、全局样式、关键帧动画、代码高亮
- 创建 Gitea 主题元信息(
- 捕获的 CSS 字符串通过
lightningcss.transform()进行压缩 - 追加公共样式覆写(
styles/)
对每个 auto 主题:
- 生成
@import声明,配合prefers-color-scheme媒体查询,引用对应的暗/亮主题文件 - 包含主题元信息,供 Gitea 识别为自动颜色主题
CSS 输出结构
theme-github-dark.css:
├── @keyframes (overlayAppear, overlayAppearDown, overlayAppearUp)
├── gitea-theme-meta-info { --theme-color-scheme: dark; ... }
├── :root { --theme-version: "1.26.2.260605"; --is-dark-theme: true; ... }
├── :root { --color-primary: #4493f8; --color-primary-contrast: ... }
├── ... (200+ 个 CSS 变量声明)
├── .chroma { ... } (代码语法高亮)
├── .code-editor-container { ... } (CodeMirror 高亮)
└── <公共样式覆写> (~60KB 单行压缩)
theme-github-auto.css:
├── @import "./theme-github-dark.css" (prefers-color-scheme: dark);
├── @import "./theme-github-light.css" (prefers-color-scheme: light);
└── gitea-theme-meta-info { --theme-color-scheme: auto; ... }
颜色系统深入
颜色缩放计算
src/functions/color.ts 中的 scaleColorLight() 实现了 Sass color.scale() 算法:
变暗: newL = currentL × (1 + scale/100) [scale < 0]
变亮: newL = currentL + (1 - currentL) × (scale/100) [scale > 0]
这是比例缩放,并非线性偏移。其意义在于:
color.scale(#000000, $lightness: 50%)→ 50% 灰色(而非"比黑色暗 50%",那仍然是黑色)color.scale(#ffffff, $lightness: -50%)→ 50% 灰色(而非"比白色亮 50%",那仍然是白色)- 比例方法确保在亮度两端都能产生视觉上有意义的变化
ThemeColor → ThemeVars 派生
src/palette/theme.ts 中的 theme2ThemeVars() 接收
ThemeColor(15 个基础色 + 元数据),派生完整的 ThemeVars(200+ 个 CSS 变量值):
- 主色阶(Primary scale):7 个暗色变体、7 个亮色变体、9 个透明度变体、hover/active 状态——全部从一个 hex 颜色生成
- 副色阶(Secondary scale):13 个暗色变体、4 个亮色变体、9 个透明度变体、按钮 hover/active 状态
- 命名颜色(15 个基础色中的 13 个):每个生成 self/light/dark-1/dark-2/badge-self/badge-bg/badge-hover-bg
- 语义消息色:bg/border/text,配合 rgba 透明度和饱和度调整
- ANSI 颜色:从命名色映射的 16 色调色板
- 方向感知:
isDarkTheme标志反转缩放方向——暗色主题中"dark"变体走向更亮的方向(为保持对比度)
样式覆写策略
选择器优先级层级
样式覆写使用 Gitea 现有的 DOM 选择器。覆写策略遵循优先级阶梯:
- 颜色变量——所有颜色引用主题中的 CSS 变量(绝不硬编码 hex 值)
- 元素级覆写——基础元素如
.ui.button、#navbar、input - 组件级覆写——页面特定区域:heatmap、issues、actions、仓库页面
!important逃离——仅在 Gitea 通过内联style属性设置颜色时使用(如热力图贡献方块)
cssCombine() 显式组合
样式通过 cssCombine() 调用树组合在一起:
styles/index.ts
├── public/index.ts (基础元素、按钮、输入框、下拉菜单、菜单、表格)
├── components/index.ts (导航栏、热力图、议题、仓库文件、Actions 等)
└── templates/index.ts (模板特定样式)
每个叶子模块导出 default cssCombine(...),将 CSS 片段串联在一起。这种显式组合使依赖关系图可见,避免了 CSS @import 或
@use 的隐式排序问题。
cssStyle() 可复用片段
src/core/css.ts 中的 cssStyle() 允许提取可复用的 CSS 属性集,同时保留 vanilla-extract 的类型检查:
// 在 styles/common/button.ts 中:
export const primaryButtonStyle = cssStyle({
color: themeVars.github.button.primary.fgColor.rest,
backgroundColor: themeVars.github.button.primary.bgColor.rest,
borderColor: themeVars.github.button.primary.borderColor.rest,
boxShadow: themeVars.github.shadow.resting.small,
});
// 在 styles/public/button.ts 中:
const baseButton = css`
.ui.primary.button {
${primaryButtonStyle}
}
`;
这在最终输出静态 CSS 字符串的系统中保留了类型安全(vanilla-extract 校验属性名和值类型)。
目录结构
├── theme.config.ts # 主题系列声明(框架入口点)
├── src/
│ ├── index.ts # 公共 API 导出
│ ├── core/ # 核心框架
│ │ ├── theme.ts # createTheme、defineTheme(颜色 → CSS 变量)
│ │ ├── css.ts # css()、cssCombine()、cssStyle()
│ │ ├── chroma.ts # Chroma(服务端)语法高亮
│ │ ├── codemirror.ts # CodeMirror(客户端)语法高亮
│ │ ├── meta.ts # Gitea 主题元信息(color scheme, display name)
│ │ └── types.d.ts # MapLeafNodes、CSSVarFunction、Tokens
│ ├── palette/ # 颜色转换与变换
│ │ ├── theme.ts # ThemeColor → ThemeVars(简化 API)
│ │ ├── github.ts # GitHubColor → ThemeColor(Primer 路径)
│ │ ├── gitea.ts # GiteaColor → ThemeVars(原生路径)
│ │ ├── catppuccin.ts # CatppuccinFlavor → ThemeColor
│ │ ├── primer.ts # Primer 令牌 → GitHubColor / Chroma / CodeMirror
│ │ ├── display.ts # Display color scale → GitHubColor 覆写
│ │ └── catppuccinSyntax.ts # Catppuccin 语法高亮
│ ├── functions/ # 工具函数
│ │ ├── color.ts # scaleColorLight(Sass color.scale)+ rgba 转换
│ │ └── var.ts # extractVarName(CSS 变量名提取)
│ ├── types/ # 类型定义与 CSS 变量契约
│ │ ├── color/ # 颜色结构定义(primary, secondary, named, 等)
│ │ └── vars.ts # createGlobalThemeContract + varMapper
│ ├── vite-plugin/ # 构建工具
│ │ ├── index.ts # 主 Vite 插件
│ │ ├── themeConfig.ts # defineThemeConfig、TypeScript 类型
│ │ └── utils.ts # buildFullThemeName、buildFullDisplayName
│ ├── vanilla-extract.ts # 适配器劫持(compileCSS、captureStyle)
│ ├── selectors.ts # 共享 CSS 选择器(root、chroma、codeMirror、emoji)
│ └── utils.ts # deepOverride、getCallerInfo
├── styles/ # CSS 样式覆写
│ ├── common/ # 可复用 CSS 片段(按钮、标签、动画)
│ ├── public/ # 基础元素(按钮、输入框、下拉菜单、菜单、表格)
│ ├── components/ # 页面特定样式(导航栏、热力图、仓库、议题、Actions)
│ └── templates/ # 模板特定样式
├── themes/ # 颜色主题定义
│ ├── github.ts # GitHub 主题颜色(来自 Primer 令牌)
│ ├── giteaDark.ts # Gitea 暗色主题颜色(原生格式)
│ ├── giteaLight.ts # Gitea 亮色主题颜色(原生格式)
│ └── catppuccin.ts # Catppuccin 主题颜色
├── primer/ # 自动生成的 Primer 设计令牌(来自 @primer/primitives)
├── scripts/ # 构建与工具脚本
│ ├── buildPrimerTSToken.ts # 从 @primer/primitives 生成 primer/ TypeScript 令牌
│ ├── syncTheme.ts # 同步构建产物到远程 Gitea 实例
│ ├── updateGitea.ts # 更新 Gitea 参考文件
│ ├── translate.ts # 生成本地化/翻译文件
│ └── version.ts # 版本管理
├── dist/ # 构建产物(30+ CSS 文件)
└── templates/ # 可选的 Gitea Go 模板覆写
关键设计决策与权衡
决策一:Vanilla-Extract 仅用于 CSS 编写,不用于运行时
选择: 使用 vanilla-extract 的 createGlobalTheme/createGlobalThemeContract
进行类型安全的 CSS 变量生成,但通过适配器劫持在构建时序列化为静态 CSS 字符串。
放弃: 使用 vanilla-extract 内置 Vite 插件(生成按模块拆分的 CSS 文件,不适合单文件主题输出)。
权衡: 适配器 API 无官方文档,可能在 vanilla-extract 版本间变化。通过锁定 @vanilla-extract/css
版本并使用快照测试检测 CSS 输出变化来缓解风险。
决策二:单文件 CSS 输出
选择: 每个主题是包含所有变量和所有样式覆写的单个 CSS 文件。
放弃: 通过 @import 链拆分为多个 CSS 文件(Gitea 主题系统每个主题只加载一个 CSS 文件)。
权衡: 样式覆写在所有主题文件中重复嵌入(约 60KB × 30 个主题 ≈ 1.8MB 冗余)。这是 Gitea 的约束而非设计选择。替代方案(独立 common.css)需要 Gitea 支持多文件主题加载。
决策三:LightningCSS 同时用于语法校验和输出压缩
选择: 使用 LightningCSS 进行构建时 CSS 语法校验(在 css() 模板标签中)和输出压缩(在 Vite 插件中)。
放弃: PostCSS(更慢)、esbuild CSS(功能不够完整)、完全不校验。
权衡: LightningCSS 较宽容——它会从许多语法错误中恢复而非抛出异常。这意味着 css()
中的"校验"能捕获严重错误,但可能静默接受某些边缘情况。构建产物快照测试部分补偿了这个不足。
决策四:仅支持 Bun 运行时
选择: 要求 Bun ≥ 1.3.14 用于开发和构建。
放弃: 跨运行时支持(Node + Bun)。
权衡: 限制了贡献者环境。收益:原生 TypeScript 执行(无 ts-node/esbuild 开销)、一致的堆栈追踪格式(用于调试工具)、更快的构建速度(Bun 原生打包器)。
决策五:包自引用用于内部导入
选择: 即使在同一个包内也使用 @lutinglt/gitea-github-theme/core 风格的导入,通过 package.json 中的 exports
映射实现。
放弃: 全程使用相对路径导入。
权衡: 需要 tsconfig.json 中的 paths
映射支持 IDE。收益:无论作为依赖使用还是本地开发,导入路径完全一致;src/、styles/、themes/
三个目录之间没有路径混淆。
添加新主题
快速路径(15 个颜色定义)
- 创建
themes/my-theme.ts:
import { defineTheme } from "@lutinglt/gitea-github-theme/core";
import type { ThemeColor, Syntax } from "@lutinglt/gitea-github-theme/core";
const themeColor: ThemeColor = {
isDarkTheme: true,
primary: "#8b5cf6", // 强调色(紫色)
primaryContrast: "#ffffff",
secondary: "#27272a", // 边框色
base: {
red: "#ef4444",
orange: "#f97316",
yellow: "#eab308",
olive: "#84cc16",
green: "#22c55e",
teal: "#14b8a6",
cyan: "#06b6d4",
blue: "#3b82f6",
violet: "#8b5cf6",
purple: "#a855f7",
pink: "#ec4899",
brown: "#a16207",
black: "#18181b",
grey: "#71717a",
gold: "#eab308",
white: "#fafafa",
},
console: {
/* Actions 日志颜色 */
},
diff: {
/* 代码差异颜色 */
},
other: {
/* body、text、input、shadow 等 */
},
github: {
/* GitHub 专有变量 */
},
};
const syntaxColor: Syntax = {
/* 代码高亮色 */
};
export default defineTheme({ colorType: "theme", themeColor, syntaxColor });
- 在
theme.config.ts中注册:
{
themeSeriesName: "my-theme",
themes: {
dark: { theme: myDarkTheme },
// 可选: 添加 light 变体后自动生成 auto 主题
light: { theme: myLightTheme },
},
}
- 运行
bun bundle——主题 CSS 将出现在dist/目录中。
完整路径(Primer 令牌)
如需像素级精准的 GitHub 颜色匹配,使用 github 路径直接映射 Primer 设计令牌。完整映射参考见 themes/github.ts 和
src/palette/github.ts。
测试策略
| 层级 | 测试类型 | 位置 | 验证内容 |
|---|---|---|---|
| 工具函数 | 单元测试 | src/utils.test.ts |
deepOverride 行为、getCallerInfo 堆栈解析 |
| 计算函数 | 单元测试 | src/functions/*.test.ts |
scaleColorLight 数值计算、extractVarName 解析 |
| 核心框架 | 单元测试 | src/core/css.test.ts |
css() 校验、cssCombine() 组合、cssStyle() 序列化 |
| 调色板 | 快照测试 | src/palette/*.test.ts |
完整颜色转换链路(Primer → ThemeColor → ThemeVars、Catppuccin → ThemeColor → ThemeVars 等) |
| 调色板 | 结构测试 | src/palette/github.test.ts |
颜色值合法性(所有叶子节点都是有效 CSS 颜色字符串)、必需键存在 |
| 构建产物 | 集成测试 | src/build-output.test.ts |
预期文件存在、CSS 内容有效性(变量存在、无调试残留、hex 小写、color-scheme 匹配)、文件体积上限 |
相关文档
- CONTRIBUTING_CN.md — 开发环境配置与贡献指南
- README.md — 用户面安装与使用
- README_CN.md — 中文用户安装与使用
- primer/README.md — 自动生成的 Primer 令牌说明
- CHANGELOG.md — 发布历史