这篇文章会带着你从零搭建一个基于 vue3 的组件库。
github 地址
gitee 地址
话不多说,开搞
npm i pnpm -g
# pnpm-workspace.yaml
packages:
- 'packages/*'
# -w 表示在要把包下载到根目录
pnpm add typescript -D -w
npx tsc --init
{
"compilerOptions": {
"baseUrl": ".",
"target": "es2016",
"sourceMap": false,
"module": "esnext",
"esModuleInterop": true,
"strict": true,
"jsx": "preserve",
"types": ["node"],
"rootDir": "."
}
}
pnpm add prettier -D -w
module.exports = {
semi: false,
singleQuote: true,
printWidth: 80,
trailingComma: 'none',
arrowParens: 'avoid'
}
pnpm add eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin -D -w
当 ESLint 的规则和 Prettier 的规则相冲突时,就会发现一个尴尬的问题,用其中一种来格式化代码,另一种就会报错。prettier 官方提供了一款工具 eslint-config-prettier 来解决这个问题,本质上这个工具其实就是禁用掉了一些不必要的以及和 Prettier 相冲突的 ESLint 规则。
pnpm add eslint-config-prettier eslint-plugin-prettier -D -w
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
'plugin:prettier/recommended'
],
env: {
browser: true,
es2021: true
},
extends: ['eslint:recommended'],
plugins: ['@typescript-eslint', 'prettier'],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module'
},
rules: {
'prettier/prettier': 'error',
'no-extra-semi': 'off',
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-extra-semi': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-empty-interface': 'off'
}
}
"scripts": {
"prettier": "prettier --write .",
"lint": "eslint --ext .ts packages/*/**.ts",
"lint:fix": "eslint --ext .ts packages/*/**.ts --fix"
},
这时我们可以在 packages 下创建 components/index.ts,写一些不符合规则的代码然后运行命令试试效果
husky 哈士奇,代码提交前可以执行自定义 git hooks
在代码提交之前,进行代码规则检查能够确保进入 git 库的代码都是符合代码规则的。但是整个项目上运行 lint 速度会很慢,lint-staged 能够让 lint 只检测暂存区的文件,所以速度很快。
pnpm add husky lint-staged -D -w
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
{
"lint-staged": {
"*.{js,jsx,vue,ts,tsx}": [
"eslint --ext .ts packages/*/**.ts", // 这里也可以写我们上面定义好的命令,如:pnpm lint
"eslint --ext .ts packages/*/**.ts --fix" // 这里也可以写我们上面定义好的命令,如:pnpm lint:dix
]
}
}
现在我们可以试着提交一下代码,如果不符合 eslint 校验规则的会自动修复,修复完成后需要再次提交
commitlint 统一提交时的 message,官方文档
pnpm add @commitlint/config-conventional @commitlint/cli -D -w
module.exports = {
extends: ['@commitlint/config-conventional']
}
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install commitlint --edit $1
现在我们试着提交一下代码
git add .
git commit -m "test"
由于 “test” 不符合提交格式,所以不会通过
我们再试着使用正确的规则提交,不出意外能成功。。。
git commit -m "style: commitlint"
到此我们项目搭建和代码规范以完毕,目录结构如下
|-- vangle
|-- .eslintrc.js
|-- .gitignore
|-- .prettierrc.js
|-- commitlint.config.js
|-- package.json
|-- pnpm-lock.yaml
|-- pnpm-workspace.yaml
|-- README.md
|-- tsconfig.json
|-- .husky
| |-- commit-msg
| |-- pre-commit
| |-- _
| |-- .gitignore
| |-- husky.sh
|-- packages
|-- components
|-- index.ts
// packages/components/package.json
{
"name": "@vangle/components",
"version": "1.0.0",
"description": "all components are settled here",
"main": "index.ts",
"module": "index.ts",
"unpkg": "index.js",
"jsdelivr": "index.js",
"scripts": {},
"keywords": [],
"author": "",
"license": "ISC",
"peerDependencies": {
"vue": "^3.2.0"
},
"types": "index.d.ts"
}
pnpm add vue vite unplugin-vue-define-options -D -w
defineOptions({
name: 'PlayButton'
})
{
"compilerOptions": {
"baseUrl": ".",
"target": "es2016",
"sourceMap": false,
"module": "esnext",
"esModuleInterop": true,
"strict": true,
"jsx": "preserve",
"lib": ["esnext", "dom"],
"types": ["node", "unplugin-vue-define-options"],
"rootDir": ".",
"moduleResolution": "node",
"paths": {
"@valgle/*": ["packages/*"]
}
}
}
pnpm add eslint-plugin-vue -D -w
module.exports = {
extends: [
'eslint:recommended',
'plugin:vue/recommended', // add
'plugin:@typescript-eslint/recommended',
'prettier',
'plugin:prettier/recommended'
],
plugins: ['@typescript-eslint', 'prettier', 'vue'] // add
}
注意:我们这里只编写一个简单的 button 组件,主要是打通整体流程
|-- button
|-- index.ts
|-- src
| |-- button.ts
| |-- button.vue
| |-- button.less
|-- __test__
components/button/src/button.vue
components/button/index.ts
export * from './src/button'
import type { App } from 'vue'
import Button from './src/button.vue'
Button.install = (app: App) => {
app.component(Button.name, Button)
}
export { Button }
export default Button
components/index.ts 导出
export * from './button'
{
"devDependencies": {
"@vangle/components": "workspace:*"
}
}
这里的包名 @vangle/components,就是我们在 pzckages/components/package.json 中设置的 name 属性
我们可以在根目录创建使用 vite 创建一个项目,请参考 vite 官网,项目名称就叫 play
创建完后修改 pnpm-workspace.yaml
packages:
- 'packages/*'
- 'play' # add
{
"scripts": {
"play": "pnpm dev --filter ./play", // add
"prettier": "prettier --write .",
"lint": "eslint --ext .ts packages/*/**.ts",
"lint:fix": "eslint --ext .ts packages/*/**.ts --fix"
}
}
注意事项:
由于我们处于开发环境,需要给 vite.config.ts 添加 unplugin-vue-define-options/vite 插件
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import DefineOptions from 'unplugin-vue-define-options/vite'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue(), DefineOptions()]
})
================================= 分割线 =================================
到这里就是本篇文章的全部内容了,如果对大家有用,希望多多支持一下,你们的支持就是我的动力呀 (●’◡’●)
下期准备写一个完整的组件,并详细介绍如何为组件编写文档。组件文档使用 vitepress