下篇是:文档、添加类型定义和打包。
文档
- storybook,但目前 storybook 对 Vue(+ts) 的支持还不够完美。
cd rect-ui
npx sb init
yarn add --dev vitepress
- vue-styleguidist 从 Vue 组件&注释中生成文档,也能利用 vue-docgen-cli 抽取的数据用在其他文档生成器中(比如 vuepress)。
新建项目
vue-docgen-cli
+ vitepress
示例:
# 新建 docs 文件夹,在文件夹里
yarn add -D vue-docgen-cli vitepress
docs
里新建 docgen.config.js
, 按 设置 填写。
const path = require("path");
module.exports = {
componentsRoot: "../packages/components", // 开始搜寻组件的文件夹
components: "**/index.vue", // 需要生成文档的文件的 glob
outDir: "docs/components", // 存放生成的文档的地方
getDestFile: (file, config) =>
path.join(config.outDir, file).replace(/\.vue$/, ".md"), // 确认生成的文档的名字
};
运行抽取:
yarn vue-docgen
生成的 md
文档就会放到 docs/docs/components
下了。
编写文档
- 按 Vue Styleguidist 的方式写注释
- 在组件文件夹下的
Readme.md
(或者getDocFileName
里规定的名字)
导入组件示例:
# Docs
This is a .md using a custom component
<CustomComponent />
## More docs
...
<script setup>
import CustomComponent from '../components/CustomComponent.vue'
</script>
将文件作为代码块渲染:
<<< ../filepath
别名
由于使用 vite
在 docs
文件夹下(.vitepress
同级)放vite.config.js
即可套用设定,如设置别名:
import { defineConfig } from "vite";
const path = require("path");
export default defineConfig({
resolve: {
alias: {
"@": path.resolve(__dirname, "../../packages/components"), // <script> 中用
},
},
});
然后在文档中就可以:
import Basic from "@/button/demo/basic.vue";
<<<
方法导入的别名不通用,在<<<
方法中,@
指根文件夹(.vitepress
放置的文件夹,这里是docs/docs
)。修改方法是修改 srcDir
,但目前无法设置在根目录外的文件夹。主题
导入 css 到 vitepress 方法:
创建主题:新建文件 ./vitepress/theme/index.js
import Theme from "vitepress/theme";
import "../../../../packages/color.css"; // ← 要导入的 css
export default { ...Theme };
类型定义
如果只是想让 ts 不报错的话,写个粗略的定义就可以了。
// packages/components/index.d.ts
import {Component} from "vue";
declare module "rect-ui";
export RButton:Component;
export function install(...args: any[]): void;
详细的定义:
declare module "rect-ui" {
import { DefineComponent } from "vue";
export const RButton: DefineComponent<
{
flat: { type: Boolean; default: false };
color: { type: String; default: string };
ghost: { type: Boolean; default: false };
disabled: { type: Boolean; default: false };
},
{} // 后面还有很多,不写了,大概是这样……
>;
}
既然都用 TS 了,我们可以利用现代化的工具 → vite-plugin-dts
安装:yarn add -D vite-plugin-dts
设置 vite.config.ts
:
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import dts from "vite-plugin-dts";
import { resolve } from "path";
export default defineConfig({
plugins: [dts(), vue()],
build: {
lib: {
entry: resolve(__dirname, "packages/index.ts"),
name: "rect-ui",
fileName: (format) => `rect-ui.${format}.js`,
},
rollupOptions: {
// make sure to externalize deps that shouldn't be bundled
// into your library
external: ["vue"],
output: {
// Provide global variables to use in the UMD build
// for externalized deps
globals: {
vue: "Vue",
},
},
},
},
});
按照我们目前的目录结构,设置一下tsconfig.json
以免检查到demo
和tests
文件:
// tsconfig.json
{
"compilerOptions": {
"esModuleInterop": true,
"target": "ES2015",
"moduleResolution": "node"
},
"include": ["packages/**/**/*"],
"exclude": ["packages/components/**/demo", "packages/components/**/tests"]
}
在 build
之后目标文件夹就会生成 .d.ts
文件了。
由于插件自带的打包没给路径设置,单独使用 API Extractor 把分散的.d.ts
打包成一个。因为不用它生成文档,所以关闭了相关功能。
api-extractor.json
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"mainEntryPointFilePath": "dist/index.d.ts",
"bundledPackages": [],
"compiler": { "skipLibCheck": false },
"apiReport": {
"enabled": false
},
"docModel": {
"enabled": false
},
"dtsRollup": {
"enabled": true,
"omitTrimmingComments": true,
"untrimmedFilePath": "./index.d.ts"
},
"tsdocMetadata": {
"enabled": false
},
"messages": {
"compilerMessageReporting": {
"default": {
"logLevel": "error"
}
},
"extractorMessageReporting": {
"default": {
"logLevel": "none"
}
},
"tsdocMessageReporting": {
"default": {
"logLevel": "none"
}
}
}
}

编译打包
然后运行vite build
打包,不设置outDir
的话默认在 dist
文件夹里。
给编译好的包准备 package.json
(其它内容 自己填),和原来的 package.json
合并。
sideEffects
。
{
"name": "rect-ui",
"version": "0.0.1",
"peerDependencies": {
"vue": "^3.0.4"
},
/* 中略 */
"files": ["dist/", "index.d.ts"],
"main": "./dist/rect-ui.umd.js",
"module": "./dist/rect-ui.es.js",
"exports": {
".": {
"import": "./dist/rect-ui.es.js",
"require": "./dist/rect-ui.umd.js"
},
"./dist/style.css": "./dist/style.css"
},
"sideEffects": ["*.css"]
}
用 npm pack
打包后的文件仅会留下 file
里的文件(还有 readme.md
等一定会留下的文件)。
使用
新建一个 vite
项目,本地安装编译出来的包。
npm init vite-app lib-test -- --template vue-ts
cd lib-test
yarn add <npm pack 打出的包>
基础测试
修改 main.ts
引入自己的库和 css。
// main.ts
import { createApp } from "vue";
import App from "./App.vue";
import RectUI from "rect-ui";
import "rect-ui/dist/style.css";
createApp(App).use(RectUI).mount("#app");
修改 App.vue
<template>
<r-button>显示按钮!</r-button>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "App",
});
</script>
查看能否被正确渲染。
按需引用测试
将代码引用改按需安装:
import { createApp } from "vue";
import App from "./App.vue";
import "rect-ui/dist/style.css";
import { Button } from "rect-ui";
createApp(App).use(Button).mount("#app");
全部引入打包:
vite v2.9.5 building for production...
✓ 12 modules transformed.
dist/index.html 0.39 KiB
dist/assets/index.76546b54.css 15.17 KiB / gzip: 3.05 KiB
dist/assets/index.4c0e342d.js 60.03 KiB / gzip: 23.34 KiB
部分引入打包:
vite v2.9.5 building for production...
✓ 12 modules transformed.
dist/index.html 0.39 KiB
dist/assets/index.76546b54.css 15.17 KiB / gzip: 3.05 KiB
dist/assets/index.1e459a5a.js 52.18 KiB / gzip: 21.04 KiB
在生成的 js 文件里没有搜索到其他组件的信息。
- 封面图片:Photo by Marita Kavelashvili on Unsplash