解决 highlight.js 不支持语言的方法

一、前端高亮不支持语言的问题及解决方案

在前端技术文章或代码展示中,我们通常使用 highlight.js 来实现代码高亮。highlight.js 支持大部分常见语言,如 JavaScript、TypeScript、HTML、CSS 等,但对于一些冷门或自定义语言(如 conf 配置文件、特定 DSL),默认情况下并不支持。这就可能出现以下问题:

  1. 代码无法高亮显示,显示为纯文本。

  2. 为了避免报错,开发者通常会临时替代语言,导致高亮不准确。

  3. 可维护性差,新增语言时需要修改逻辑或写额外判断。

下面整理几种常用解决方案。


二、方法一:语言替代(折中方案)

最简单的做法是 用已有语言代替不支持的语言 。例如,将 conf 配置文件当作 bash 高亮:

javascript 复制代码
md.options.highlight = (str: string, lang: string) => {
  if (lang === 'conf') {
    lang = 'bash'
  }
  lang = lang || 'plaintext' // highlight 支持 plaintext
  if (hljs.getLanguage(lang)) {
    return hljs.highlight(str, { language: lang }).value
  }
  return hljs.highlightAuto(str).value
}

优点:

  • 简单快捷,无需额外注册语言。

缺点:

  • 高亮语法可能不准确。

  • 难以扩展,新增语言需要写 if 分支。


三、方法二:使用 registerLanguage 注册语言别名(推荐)

更规范的做法是使用 highlight.js 提供的 registerLanguage API,将不支持语言注册为已有语言规则或自定义规则

1. 注册已有语言作为别名

javascript 复制代码
import hljs from 'highlight.js/lib/core'
import bash from 'highlight.js/lib/languages/bash'

hljs.registerLanguage('bash', bash)
hljs.registerLanguage('conf', bash) // 将 conf 注册为 bash 的语法

然后在 markdown-it 高亮函数里直接使用:

javascript 复制代码
md.options.highlight = (str: string, lang: string) => {
  if (lang && hljs.getLanguage(lang)) {
    return hljs.highlight(str, { language: lang }).value
  }
  return hljs.highlightAuto(str).value
}

优点:

  • 代码逻辑更清晰,无需 if (lang === 'conf')

  • 可维护性强,新增别名只需注册一次。

缺点:

  • 高亮语法依旧复用已有语言,可能不完全匹配目标语言。

2. 注册自定义语言

如果希望高亮完全匹配,可以自定义语言规则:

javascript 复制代码
import hljs from 'highlight.js/lib/core'

const confLang = function (hljs: any) {
  return {
    name: 'conf',
    contains: [
      hljs.COMMENT('#', '$'),
      { className: 'keyword', begin: '\\b(server|port|timeout)\\b' },
      { className: 'string', begin: '"', end: '"' },
    ]
  }
}

hljs.registerLanguage('conf', confLang)

然后同样在 markdown-it 或直接调用 hljs.highlight 时使用即可。

优点:

  • 高亮准确,完全匹配自定义语法。

  • 扩展性强,可随时增加新语言规则。


四、方法三:按需加载语言(优化体积)

对于 Vite、Webpack 等前端项目,如果引入了 highlight.js 完整版本,体积可能偏大。可以使用 core + registerLanguage 按需加载语言:

javascript 复制代码
import hljs from 'highlight.js/lib/core'
import javascript from 'highlight.js/lib/languages/javascript'
import bash from 'highlight.js/lib/languages/bash'

hljs.registerLanguage('javascript', javascript)
hljs.registerLanguage('bash', bash)
hljs.registerLanguage('conf', bash) // 别名

这样只打包需要的语言,体积更小。

不使用 core 版本,而是 highlight.js 的完整版,就不用手动注册语言

highlight.js 有两个主要安装方式

  1. 完整版(highlight.js

    • 默认包含 全部常见语言的解析器

    • 即使你不注册语言,hljs.highlight(str, { language: 'js' }) 也能直接工作

    • 所以你"没注册也能用",是因为这些语言在 bundle 里已经内置了

  2. 核心版(highlight.js/core

    • 不包含任何语言解析器

    • 必须手动 registerLanguage 才能生效

    • 适合按需加载语言、优化打包体积


五、总结

方法 适用场景 优缺点
语言替代(if 分支) 快速处理少量不支持语言 简单但高亮不准确,扩展性差
registerLanguage 注册别名 已有语言可以复用规则 逻辑清晰、易维护,高亮有限
自定义语言注册 需要精准高亮的自定义语法 高亮准确,灵活,维护成本略高
按需注册 前端项目优化体积 减少打包大小,需手动注册语言

六、推荐实践

  1. 快速展示代码 → 使用语言替代或注册别名。

  2. 技术文章或需要精准语法高亮 → 自定义语言注册。

  3. 前端项目优化 → 使用 core + 按需注册语言。

  4. markdown-it 集成 → 高亮函数统一调用 hljs.highlight,避免在逻辑中写太多 if

通过这些方法,你可以优雅地解决 highlight.js 不支持语言的问题,同时保证代码可维护、可扩展,并可优化前端打包体积。

相关推荐
草履虫建模13 小时前
力扣算法 1768. 交替合并字符串
java·开发语言·算法·leetcode·职场和发展·idea·基础
naruto_lnq15 小时前
分布式系统安全通信
开发语言·c++·算法
Mr Xu_16 小时前
告别冗长 switch-case:Vue 项目中基于映射表的优雅路由数据匹配方案
前端·javascript·vue.js
前端摸鱼匠16 小时前
Vue 3 的toRefs保持响应性:讲解toRefs在解构响应式对象时的作用
前端·javascript·vue.js·前端框架·ecmascript
学嵌入式的小杨同学16 小时前
【Linux 封神之路】信号编程全解析:从信号基础到 MP3 播放器实战(含核心 API 与避坑指南)
java·linux·c语言·开发语言·vscode·vim·ux
sleeppingfrog16 小时前
zebra通过zpl语言实现中文打印(二)
javascript
Re.不晚16 小时前
Java入门17——异常
java·开发语言
精彩极了吧16 小时前
C语言基本语法-自定义类型:结构体&联合体&枚举
c语言·开发语言·枚举·结构体·内存对齐·位段·联合
南极星100517 小时前
蓝桥杯JAVA--启蒙之路(十)class版本 模块
java·开发语言
未来之窗软件服务17 小时前
未来之窗昭和仙君(六十五)Vue与跨地区多部门开发—东方仙盟练气
前端·javascript·vue.js·仙盟创梦ide·东方仙盟·昭和仙君