在技术博客中,代码块是展示核心内容的灵魂。如果代码没有颜色区分,阅读起来就像在看一堆枯燥的字符堆砌。Hexo 内置了对两大主流语法高亮库——Highlight.js 和 PrismJS 的支持。
你可以把语法高亮想象成给代码穿上“制服”。Highlight.js 和 PrismJS 就是两家不同的制服制造商,一家擅长在服务器端就把衣服做好(服务端高亮),另一家则提供了丰富的配件让浏览器自己去搭配(浏览器端高亮)。Hexo 允许你自由选择其中一家,甚至决定是在生成网站时穿好衣服,还是让读者打开网页时再穿。
本篇教程将详细讲解如何在 Hexo 中配置和使用这两套系统。
一、如何在文章中插入代码块
在开始配置之前,你需要知道如何在文章中写出代码块。Hexo 兼容三种写法,无论你的文章是用 Markdown、EJS 还是其他格式编写,这三种方式都通用。
1. 标签插件写法 (Tag Plugins)
这是 Hexo 原生的标签语法,功能最强大,支持标题、链接等额外选项。
完整语法:
1 | {% codeblock [title] [lang:language] [url] [link text] [additional options] %} |
或者使用简写 code:
1 | {% code [title] [lang:language] [url] [link text] [additional options] %} |
参数说明:
title:代码块上方的标题。lang:language:指定编程语言(如js,python,yaml),用于高亮。url:代码来源的链接。link text:链接显示的文字。additional options:其他选项,如mark(高亮特定行)、first_line(起始行号)等。
示例:
1 | {% codeblock Hello World lang:js https://example.com 'View Source' %} |
2. 反引号代码块 (Fenced Code Block)
这是标准的 Markdown 语法,Hexo 对其进行了扩展,使其支持上述标签插件的大部分功能。
语法:
1 | ```[language] [title] [url] [link text] [additional options] |
示例:
1 | ```python 计算斐波那契数列 |
1 | def fib(n): |
概念辨析:三种写法的区别
- 标签插件 (
{% codeblock %}):功能最全,兼容性最好,但语法稍显繁琐,容易在 Markdown 编辑器中破坏预览。 - 反引号扩展 (
```):书写最自然,符合 Markdown 习惯,推荐使用。Hexo 会自动识别其中的扩展参数。 - 标准 Markdown:如果你只写 ```` ```js ` 而不加其他参数,它就是标准的 Markdown 代码块,Hexo 也会正常处理高亮。
二、核心配置:选择高亮引擎
Hexo 的高亮配置位于站点根目录的 _config.yml 文件中。根据 Hexo 版本的不同(以 v7.0.0 为界),配置方式略有差异。
1. Hexo v7.0.0 及以上版本
新版本引入了 syntax_highlighter 字段来统一切换引擎。
启用 Highlight.js (默认):
1 | # _config.yml |
启用 PrismJS:
你需要将主开关设为 prismjs,并确保护 highlight 下的配置不冲突(通常只需改主开关即可,Hexo 会自动忽略未选中的引擎配置)。
1 | # _config.yml |
禁用所有内置高亮:
如果你想完全自己控制(例如使用浏览器端的第三方库),可以将开关留空。
1 | # _config.yml |
此时,代码块将输出最原始的 HTML 结构(<pre><code class="language">),由渲染器(如 marked.js)控制基础结构。
2. Hexo v7.0.0 以下版本
旧版本通过 enable 布尔值来独立控制两个引擎。注意:两者不能同时开启。
启用 Highlight.js:
1 | # _config.yml |
启用 PrismJS:
1 | # _config.yml |
禁用所有:
1 | # _config.yml |
三、深度解析 Highlight.js 配置
Highlight.js 是 Hexo 的默认高亮引擎,它在服务器端(生成静态文件时)完成高亮处理。这意味着用户看到的 HTML 已经带有颜色样式,加载速度快,且无需浏览器执行额外 JS。
1. auto_detect (自动检测语言)
- 功能:让 Highlight.js 自动猜测代码块的语言,即使你在文章中没有标注
lang:js。 - 适用场景:当你需要“子语言高亮”时(例如在 HTML 代码块中高亮内部的 JS 脚本),或者你懒得每次都给代码块标语言。
- 警告:此功能非常消耗 CPU 资源,会显著增加生成网站的时间。除非必要,否则不建议开启。
- 配置示例:
1
2highlight:
auto_detect: false # 推荐保持关闭
2. line_number (显示行号)
- 功能:在代码块左侧显示行号。
- 原理:Highlight.js 本身不支持行号。Hexo 通过包裹一层
<figure>和<table>标签来模拟行号效果。 - 生成的 HTML 结构:
1
2
3
4
5
6
7
8
9
10<figure class="highlight yaml">
<table>
<tbody>
<tr>
<td class="gutter"><pre><span class="line">1</span><br></pre></td>
<td class="code"><pre><span class="line">...</span></pre></td>
</tr>
</tbody>
</table>
</figure> - 注意事项:由于引入了表格布局,你可能需要在主题 CSS 中针对
figure.highlight table编写样式,以确保行号和代码对齐美观。
3. line_threshold (行号阈值)
- 功能:只有当代码行数超过设定值时,才显示行号。
- 用途:避免只有一两行代码时也显示行号,造成视觉浪费。
- 配置示例:
1
2
3highlight:
line_number: true
line_threshold: 5 # 只有超过 5 行的代码块才显示行号
4. tab_replace (制表符替换)
- 功能:将代码中的 Tab 字符 (
\t) 替换为指定数量的空格。 - 默认值:2 个空格。
- 配置示例:
1
2highlight:
tab_replace: " " # 替换为 4 个空格
5. exclude_languages (排除语言)
- 功能:指定某些语言不进行高亮处理,仅输出纯文本代码块。
- 用途:某些语言的高亮效果不好,或者你希望某些特定格式(如日志文件)保持原样。
- 配置示例:此时,这些语言的代码块只会生成
1
2
3
4highlight:
exclude_languages:
- example
- log<pre><code class="example">...</code></pre>,内部不会有复杂的<span>标签。
6. wrap (包裹模式)
- 功能:是否使用
<figure>和<table>包裹代码。 - 依赖关系:
line_number功能强依赖于wrap。如果你开启line_number: true,Hexo 会强制开启wrap,即使你设置wrap: false也会失效。 - 如何获得原生 Highlight.js 行为:
如果你不需要行号,只想得到最纯净的<pre><code>结构(方便直接应用 highlight.js 的官方 CSS 主题),必须同时关闭这两个选项:1
2
3
4highlight:
line_number: false
wrap: false
hljs: true # 建议开启,见下文
7. hljs (类名前缀)
- 功能:是否在生成的 HTML class 中添加
hljs-前缀。 - 背景:Highlight.js 的官方 CSS 主题通常要求 class 带有
hljs-前缀(如hljs-comment),而 Hexo 默认为了兼容性去掉了这个前缀。 - 配置示例:效果对比:
1
2highlight:
hljs: truehljs: false(默认):<span class="comment">hljs: true:<span class="hljs-comment">
- 最佳实践:如果你打算直接使用 Highlight.js 官网下载的 CSS 主题文件,请务必设置
line_number: false,wrap: false, 以及hljs: true。
四、深度解析 PrismJS 配置
PrismJS 是另一个流行的高亮库,它以轻量级和丰富的插件生态著称。Hexo 支持将其运行在服务端(Preprocess)或浏览器端。
1. preprocess (预处理模式)
这是 PrismJS 配置中最核心的选项,决定了高亮发生的时机。
preprocess: true(服务端高亮 - 推荐)- 行为:在
hexo generate时,Hexo 直接计算出带颜色的 HTML。 - 优点:页面加载极快,SEO 友好,无闪烁。
- 行号支持:当
line_number: true时,Hexo 会自动生成所需的 HTML 结构。你只需要在主题中引入prism-line-numbers.css即可,不需要引入 JS 文件。 - 限制:无法使用那些依赖浏览器端动态分析的 Prism 插件。
- 行为:在
preprocess: false(浏览器端高亮)- 行为:Hexo 只输出带有语言标记的原始代码块,高亮由浏览器加载 PrismJS 的 JS 库后动态执行。
- 优点:可以使用 PrismJS 的所有插件(如实时高亮特定行、工具提示等)。
- 代价:增加了浏览器的 JS 执行负担,页面加载初期可能看到无色代码(闪烁)。
- 行号支持:Hexo 不会生成行号所需的 HTML 结构。你必须手动在主题中同时引入
prism-line-numbers.css和prism-line-numbers.js。 - 特定行高亮:如果你在代码块中使用了
mark选项(高亮特定行),Hexo 依然会生成相应的 HTML 结构,即使在此模式下。
配置示例 (服务端模式):
1 | # _config.yml |
此时只需在模板引入 CSS:
1 | <link rel="stylesheet" href="/css/prism-line-numbers.css"> |
配置示例 (浏览器端模式):
1 | # _config.yml |
此时需在模板引入 CSS 和 JS:
1 | <link rel="stylesheet" href="/css/prism-line-numbers.css"> |
2. line_number & line_threshold & tab_replace
这三个参数的功能与 Highlight.js 中的完全一致:
line_number: 开启行号。注意:PrismJS 的行号同样依赖内部包裹结构,无法在关闭wrap(隐式) 的情况下单独开启行号。line_threshold: 行号显示的行数阈值。tab_replace: Tab 转空格策略。
3. 插件兼容性特别说明
当使用 preprocess: false 时,PrismJS 的插件支持情况如下:
- 行号 (Line Numbers):需手动引入 CSS + JS。
- 显示语言 (Show Language):Hexo 会自动为代码块添加
data-language属性,配合 Prism 的 show-language 插件即可显示角标。 - 高亮特定行 (Line Highlight):Hexo 的代码块标签支持
mark参数(如{% codeblock mark:[1,3-5] %})。无论preprocess是 true 还是 false,Hexo 都会生成对应的 HTML 标记,但浏览器端模式下需确保引入了 line-highlight 插件的 JS/CSS。
五、总结与选型建议
面对两种引擎和多种配置,初学者该如何选择?
追求性能与 SEO (大多数博客):
- 选择 Highlight.js (默认) 或 PrismJS (preprocess: true)。
- 理由:高亮工作在构建时完成,用户打开网页即看到彩色代码,速度最快,对搜索引擎最友好。
- 配置要点:开启
line_number,根据需要调整tab_replace。如果使用 Highlight.js 且想套用官方主题,记得设hljs: true并关闭wrap。
追求极致插件功能:
- 选择 PrismJS (preprocess: false)。
- 理由:如果你需要使用 Prism 特有的复杂插件(如实时编辑高亮、复杂的悬浮提示),必须让它在浏览器端运行。
- 配置要点:记得手动在主题中引入对应的 JS 和 CSS 文件。
完全自定义:
- 禁用所有内置高亮 (
syntax_highlighter:留空)。 - 理由:你想引入最新版的 Highlight.js CDN,或者使用完全不同的着色方案。此时 Hexo 只负责输出最纯净的
<pre><code>结构。
- 禁用所有内置高亮 (
无论选择哪种方式,理解 line_number 与 wrap 的依赖关系,以及 preprocess 对 PrismJS 行为的决定性影响,是配置成功的关键。