前端后端知识管理【免费下载链接】gitbookThe open source frontend for GitBook doc sites项目地址https://gitcode.com/gh_mirrors/gi/gitbook点击查看免费下载GitBook 的文档站点前端packages/gitbook在代码块渲染上做了一个关键的打包优化把 Shiki 语法高亮引擎从初始页面 bundle 中剔除只让客户端在真正需要时按需加载。本文基于仓库中 .changeset/shiki-out-of-initial-bundle.md 描述的改动结合packages/gitbook/src/components/DocumentView/CodeBlock/下的源码实现讲解这套拆分高亮器与纯文本 token 辅助函数的模块划分方案、懒加载调用链以及对应的测试验证帮助你理解如何在 Next.js/React 应用中为重型语法高亮依赖做 bundle 瘦身。改动背景共享 import 让 Shiki 引擎泄漏进初始包changeset 原文只有一句话核心意图非常明确Keep Shiki out of the initial page bundle by splitting the highlighter from the plain-text token helpers, so client code no longer pulls the engine and language bundles in through a shared import.意思是把高亮器highlighter与纯文本 token 辅助函数plain-text token helpers拆开让客户端代码不再因为一个共享的 import 就把 Shiki 引擎和语言包language bundles带进初始页面包。在拆分之前代码块相关的公共模块同时承担两类职责一是纯函数式的 token 处理拼接代码文本、解析 diff 标记、截断 token、匹配行内注解二是真正调用 Shiki 的引擎初始化与codeToTokens高亮计算。只要客户端代码从同一个模块 import 任何内容构建工具就会把该模块及其全部依赖——包括 Shiki 引擎和数十种语言 bundle——一并打进初始 chunk即使页面上的大部分代码块根本不需要立即高亮。拆分后的现状可以从 packages/gitbook/src/components/DocumentView/CodeBlock/ 目录结构直接看出highlight-tokens.ts、highlight.ts、plain-highlight.ts三个文件各司其职文件职责是否引入 Shiki 运行时highlight-tokens.ts类型定义与纯文本 token 辅助函数否仅 type-only importplain-highlight.ts无引擎的朴素高亮降级渲染仅shiki/themes的主题元信息highlight.ts真正的 Shiki 高亮器引擎 语言 主题是完整的引擎与语言包highlight-tokens.ts纯文本辅助层的拆分锚点highlight-tokens.ts 是这个改动的关键产物。文件顶部的注释直接点明了拆分动机// Split from ./highlight so client code can use these helpers without dragging Shikis engine // and language bundles into the initial chunk. Imports from shiki/core here must stay type-only.也就是说所有从shiki/core的 import 必须保持 type-only这样它们只参与类型推导不会在运行时引入 Shiki 的引擎代码。该文件定义了代码块渲染的数据模型与核心纯函数类型体系HighlightTheme含bg/fg/themes/lines、HighlightLine、HighlightToken联合类型plain纯文本 /shiki高亮 token /annotation行内注解、PositionedToken、RenderedInline等getPlainCodeBlock把DocumentBlockCode的节点树拍平成纯文本字符串同时收集行内注解annotation与表达式expression的start/end位置信息供后续 token 与行内元素对齐使用。表达式会通过options.evaluateInlineExpression回调求值后写入文本parseDiffNotation识别行尾的源码 diff 标记如// [!code ]、# [!code --]、!-- [!code ] --、/* [!code --] */注释明确要求与 gitbook-x 解析器保持正则逐字节一致NOTATION_PATTERN返回added/deleted及标记起始位置truncateHighlightTokens/getHighlightTokensText按字符数截断 token 序列递归进入注解子节点或把 token 序列重新拼接为文本用于剥离 diff 标记matchTokenAndInlines核心的token 与行内注解对齐算法——把 Shiki token 按行内元素的位置切分splitPositionedTokenAt支持一个 token 覆盖多个注解一个注解横跨多个 tokentoken 在注解内部结束等边界情况DEFAULT_THEMES默认使用CustomizationCodeTheme.DefaultLight/DefaultDark作为亮暗主题。这个文件可以被任何不需要高亮引擎的模块安全引用——例如 Prompt.tsx 和 MermaidCodeBlock.tsx 都只从这里导入getPlainCodeBlock而 CodeBlockRenderer.tsx 则只导入类型。plain-highlight.ts不进引擎的朴素高亮路径plain-highlight.ts 提供plainHighlight函数不调用 Shiki 的 tokenizer而是直接把代码行按节点结构转成plain/annotationtoken。它只从shiki/themes导入bundledThemesInfo主题元信息不含语法引擎用于把主题名称解析为轻量的主题对象。该函数承担两类场景语言未知时的降级在 highlight.ts 的highlight()中如果getBlockLang(block)返回null例如没有指定syntax就回退到plainHighlight客户端渲染的初始呈现见下文 ClientCodeBlock.tsx高亮器尚未加载完成前先用plainHighlight同步渲染出朴素代码块保证首屏有内容。plainHighlight同样完整处理 diff 标记检测与截断针对拼接后的 token 文本做parseDiffNotation以便把求值后的行内表达式纳入偏移计算并输出与highlight()完全一致的HighlightTheme结构因此渲染层无需区分数据来源。highlight.ts引擎侧的唯一入口highlight.ts 是唯一真正实例化 Shiki 引擎的模块其 imports 暴露了引擎的全部重量import { createSingletonShorthands, createdBundledHighlighter } from shiki/core; import { createJavaScriptRegexEngine } from shiki/engine/javascript; import { type BundledLanguage, bundledLanguages } from shiki/langs; import { bundledThemes } from shiki/themes;引擎配置使用createdBundledHighlighter创建单例高亮器注册全部bundledLanguages语言与bundledThemes主题并合并./customThemes自定义主题词法引擎选用createJavaScriptRegexEngine({ forgiving: true, target: ES2018 })即纯 JS 正则引擎无需 WASMpreloadHighlight按代码块的语言与亮暗主题预加载高亮器供客户端挂载时提前预热highlight获取单例高亮器后调用codeToTokens传入themes亮/暗双主题、defaultColor: light-dark()让 Shiki 输出 CSS 的light-dark()函数以适配站点明暗模式以及tokenizeMaxLineLength——单行代码块放宽到 5000 字符多行则限 400 字符避免极端行拖垮性能语言归一化getLanguageForSyntax会把语法名转小写并通过syntaxAliases处理 GitBook 特有的别名例如parser→blade、objectivec→objective-c模块末尾export * from ./highlight-tokens保留向后兼容的导出面同时该文件也被 highlight.test.ts 作为测试入口。客户端调用链动态 import 与视口懒加载拆分真正的收益体现在客户端渲染路径上。ClientCodeBlock.tsx 是一个use client组件其注释说明了设计目标Render a code-block client-side by loading the highlighter asynchronously. It allows us to defer some load to avoid blocking the rendering of the whole page with block highlighting.关键点在于该文件顶层只 importplainHighlight和类型对highlight.ts一律使用动态import()且只在两种时机触发挂载预加载useEffect中import(./highlight).then(({ preloadHighlight }) preloadHighlight(block, themes))块一旦挂载就开始预热高亮器进入视口后真正高亮通过useInViewportListenerrootMargin: 200px检测代码块是否接近视口滚动过程中由useDebounceCallback100ms推迟判定避免滚动时反复触发进入视口后才import(./highlight).then(({ highlight }) ...)执行真正的 Shiki 高亮。在高亮器就绪前theme状态为null渲染层拿到的是plainThemeuseMemo同步计算的plainHighlight结果代码块先以朴素形式展示等异步高亮完成后无缝切换为着色后的theme。整个交互期间aria-busy标记保持代码块可访问性。渲染层 CodeBlockRenderer.tsx 则统一消费HighlightTheme把 token 的htmlStyle、背景/前景色Shiki 返回的defaultColor;--shiki-light:...;--shiki-dark:...字符串由parseShikiColorString拆成 Reactstyle对象以及行号、diff 行、高亮行、展开折叠等特性全部落到 DOM。收益与验证收益由于客户端代码ClientCodeBlock、CodeBlockRenderer、MermaidCodeBlock、Prompt等不再通过共享模块间接引入shiki/core的引擎与shiki/langs语言包初始页面 bundle 得以显著瘦身Shiki 引擎与语言资源只在代码块真正进入视口时才按需加载。这与仓库 CHANGELOG 中此前针对 Shiki 的优化如升级 Shiki 并改用 JS RegExp 引擎、减小 server 输出的 bundle 体积、跳过非必要主题等见 packages/gitbook/CHANGELOG.md一脉相承当前依赖版本为shiki: ^3.21.0见 packages/gitbook/package.json。验证highlight.test.ts 用bun:test覆盖了拆分后语义的一致性包括无语法时的纯文本解析、多种语言并行高亮、多行代码、单行与跨行行内注解的 token 切分、token 在注解内结束/多个 token 落在同一注解等边界、\r字符清理以及 diff 标记的识别与剥离JS 的// [!code ]、Python 的# [!code --]、HTML 的!-- [!code ] --、CSS 的/* [!code --] */非行尾标记不识别。这些测试同时断言了plainHighlight降级路径与引擎高亮路径在 diff 处理上的一致性为模块拆分后的行为等价性提供了保障。关键文件索引改动声明.changeset/shiki-out-of-initial-bundle.md纯文本辅助层type-only供客户端安全引用highlight-tokens.ts无引擎降级高亮plain-highlight.ts引擎侧高亮入口highlight.ts客户端懒加载调用链ClientCodeBlock.tsx渲染层CodeBlockRenderer.tsx行为测试highlight.test.ts实践启示如果你的 Next.js/React 项目同样重度依赖 Shiki 这类引擎 语言包的库可以复制这套模式——把纯函数与类型抽到仅使用 type-only import 的模块中让客户端代码只依赖轻量模块把引擎入口留给动态import()再结合视口检测与预加载即可在不改变渲染语义的前提下把重型依赖移出初始 bundle。赞分享前端后端知识管理【免费下载链接】gitbookThe open source frontend for GitBook doc sites项目地址https://gitcode.com/gh_mirrors/gi/gitbook点击查看免费下载相关推荐Shiki 语法高亮器基于 TextMate 语法与主题的高精度高亮引擎入门指南Shiki 语法高亮器基于 TextMate 语法与主题的高精度高亮引擎入门指南 Shiki式取自日语中表示 Style 的词汇是一个基于 Text前端开发工具BlockNote 代码块语法高亮从 blocknote/code-block 到自定义 Shiki 高亮器BlockNote 代码块语法高亮从 blocknote/code block 到自定义 Shiki 高亮器 本篇技术指南以 BlockNote 仓库中的前端富文本UI组件AI 应用Shiki 性能优化实践指南从高亮器复用到细粒度打包与正则引擎选型Shiki 性能优化实践指南从高亮器复用到细粒度打包与正则引擎选型 本篇指南以 Shiki 官方文档 docs/guide/best performance.前端开发工具上一篇在 Roo Code 中接入 Baseten Model APIs配置指南与底层实现解析下一篇Haystack BraveWebSearch 组件详解使用 Brave Search API 构建联网 RAG 与网页检索管线创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考