在 项目根目录创建一个名为
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"
],
};
开发组件库中不可避免要对 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,
},
});
};
Docz 2.x 开始是通过 Gatsby 来实现的,默认使用了
gatsby-theme-docz
作为主题,而 Docz 实际上主要是帮助我们解析文件,处理数据,同时 提供一部分展示组件,用于 代码及 props 展示,因此要定制化 Docz 主题,需要从两部分入手,一个是 Gatsby 的Component Shadowing
机制,一个是 Docz 提供的基本组件与 Hook 钩子
细致的说明可以看这里 官方Components & Hooks API ,下边会做简易的说明,具体使用会结合定制主题详细说明
<Playground>
: 代码&组件展示组件,在 .mdx 文件中使用,用来渲染我们写的组件,并将其源码暴露出来<Props>
: 组件属性展示组件,在 .mdx 文件中使用,用来将我们所开发组件的 Props 自动列出来<ComponentsProvider>
: 这个组件要在自定义主题时使用,它接收一个 components 属性,其值是一个 map 用来映射 markdown 中元素映射为那种组件显示,可以用来定制化 docz 对 mdx 的渲染结果useComponents()
: Hooks,用在自定义主题时,可以获得向 <ComponentsProvider>
传入的 components MapuseDocs()
: Hooks,用在自定义主题时, 获得关于docz 的数据,例如 menu 、route、以及如果我们有 “自定义文档配置” 这个 “自定义文档配置” 也可以通过这个方法拿到useMenus()
: Hooks,用在自定义主题时, 快速的拿到 menu 配置useConfig()
: Hooks,用在自定义主题时 获得关于 docz 的配置theme()
: 一个高阶组件,用来创建自定义主题,具体使用我们在案例中学习
- 首先我们需要先安装
yarn add gatsby gatsby-theme-docz
, 实际上我们使用 Docz 安装docz
时这两个 package 已经被安装了;
- 然后,我们进入 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
- 在我们项目的 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/
下的所有组件都可以通过遮蔽来实现自定义
借助
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, // 组件属性展示部分
}
在 doczrc.js 中可以通过设置 ‘menu’ 来进行排序,但是如果每增加一个组件都要配置会显得比较 ”不智能“,因此我们可以通过定制化化主题时将侧边导航一并改掉
- 首先给每个 mdx 文件增加一个名为
weight
的 文档设置
---
name: Button
route: /button
menu: Components
weight: 2
---
---
name: Alert
route: /alert
menu: Components
weight: 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>
)
}
- 自定义主题中引用,即可看到我们创建的 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)