如何生成组件文档与示例
解读
在国内前端团队里,组件库沉淀已成标配,面试官问“怎么用 Grunt 把组件文档和示例跑起来”,核心想验证三件事:
- 你是否理解 Grunt 的“任务链”思维,能把文档生成、Demo 编译、静态服务器、热刷新串成一条闭环;
- 你是否熟悉国内主流文档引擎(JSDoc、Docz、Storybook、VitePress)并知道如何用 Grunt 插件或自定义任务去驱动;
- 你是否能把产物部署到内网 GitLab Pages、腾讯 COS、阿里云 OSS 等国内常见静态托管,实现“文档即交付”。
回答时务必给出可落地的 Gruntfile 片段,并解释每一步在国内网络环境下的踩坑点与加速方案。
知识点
- grunt-jsdoc:把 JSDoc 注释转成静态 HTML,支持自定义主题 cn.docstrap 以解决国内访问慢的问题。
- grunt-webpack 或 grunt-contrib-webpack5:把示例目录
examples/*.md或*.stories.jsx打包成 umd bundle,供 iframe 嵌入。 - grunt-contrib-copy + grunt-contrib-clean:把 README、CHANGELOG、设计图一键拷到 docs/dist,保证交付物完整。
- grunt-contrib-connect + grunt-contrib-watch:本地起 8080 端口,配合 livereload 实现“改注释→刷新文档”的秒级反馈。
- grunt-gh-pages(私有版 grunt-gitlab-pages):CI 阶段把
docs/dist推至内网 GitLab Pages 或 OSS,实现 MR 即预览。 - 多语言示例:用 grunt-i18n-extract 把 Vue/React 组件的
$t文案抽成 json,再让文档站切换中英文,满足国内“出海”业务需求。 - 性能优化:通过 grunt-aliyun-oss 开启 gzip、cache-control、cdn 刷新,解决首次打开白屏;用 grunt-tinypng 把示例截图压到 100 KB 以内,降低移动端流量。
答案
下面给出一条“零到一”可复制的 Grunt 任务链,覆盖开发、构建、部署三阶段,全部插件均在国内镜像源可拉取。
- 安装依赖(使用淘宝源)
npm i -D grunt grunt-cli grunt-jsdoc grunt-webpack grunt-contrib-copy grunt-contrib-clean grunt-contrib-connect grunt-contrib-watch grunt-gh-pages cn.docstrap
- 目录约定
src/
└─ Button/
├─ index.jsx
├─ index.md // 示例 Markdown
└─ README.md // API 注释
docs/
└─ dist/ // 生成物
- Gruntfile.js 核心片段
module.exports = function(grunt) {
grunt.initConfig({
// 1. 生成 API 文档
jsdoc: {
dist: {
src: ['src/**/*.js*', '!src/**/*.test.js'],
options: {
destination: 'docs/dist/api',
configure: './jsdoc.json',
template: 'node_modules/cn.docstrap/template' // 国内加速主题
}
}
},
// 2. 把示例 Markdown 编译成可运行 bundle
webpack: {
examples: {
entry: './examples/entry.js',
output: { path: __dirname + '/docs/dist/examples', filename: 'bundle.js' },
module: { rules: [{ test: /\.md$/, use: 'raw-loader' }] }
}
},
// 3. 拷贝静态资源
copy: {
assets: {
files: [
{ expand: true, cwd: 'assets/', src: ['**'], dest: 'docs/dist/' }
]
}
},
// 4. 本地服务器 + livereload
connect: {
server: {
options: { port: 8080, base: 'docs/dist', livereload: true, open: true }
}
},
// 5. 监听
watch: {
docs: {
files: ['src/**/*', 'examples/**/*'],
tasks: ['clean', 'jsdoc', 'webpack', 'copy'],
options: { livereload: true }
}
},
// 6. 部署到内网 GitLab Pages
'gh-pages': {
options: {
base: 'docs/dist',
branch: 'gh-pages',
repo: 'git@gitlab.xxx.com:fe/components.git',
message: 'docs: auto deploy via grunt'
},
src: ['**']
}
});
grunt.registerTask('docs', ['clean', 'jsdoc', 'webpack', 'copy']);
grunt.registerTask('serve', ['docs', 'connect', 'watch']);
grunt.registerTask('deploy', ['docs', 'gh-pages']);
};
- 脚本命令
"scripts": {
"docs:dev": "grunt serve",
"docs:build": "grunt docs",
"docs:deploy": "grunt deploy"
}
- 国内加速技巧
- 把 cn.docstrap 的静态资源(bootstrap、jquery)改走 unpkg.zhimg.com 镜像;
- 在
.npmrc里加sass_binary_site=https://npmmirror.com/mirrors/node-sass,避免 node-sass 编译卡死; - 若公司用 OSS,把
grunt-gh-pages换成 grunt-aliyun-oss,并配置region: 'oss-cn-shanghai',上传后自动刷新 CDN。
执行 npm run docs:dev,5 秒内即可在 http://localhost:8080 看到带搜索、主题、示例 iframe 的完整组件库文档;MR 合并后,GitLab CI 自动运行 npm run docs:deploy,产物秒级上线,实现“文档即版本”。
拓展思考
-
Storybook 能不能接 Grunt?
可以。用grunt-shell调用build-storybook -o docs/dist/storybook,再把产物同步到 OSS;优势是 UI 交互更强,劣势是包体积大,需用 terser-webpack-plugin 开并行压缩,否则 200+ 组件时 CI 会超时。 -
如何做到“示例即测试”?
把examples/*.spec.jsx用 grunt-mocha-test 跑一遍,再把通过率 badge 注入到生成的index.html,让文档直接显示“测试通过 98%”,国内老板最爱这一屏数字。 -
多人协作冲突?
在grunt-contrib-watch里加debounceDelay: 3000,并配合 husky + lint-staged 在 commit 前自动grunt docs,保证每个人推送的注释都是最新可编译状态,避免“文档红叉”回滚。 -
微前端场景下如何聚合多仓库文档?
主站用 Grunt 起connect做代理,把/button转发到http://localhost:3001,/table转发到3002,各子仓库独立grunt serve,本地一体化预览,部署阶段再用grunt-ssi拼成整站,解决国内“巨石文档”加载慢的问题。
掌握以上套路,面试时不仅能现场手写 Gruntfile,还能把“文档驱动开发”讲成工程化、自动化、可度量的完整故事,稳稳拿下 offer。