出于学习的目的探究一下 Vue3 组件库的编写,刚好整个新 web app 用得上。写组件本身问题不大,难受的是写文档 |・ω・`) 目前主要探索一下文件组织。
太长了分成上下篇吧,上篇是组织和编写。
一边写一边改的,可能有地方先写了后改的对不上。
建立项目
使用 vue3 + vite + typescript
新建项目
npm init vite-app rect-ui -- --template vue-ts
- template 里的组件版本可能不是最新的,检查更新下
package.json
。 - 为了支持摇树优化,更新
tsconfig.json
的target
到es6
及以上。
文件组织
参考一下一些大组件库的组织方法:
总结了个我自己能理解的样子 🤨:
.
├── docs/
│ └── docs
└── packages/
├── 其他
├── components/
│ └── button/
│ ├── tests/
│ │ └── button.test.ts
│ ├── demo/
│ │ └── demo.vue
│ ├── index.vue
│ ├── index.ts
│ └── Readme.md
└── index.ts
事实上没人用 index.vue
这种写法,都直接上组件名。这是为了后期文档生成能偷懒(擦汗)。
按需安装
在使用别的 UI 库的时候经常见到按需安装
的条目,可以只安装需要的组件。
需要给每个可以自主安装的组件一个install
函数用来调用。
就当研究一下组件库都有的东西是什么样的好了 😂,下次不写了(还有下次吗)。

// packages/components/button/index.ts
import type { App } from "vue";
import RButton from "./index.vue";
const Button = {
install(Vue: App) {
Vue.component(RButton.name, RButton);
},
};
export default Button;
export { RButton };
// packages/components/index.ts
export * from "./button";
export { default as Button } from "./button";
安装所有组件的主函数
// packages/index.ts
import * as components from "./components";
import "./css/color.css";
import "./css/common.styl";
const ComponentLibrary = {
install(Vue, options = {}) {
// components
for (const componentName in components) {
const component = components[componentName];
component.install = function (Vue) {
Vue.component(component.name, component);
};
Vue.component(component.name, component);
}
},
};
export default ComponentLibrary;
export * from "./components";
测试按需安装成功,但 tree shaking 一直下不来,最后搜索到了 这里,原来在 TS 里要自己加 /*#__PURE__*/
…… 😢
修改组件定义为 export default /*#__PURE__*/ defineComponent
,打包后用 agadoo 检查,通过了。
不过这样打断后用vue-docgen-cli
生成文档就无法识别自定义名字了,所以后来就先打包,再批量改。
测试
Jest
- 安装依赖
yarn add -D @babel/preset-env @babel/preset-typescript @testing-library/jest-dom @types/jest @vue/babel-plugin-jsx @vue/test-utils@next @vue/vue3-jest ts-jest jest-environment-jsdom jest
包名 | 说明 |
---|---|
@babel/preset-env | 智能设定,使用最新的 JavaScript。 |
@babel/preset-typescript | babel 的 typescript 支持 |
@testing-library/jest-dom | 用来添加一些方便 DOM 测试的函数。 |
@types/jest | 给 jest 提供类型定义。 |
@vue/babel-plugin-jsx | 添加 Vue JSX 转译支持。 |
@vue/test-utils@next | vue3 的测试套组。 |
@vue/vue3-jest | 用于 Vue 单文件组件 (SFC) 的 Jest transformer。 |
ts-jest | 提供 ts 测试支持 |
jest-environment-jsdom | 提供 jsdom 测试环境。 |
jest | 测试工具。 |
- 新建
jest.config.js
并设置
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "jsdom",
transform: {
"^.+\\.vue$": "@vue/vue3-jest", // Update to match your installed version
"^.+\\js$": "babel-jest",
},
testMatch: ["**/tests/*.test.[jt]s?(x)"],
moduleFileExtensions: ["js", "jsx", "ts", "tsx", "vue"],
testEnvironmentOptions: {
customExportConditions: ["node", "node-addons"],
},
globals: {
"ts-jest": { babelConfig: true },
},
};
- 新建
babel.config.js
并设置:
module.exports = {
presets: [
["@babel/preset-env", { targets: { node: "current" } }],
"@babel/preset-typescript",
],
plugins: ["@vue/babel-plugin-jsx"],
};
- 运行测试
npx jest
Vitest
整理完了 Jest 后一搜发现了新的(两眼一黑)。但 Jest 怎么说也是起了个新环境,需要共用设置时能 vite 一把梭还是很好的。vitest 官网,测试用例 API 和 Jest 兼容。
- 安装依赖
yarn add -D vitest jsdom
套件没有内置模拟环境,需要自选 jsdom
或者 happy-dom
安装。
- 和 vite 共用配置,可以直接将配置写在
vite.confing.js
里,其余情况参见 配置。
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
include: ["**/tests/*.test.[jt]s?(x)"],
environment: "jsdom",
},
});
- 封面图片:Photo by Alfons Morales on Unsplash