当前位置: 首页 > 工具软件 > Docz > 使用案例 >

Docz 组件库文档实现方案(二)

耿弘阔
2023-12-01

Docz 组件库文档实现方案(二)

相关

定制化 Docz

1. 定制化项目配置

在 项目根目录创建一个名为 doczrc.js 的文件,通过这个文件来对项目进行配置,官方项目配置文档

// /doczrc.js
export default {
  /**
   * 要发布到网站的路径,例如 https://xxx.github.com/docs/ 默认 / ,注意必须 / 结尾
   * */
  base: "/docs/",
  /**
   * 限制那个资源目录下的规定文件会被生成文档
   */
  src: "./",
  /**
   * 规定哪些文件会被当做文档文件,string | string[]
   */
  files: "**/*.{md,markdown,mdx}",
  /**
   * 排除哪些文件
   */
  ignore: ["README.md"],
  /**
   * docz build 之后生成的静态文件到哪个目录
   */
  dest: "/build",
  /**
   * 网站的标题,默认是 package.json name
   */
  title: "Mjz Test UI",
  /**
   * 网站的描述,会生成 mate 标签,默认是 package.json description
   */
  description: "mjzhang1993 测试用 UI Components",
  /**
   * Typescript 项目开启,同时需要创建 tsconfig.json 文件
   */
  typescript: true,
  /**
   * 用来配置静态文件绝对路径,例如 ![placeholder image](/public/some-image.png)
   * NOTICE:亲测,无效,还是得用相对路径
   */
  public: "/public",
  /**
   * 默认的 Docz 文档中提供编辑跳转到 github 的功能,这个用来配置调转过去的分支名
   */
  editBranch: "main",
  /**
   * docz dev 环境的端口号配置,同样可配置 host
   */
  port: 3002,
  /**
   * 侧边导航的排序 可以是文档 name 的数组,也可以是一个配置对象如下,
   * 虽然可以在这里排序,但是如果每开发一个组件,还有到这里做一下排序,是比较麻烦的
   * 这个可以通过 自定义文档配置 + 自定义主题实现
  */
  menu: [
    "Feu", 
    { name: "Components", menu: ["Button", "Alert"] }, 
    "ChangeLog"
  ],
};

2. 开发环境定制化

开发组件库中不可避免要对 webpack 与 babel 进行一些配置,而我们的文档是直接引用的组件库组件,因此也有需要对 webpack 、babel 进行配置的可能

Docz 底层由 Gatsby 实现,Gatsby 相关的 Hooks 钩子都是支持的,我们可以借用 Gatsby 的配置来实现开发环境定制化,Gatsby Node APIs

const path = require("path");

// 定制化 Webpack 配置
exports.onCreateWebpackConfig = (args) => {
  args.actions.setWebpackConfig({
    resolve: {
      alias: {
          // 配置后就可以使用 import Button from `@/Button` 来引入组件了
        "@": path.resolve(__dirname, "../src/components/"), 
      },
    },
  });
};

// 定制化 Babel 配置
exports.onCreateBabelConfig = ({ actions }) => {
  actions.setBabelPlugin({
    name: `babel-plugin-emotion`,
    options: {
      sourceMap: true,
    },
  });
};

3. Docz 主题定制化

Docz 2.x 开始是通过 Gatsby 来实现的,默认使用了 gatsby-theme-docz 作为主题,而 Docz 实际上主要是帮助我们解析文件,处理数据,同时 提供一部分展示组件,用于 代码及 props 展示,因此要定制化 Docz 主题,需要从两部分入手,一个是 Gatsby 的 Component Shadowing 机制,一个是 Docz 提供的基本组件与 Hook 钩子

Docz 提供的 基础组件与 Hook Api

细致的说明可以看这里 官方Components & Hooks API ,下边会做简易的说明,具体使用会结合定制主题详细说明

  • <Playground> : 代码&组件展示组件,在 .mdx 文件中使用,用来渲染我们写的组件,并将其源码暴露出来
  • <Props> : 组件属性展示组件,在 .mdx 文件中使用,用来将我们所开发组件的 Props 自动列出来
  • <ComponentsProvider> : 这个组件要在自定义主题时使用,它接收一个 components 属性,其值是一个 map 用来映射 markdown 中元素映射为那种组件显示,可以用来定制化 docz 对 mdx 的渲染结果
  • useComponents() : Hooks,用在自定义主题时,可以获得向 <ComponentsProvider> 传入的 components Map
  • useDocs() : Hooks,用在自定义主题时, 获得关于docz 的数据,例如 menu 、route、以及如果我们有 “自定义文档配置” 这个 “自定义文档配置” 也可以通过这个方法拿到
  • useMenus() : Hooks,用在自定义主题时, 快速的拿到 menu 配置
  • useConfig() : Hooks,用在自定义主题时 获得关于 docz 的配置
  • theme(): 一个高阶组件,用来创建自定义主题,具体使用我们在案例中学习
Component Shadowing
  1. 首先我们需要先安装 yarn add gatsby gatsby-theme-docz, 实际上我们使用 Docz 安装 docz 时这两个 package 已经被安装了;
  1. 然后,我们进入 node_modules 查看一下 gatsby-theme-docz 的目录结构
# 进入
cd node_modules/gatsby-theme-docz/src/

# 打印出目录结构
tree -L 2

# 以下是我们需要关注目录结构部分
.
├── base
│   ├── Layout.js
│   └── Seo.js
├── components
│   ├── Code
│   ├── Header
│   ├── Headings
│   ├── Icons
│   ├── Layout
│   ├── Logo
│   ├── MainContainer
│   ├── NavGroup
│   ├── NavLink
│   ├── NavSearch
│   ├── Playground
│   ├── Pre
│   ├── Props
│   ├── Sidebar
│   └── index.js
├── hooks
│   └── useDbQuery.js
├── index.css
├── index.js
├── theme
│   ├── breakpoints.js
│   ├── colors.js
│   ├── global.js
│   ├── index.js
│   ├── modes.js
│   ├── prism
│   └── styles.js
├── utils
│   ├── mixins.js
│   └── theme.js
└── wrapper.js
  1. 在我们项目的 src 目录也创建一个名为 gatsby-theme-docz 的文件夹,然后,模仿 gatsby-theme-docz 下的文件结构创建如下组件, yarn docz:dev 即可在页面中发现,文档页面的 Header 部分被我们写的新组建替代了,通过这种 “遵循文件命名约定创建自己的文件来替换主题文件“,来实现自定义渲染结果的方式就是我们一直说的 Component Shadowing
// /src/gatsby-theme-docz/components/Header/index.tsx
import * as React from 'react';

export const Header = () => (
  <div>this is Header</div>
)

基本上 node_modules/gatsby-theme-docz/src/components/ 下的所有组件都可以通过遮蔽来实现自定义

创建我们自己的 Docz 主题

借助 Component Shadowing 我们可以一个一个的替换 node_modules/gatsby-theme-docz/src/components/ 下的组件,如果我们想要完全的定制化,可以直接创建 /src/gatsby-theme-docz/index.js 来替换node_modules/gatsby-theme-docz/src/index.js 这个文件

// /src/gatsby-theme-docz/index.js
/**
 * 自定义主题
*/
import React from 'react'
import { theme, useConfig, ComponentsProvider } from 'docz'
import { ThemeProvider } from 'theme-ui'
import baseComponents from 'gatsby-theme-docz/src/components'
import baseTheme from 'gatsby-theme-docz/src/theme'
/**
    注意: 如果使用自定义主题并且还要使用一部分 gatsby-theme-docz 的组件,那么我们就不能把 新组建目录命名为 components ,(即不能有 /src/gatsby-theme-docz/components/ 这个目录)这样会造成一些编译问题
*/
import customComponents from './customComponents' 

/**
 * markdow => html 的映射组件
 * 在这里仿照 gatsby-theme-docz 开发我们自己的替代组件
 * */ 
const componentsMap = {
  ...baseComponents,
  ...customComponents,
  /* your custom components */
}

const Theme = ({ children }) => {
  const config = useConfig();
  /**
   * ThemeProvider 是 theme-ui 的包装组件
   * docz 同样使用的 theme-ui 做样式展示
   * */ 
  return (
    <ThemeProvider theme={config.themeConfig}>
      <ComponentsProvider components={componentsMap}>
        {children}
      </ComponentsProvider>
    </ThemeProvider>
  )
}

/**
 * baseTheme: theme-ui 需要传入的样式配置,也可以在 doczrc.js 中配置 themeConfig
 * 我们这里使用的时 gatsby-theme-docz 默认的 theme 配置,也可以仿照它写一个新的
 */
export default theme(baseTheme)(Theme)

componentsMap 的可配置组件如下

const componentsMap = {
  h1: components.H1, // h1 ~ h6 标签都可以
  ul: components.List, 
  loading: components.Loading,
  table: components.Table,
  pre: components.Pre,
  inlineCode: components.Code,
  code: Code, // 代码展示
  playground: Playground, // 代码渲染及展示部分
  layout: Layout, // 整体布局,包括了 Header 部分与 侧边导航部分
  props: Props, // 组件属性展示部分
}
借助 Docz 主题实现侧边导航可排序

在 doczrc.js 中可以通过设置 ‘menu’ 来进行排序,但是如果每增加一个组件都要配置会显得比较 ”不智能“,因此我们可以通过定制化化主题时将侧边导航一并改掉

  1. 首先给每个 mdx 文件增加一个名为 weight 的 文档设置
---
name: Button
route: /button
menu: Components
weight: 2
---

---
name: Alert
route: /alert
menu: Components
weight: 1
---
  1. 创建一个新的 Menu 组件
// /src/gatsby-theme-docz/customComponents/Menu.js
import * as React from 'react'
import { useMenus, Link } from 'docz'

export const Menu = ({menus: prevMenus}) => {
  const menus = useMenus()
  // 使用 weight 字段来排序
  const sortMenus = (prevMenus || menus).sort((a, b) => (a.weight || 0) - (b.weight || 0))

  return (
    <ul>
      {sortMenus.map(menu => {
        if (Array.isArray(menu.menu)) {
          return (
            <li key={menu.id}>
              <Menu menus={menu.menu}/>
            </li>
          )
        }
        return (
          <li key={menu.id}>
            <Link to={menu.route}>{menu.name}</Link>
          </li>
        )
      })}
    </ul>
  )
}
  1. 自定义主题中引用,即可看到我们创建的 menu 组件
/**
 * 自定义主题
*/
import React from 'react'
import { theme, useConfig, ComponentsProvider } from 'docz'
import { ThemeProvider } from 'theme-ui'
import baseComponents from 'gatsby-theme-docz/src/components'
import baseTheme from 'gatsby-theme-docz/src/theme'
// import customComponents from './components/index'
import {Menu} from './customComponents/Menu';

const componentsMap = {
  ...baseComponents,
  // ...customComponents,
  /* your custom components */
}

const Theme = ({ children }) => {
  const config = useConfig();
  return (
    <ThemeProvider theme={config.themeConfig}>
      <Menu/>
      <ComponentsProvider components={componentsMap}>
        {children}
      </ComponentsProvider>
    </ThemeProvider>
  )
}

export default theme(baseTheme)(Theme)
 类似资料: