使用 @elastic/eui-docusaurus-theme 为 Docusaurus 文档站集成 Elastic UI 设计系统
2026/9/17 22:34:48 网站建设 项目流程

使用 @elastic/eui-docusaurus-theme 为 Docusaurus 文档站集成 Elastic UI 设计系统

【免费下载链接】euiElastic UI Framework 🙌项目地址: https://gitcode.com/GitHub_Trending/eu/eui

本文是一份针对@elastic/eui-docusaurus-theme(Elastic UI Framework 仓库packages/docusaurus-theme)的完整集成与开发指南。该主题通过 Docusaurus 的 Swizzling 机制,将经典主题组件替换为基于 EUI 组件与设计 token 的自定义实现,使文档站点获得与 EUI 官方文档 一致的视觉语言。读完本文,你将掌握:如何为 Docusaurus 项目安装并配置该主题(推荐 preset 与仅主题两种方式)、如何启用右侧导航栏的 changelog / github / figma 快捷链接、如何在本仓库中构建、打包并在本地进行端到端验证,以及主题内置的 Demo、PropTable、FigmaAsset 等文档增强组件能力。

背景:Docusaurus Swizzling 与 EUI 主题的原理

Docusaurus 自带@docusaurus/theme-classic(基于 Infima 默认 CSS 框架)渲染站点。EUI Docusaurus 主题同样以经典主题为基础,但利用 Docusaurus 官方的 Swizzling):

export default function euiDocusaurusTheme(): Plugin<void> { return { name: 'eui-docusaurus-theme', getThemePath() { return '../lib/theme'; }, getTypeScriptThemePath() { return '../src/theme'; }, }; }

它只是声明了主题渲染目录(编译后的lib/theme与 TS 源码src/theme),主题目录下 Swizzle 了一整套 Docusaurus 官方组件,包括AdmonitionCodeBlockColorModeToggleDocBreadcrumbsDocCardDocItemDocPaginatorDocSidebarItemEditThisPageFooterHeadingLogoMDXComponentsNavbarTOCCollapsibleTOCItems等(见 packages/docusaurus-theme/src/theme),每个组件内部都改用EuiXxx组件与 Emotion 样式实现。

全局样式的注入发生在根组件(packages/docusaurus-theme/src/theme/Root.tsx)中:用AppThemeProvider包裹站点,通过 Emotion 的CacheProviderGlobal同时加载 reset 样式、精简版 Infima 样式与 EUI 全局样式,并根据明暗模式动态注入@elastic/chartstheme_only_light.css/theme_only_dark.css图表主题。

集成前置条件:依赖、TypeScript 与 Babel

在安装主题之前,需要先把 Docusaurus 项目调整到兼容状态。

1. 安装所需依赖包

yarn add @emotion/react @emotion/css @elastic/charts

这三个依赖是运行前提:@emotion/react是主题所有样式的基础运行时,@emotion/css提供非 React 场景的 CSS 生成能力,@elastic/charts则用于文档站内嵌的 Elastic 图表 Demo。主题自身的依赖清单可查看 packages/docusaurus-theme/package.json,其中还包含@elastic/eui(workspace 内联版本)、@elastic/eui-theme-borealisprism-react-renderer(代码高亮)、react-live(Demo 实时编辑)等。

2. 配置 TypeScript

在你的项目tsconfig.json中追加两项编译选项,让 JSX 编译默认走 Emotion 的 runtime:

{ // This file is not used in compilation. It is here just for a nice editor experience. "extends": "@docusaurus/tsconfig", "compilerOptions": { "baseUrl": ".", + "jsxImportSource": "@emotion/react", + "moduleResolution": "nodenext" } }

其中jsxImportSource告诉 TypeScript 将jsx自动导入指向@emotion/react(主题内部即采用jsx: "react-jsx"+jsxImportSource: "@emotion/react"的配置,见 packages/docusaurus-theme/tsconfig.json);moduleResolution: "nodenext"则与 Docusaurus 3.x 的模块解析约定保持一致。EUI 文档站自身的配置也是完全相同的写法(见 packages/website/tsconfig.json)。

3. 配置 Babel

为了让 Emotion 接管importSource,需要追加@babel/preset-react

module.exports = { presets: [ require.resolve('@docusaurus/core/lib/babel/preset'), + [ + '@babel/preset-react', + { runtime: 'automatic', importSource: '@emotion/react' }, + ], ], };

runtime: 'automatic'表示无需在每个文件手动import ReactimportSource: '@emotion/react'则让 JSX 转换后的辅助函数从 Emotion 导入,从而启用其 css prop 能力。

推荐安装方式:使用 Docusaurus preset

官方推荐通过 preset 一体化接入,它同时为你装配好主题与配套插件:

# npm npm install @elastic/eui-docusaurus-preset @elastic/eui-docusaurus-theme # pnpm pnpm add @elastic/eui-docusaurus-preset @elastic/eui-docusaurus-theme # Yarn yarn add @elastic/eui-docusaurus-preset @elastic/eui-docusaurus-theme

然后在docusaurus.config.ts中注册 preset:

const config: Config = { // ... presets: [ require.resolve('@elastic/eui-docusaurus-preset'), // ... ], // ... }

preset 内部装配了什么

从 packages/docusaurus-preset/src/index.ts 可以清楚看到 preset 的组合逻辑:

  • 主题:先加载@docusaurus/theme-classic(EUI 主题基于它),再加载@elastic/eui-docusaurus-theme,由后者的 Swizzle 组件覆盖前者;
  • 插件:固定装配@docusaurus/plugin-content-docs@docusaurus/plugin-content-pages@docusaurus/plugin-svgrblog选项默认开启,传false可关闭;生产构建(NODE_ENV === 'production')时额外启用@docusaurus/plugin-sitemap
  • 可选分析插件:当配置了googleAnalytics/googleTagManager/gtag选项时,分别注册对应的 Google 统计插件。

preset 支持的选项类型在 packages/docusaurus-preset/src/options.ts 中定义:docspagessvgrsitemap(生产环境启用)、themeblog(可传false禁用)以及三个 Google 统计项。EUI 文档站的实际用法可参考 packages/website/docusaurus.config.ts,它传入了docs(含sidebarPatheditUrl、自定义 admonition 关键词)、blogshowReadingTime)与googleTagManager等选项。

ignore-styles-plugin:解决 Infima 与 EUI 的样式冲突

preset 还内嵌了一个名为ignore-styles-plugin的自定义插件,这是"推荐使用 preset 而非单独主题"的关键原因。Docusaurus 经典主题依赖 Infima 的全局样式,而这些全局样式往往会覆盖或干扰 EUI 设计系统,导致观感不一致。该插件通过 Webpack 规则把 Infima 与相关主题样式的导入"吞掉":

const ignoreInheritedStylesPlugin: PluginModule = () => ({ name: 'ignore-styles-plugin', configureWebpack() { return { module: { rules: [ { test: /node_modules\/infima/, use: 'null-loader', }, { test: /node_modules\/@docusaurus\/theme-common\/lib\/hooks\/styles.css/, use: 'null-loader', }, ], }, }; }, });

见 packages/docusaurus-preset/src/index.ts。null-loader让匹配到的样式模块不产生任何输出,从而保证 Infima 不会污染全局 CSS 作用域、不会影响 EUI 组件的渲染。

仅使用主题(Theme only)的备选方案

如果你不想引入整个 preset,也可以只安装主题包:

# npm npm install @elastic/eui-docusaurus-theme # pnpm pnpm add @elastic/eui-docusaurus-theme # Yarn yarn add @elastic/eui-docusaurus-theme

并在docusaurus.config.ts中同时注册经典主题与 EUI 主题:

const config: Config = { // ... themes: [ require.resolve('@docusaurus/theme-classic'), // Required for compatibility require.resolve('@elastic/eui-docusaurus-theme'), ], // ... }

注意@docusaurus/theme-classic是必需的:EUI 主题基于经典主题的组件结构做 Swizzle,需要它提供兼容基础。另外,单独使用主题时无法获得 preset 内置的ignore-styles-plugin,Infima 的全局样式会保留,可能与 EUI 的样式产生冲突——这是 README 明确强调"强烈建议使用 preset"的原因。

特性:右侧导航栏快捷链接

要复现 EUI 文档站右侧的导航链接效果,需要在themeConfig.navbar.items中给条目添加component属性,取值只能是"changelog" | "github" | "figma"

themeConfig: { // ... navbar: { // ... items: [ // ... // Use component: "changelog" | "github" | "figma" { href: "https://github.com/elastic/eui/tree/main/packages/eui/changelogs", label: "EUI Changelog", position: "right", component: "changelog", }, { href: "https://github.com/elastic/eui", label: "GitHub", position: "right", component: "github", }, { href: "https://www.figma.com/community/file/964536385682658129", label: "Figma", position: "right", component: "figma", }, ], }, // ... }

底层实现:CUSTOM_LINK_COMPONENT_MAP

这些component值在 packages/docusaurus-theme/src/theme/NavbarItem/NavbarNavLink.tsx 中通过CUSTOM_LINK_COMPONENT_MAP映射为自绘的图标按钮:

  • github:内联的 GitHub 品牌 SVG 图标;
  • changelog:使用 EUI 内置的popper图标;
  • figma:内联的 Figma 品牌 SVG 图标。

NavbarNavLink检测到component命中映射表时,会渲染自研的 NavbarItem 组件——它基于EuiIconEuiToolTip构建,圆形悬停背景、明暗模式适配、选中态高亮,并在非浏览器环境(SSR)下禁用交互。EUI 文档站配置中实际启用了changeloggithub两项,figma因社区 Figma 文件过期而暂时注释停用(见 packages/website/docusaurus.config.ts),这提供了一个"参考真实用法 + 关闭某项"的现成范例。

本地开发与测试

环境前置要求

  • Node.js:版本要求见仓库根目录的 .nvmrc(当前为24.19.0);
  • corepack:用于固定 Yarn 版本。

安装依赖与构建

yarn
yarn build

build脚本执行tsc --build,产物输出到lib/目录(见 packages/docusaurus-theme/package.json 的 scripts 与 packages/docusaurus-theme/tsconfig.json 的outDir)。

监听模式(watch)

yarn start

start脚本执行tsc --watch,文件变更时自动增量编译。注意:该包配置了增量构建(incremental: true,见 tsconfig),某些情况下tsc可能不会把重命名或删除文件的变化同步到lib目录;如果遇到这种情况,请手动执行一次yarn build做全量构建。

用 EUI 官方文档站联调

在 monorepo 根目录运行以下命令启动 EUI 文档网站:

yarn workspace @elastic/eui-website start

修改 Docusaurus 主题源码时,可同时开启上面的 watch 模式(yarn start),文档站会实时反映主题改动。

用自己的 Docusaurus 项目本地验证

先在本地创建一个全新的 Docusaurus TypeScript 项目:

npx create-docusaurus@latest my-website classic --typescript

回到 EUI monorepo 根目录,构建并打包 preset 与 theme 两个包:

# Build packages yarn workspace @elastic/eui-docusaurus-theme build yarn workspace @elastic/eui-docusaurus-preset build # Pack packages cd packages/docusaurus-theme yarn pack --filename docusaurus-theme.tgz cd ../docusaurus-preset yarn pack --filename docusaurus-preset.tgz

my-website项目中先安装 EUI 运行依赖:

# npm npm install @elastic/eui @elastic/charts @emotion/react @emotion/css moment # pnpm pnpm add @elastic/eui @elastic/charts @emotion/react @emotion/css moment # Yarn yarn add @elastic/eui @elastic/charts @emotion/react @emotion/css moment

再安装两个本地打包产物:

# npm npm install /path/to/eui/packages/docusaurus-preset/docusaurus-preset.tgz /path/to/eui/packages/docusaurus-theme/docusaurus-theme.tgz # pnpm pnpm add /path/to/eui/packages/docusaurus-preset/docusaurus-preset.tgz /path/to/eui/packages/docusaurus-theme/docusaurus-theme.tgz # Yarn yarn add /path/to/eui/packages/docusaurus-preset/docusaurus-preset.tgz /path/to/eui/packages/docusaurus-theme/docusaurus-theme.tgz

最后按照上文"使用 preset"一节配置docusaurus.config.ts即可。

迭代修改流程

对 preset 或 theme 做出修改后,需要依次执行:

  1. 重新构建并打包两个包(yarn workspace ... build+yarn pack);
  2. 在你的项目中重新安装.tgz产物;
  3. 重启 Docusaurus 开发服务器:
# npm npm run start # pnpm pnpm start # Yarn yarn start

主题内置的文档增强组件

除了主题组件,packages/docusaurus-theme/src/components/index.ts 还导出了一批可直接在 MDX 文档中使用的增强组件(EUI 文档站自身大量使用,可用于写作组件 API 文档与交互示例):

组件作用
Demo/createDemo/DemoSource交互式 Demo 容器:基于react-live提供可编辑源码、实时预览、明暗主题代码高亮(dark 用 Dracula、light 用 GitHub 主题)、一键复制与 CodeSandbox 导出
PropTable自动渲染组件 Props 类型表格
FigmaAsset输出 Figma 资源,支持默认的 SVG 图片输出或 iframe 嵌入两种模式
Guideline/GuidelineText撰写设计指南/规范文本
Badge渲染徽标
Icon渲染 EUI 图标
AppThemeContext/useAppTheme读写站点的 EUI 明暗主题(持久化到localStorage
HighContrastModeToggle高对比度模式切换

其中Demo组件的 Props 定义在 packages/docusaurus-theme/src/components/demo/demo.tsx:isSourceOpen控制源码编辑器默认是否展开;scope允许把组件/函数/对象注入 Demo 作用域(同时配合 import 剥离机制,相对 import 也会被移除,所有引用都必须通过scope传入);extraFiles允许附加额外文件到 CodeSandbox 实例;previewPaddingpreviewWrapper控制预览区样式。createDemo则是用预置 Props 批量创建定制 Demo 的工厂函数(见 packages/docusaurus-theme/src/components/demo/create_demo.tsx)。

版本演进速览

从 packages/docusaurus-theme/changelogs 可以看到主题的持续演进,一些值得注意的能力变化:

  • v2.8.0:文档导航栏 EUI 标志增加悬停动画,修复VersionSwitcher行重叠与悬停高亮问题;
  • v2.7.0FigmaEmbed重构为更通用的FigmaAsset,默认输出 SVG 图片资源,也可输出 Figma embed iframe;
  • v2.5.0:文档标题锚点链接与导航栏图标统一改用EuiToolTip(替代原生title属性),Demo源码编辑器配色随明暗模式切换;
  • v2.2.0Demo组件新增extraFiles属性;IMPORT_REGEX扩展为覆盖相对导入;
  • v2.0.0:新增HighContrastModeToggle并置为导航栏主条目,同时移除旧的ThemeSwitcher(破坏性变更)。

如果你需要了解某个具体版本的功能细节或破坏性变更,直接查阅对应年份的 changelog 文件即可。

小结

@elastic/eui-docusaurus-theme通过 Swizzling 机制将 EUI 设计系统完整地带入 Docusaurus 生态:preset 方式一键解决主题装配与 Infima 样式冲突,theme-only 方式适合需要自行控制插件组合的场景;右侧导航component快捷链接、Demo/PropTable/FigmaAsset等组件则让技术文档的编写与展示水平直接对齐 EUI 官方文档站。若要深度定制或参与改进,可参照本文的本地构建、pack 与联调流程在本仓库中直接迭代验证。

【免费下载链接】euiElastic UI Framework 🙌项目地址: https://gitcode.com/GitHub_Trending/eu/eui

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询