前言

记录学习 TS 后台项目的知识


项目构建

vite 构建

搭建项目

1
2
3
4
5
6
7
8
9
# 创建项目
pnpm create vite@latest
# 选择如下
√ Project name: ... vite-template
√ Select a framework: » Vue
√ Select a variant: » TypeScript
# 安装依赖
cd vite-template
pnpm i

EditorConfig

在项目根目录下增加.editorconfig文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 编辑器配置文件 参考 http://editorconfig.org

root = true # 表⽰是最顶层的配置⽂件,发现设为true时,才会停⽌查找.editorconfig⽂件

[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行尾的任意空白字符
# 先关闭防止与vscode的自动保存时冲突,在文件中最后一行写代码时未写完会自动保存跳到下一行
insert_final_newline = false # 始终在文件末尾插入一个新行

[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off # 最大行宽 填写number数值
trim_trailing_whitespace = false

安装 prettier

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 安装 prettier
pnpm add prettier -D
# 根目录新建配置文件
#.prettierrc.cjs
module.exports = {
// 一行的字符数,如果超过会进行换行,默认为80
printWidth: 80,
// 一个tab代表几个空格数,默认为80
tabWidth: 2,
// 是否使用tab进行缩进,默认为false,表示用空格进行缩减
useTabs: false,
// 字符串是否使用单引号,默认为false,使用双引号
singleQuote: true,
// 行位是否使用分号,默认为true
semi: false,
// 是否使用尾逗号,有三个可选值"<none|es5|all>"
trailingComma: 'none',
// 对象大括号直接是否有空格,默认为true,效果:{ foo: bar }
bracketSpacing: true,
// Delete `␍`eslintprettier/prettier(LF与CRLF报错)
endOfLine: 'auto'
}
# 根目录新建忽略文件
.prettierignore
# package.json 添加脚本
"format": "prettier --write \"./**/*.{html,vue,ts,js,json,md,scss,jsx,tsx,cjs,mjs}\""

安装 eslint

1
2
3
4
5
6
7
8
9
10
11
12
13
# 安装 eslint
pnpm add eslint -D
# 初始化 eslint
pnpm eslint --init 或者 npx eslint --init
# 选择如下图
# 新增依赖
devDependencies:
+ @typescript-eslint/eslint-plugin 6.7.0
+ @typescript-eslint/parser": "^6.7.0"

+ eslint-plugin-vue 9.17.0
# package.json 添加脚本
"lint:style": "stylelint \"./**/*.{css,scss,vue,html}\" --fix"


解决 Prettier 和 ESLint 的冲突

1
2
3
4
5
# eslint-plugin-prettier 将 Prettier 的规则设置到 ESLint 的规则中。
# eslint-config-prettier 关闭 ESLint 中与 Prettier 中会发生冲突的规则。
pnpm add eslint-plugin-prettier eslint-config-prettier -D

# eslintrc.cjs 里面的 extends 添加 'plugin:prettier/recommended'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
module.exports = {
env: {
browser: true,
es2021: true,
node: true
},
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:vue/vue3-essential',
'plugin:prettier/recommended'
],
overrides: [
{
env: {
node: true
},
files: ['.eslintrc.{js,cjs}'],
parserOptions: {
sourceType: 'script'
}
}
],
parserOptions: {
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
sourceType: 'module'
},
plugins: ['@typescript-eslint', 'vue'],
/**
* "off" 或 0 ==> 关闭规则
* "warn" 或 1 ==> 打开的规则作为警告(不影响代码执行)
* "error" 或 2 ==> 规则作为一个错误(代码不能执行,界面报错)
*/
rules: {
// vue (https://eslint.vuejs.org/rules)
'vue/multi-word-component-names': 'off', // 关闭组件命名规则

// typeScript (https://typescript-eslint.io/rules)

// eslint (http://eslint.cn/docs/rules)
'no-console': 'warn' // console 警告
}
}

安装 stylelint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 安装包
pnpm install stylelint stylelint-config-html stylelint-config-recommended-scss stylelint-config-recommended-vue stylelint-config-standard stylelint-config-standard-scss stylelint-config-recess-order postcss postcss-html -D
# 注:stylelint-config-prettier 仓库已经废弃了,stylelint V15自带了相关功能
# .stylelintrc.cjs 配置
// @see: https://stylelint.io

module.exports = {
root: true,
// 继承某些已有的规则
extends: [
"stylelint-config-standard", // 配置 stylelint 拓展插件
"stylelint-config-html/vue", // 配置 vue 中 template 样式格式化
"stylelint-config-standard-scss", // 配置 stylelint scss 插件
"stylelint-config-recommended-vue/scss", // 配置 vue 中 scss 样式格式化
"stylelint-config-recess-order" // 配置 stylelint css 属性书写顺序插件,
],
overrides: [
// 扫描 .vue/html 文件中的 <style> 标签内的样式
{
files: ["**/*.{vue,html}"],
customSyntax: "postcss-html"
}
],
rules: {
"function-url-quotes": "always", // URL 的引号 "always(必须加上引号)"|"never(没有引号)"
"color-hex-length": "long", // 指定 16 进制颜色的简写或扩写 "short(16进制简写)"|"long(16进制扩写)"
"rule-empty-line-before": "never", // 要求或禁止在规则之前的空行 "always(规则之前必须始终有一个空行)"|"never(规则前绝不能有空行)"|"always-multi-line(多行规则之前必须始终有一个空行)"|"never-multi-line(多行规则之前绝不能有空行)"
"font-family-no-missing-generic-family-keyword": null, // 禁止在字体族名称列表中缺少通用字体族关键字
"scss/at-import-partial-extension": null, // 解决不能使用 @import 引入 scss 文件
"property-no-unknown": null, // 禁止未知的属性
"no-empty-source": null, // 禁止空源码
"selector-class-pattern": null, // 强制选择器类名的格式
"value-no-vendor-prefix": null, // 关闭 vendor-prefix (为了解决多行省略 -webkit-box)
"no-descending-specificity": null, // 不允许较低特异性的选择器出现在覆盖较高特异性的选择器
"value-keyword-case": null, // 解决在 scss 中使用 v-bind 大写单词报错
"selector-pseudo-class-no-unknown": [
true,
{
ignorePseudoClasses: ["global", "v-deep", "deep"]
}
]
},
ignoreFiles: ["**/*.js", "**/*.jsx", "**/*.tsx", "**/*.ts"]
};
依赖 作用描述
stylelint stylelint 核心库
stylelint-config-html Stylelint 的可共享 HTML(和类似 HTML)配置,捆绑 postcss-html 并对其进行配置。
stylelint-config-recommended-scss 扩展 stylelint-config-recommended 共享配置,并为 SCSS 配置其规则
stylelint-config-recommended-vue 扩展 stylelint-config-recommended 共享配置,并为 Vue 配置其规则
stylelint-config-standard 打开额外的规则来执行在规范和一些 CSS 样式指南中发现的通用约定,包括:惯用 CSS 原则,谷歌的 CSS 样式指南,Airbnb 的样式指南,和 @mdo 的代码指南。
stylelint-config-standard-scss 扩展 stylelint-config-standard 共享配置,并为 SCSS 配置其规则
stylelint-config-recess-order 属性的排序(插件包)
postcss postcss-html 的依赖包
postcss-html 用于解析 HTML(和类似 HTML)的 PostCSS 语法

安装 commitizen cz-customizable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# 安装依赖
pnpm add commitizen cz-customizable -D
# package.json 脚本添加
"git": "git add . && git cz",
# package.json 脚本添加如下节点
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
},
"cz-customizable": {
"config": ".cz-config.cjs"
}
}
# 根目录新建 .cz-config.cjs
// 提交代码:使用 pnpm git 命令
// 相关配置:https://github.com/leoforfree/cz-customizable
// 图标地址:https://gitmoji.dev/
module.exports = {
types: [
{
value: '✨feat',
name: '✨ feat(新功能)'
},
{
value: ':bug: fix',
name: '🐛 fix(Bug 修复)'
},
{
value: '📝docs',
name: '📝 docs(文档更新)'
},
{
value: '💄style',
name: '💄 style(代码样式更改,例如空格、格式、缺少分号等)'
},
{
value: '💡refactor',
name: '💡 refactor(重构代码)'
},
{
value: '⚡️perf',
name: '⚡️ perf(性能优化)'
},
{
value: '✅test',
name: '✅ test(添加缺失或修正测试代码)'
},
{
value: '🔨chore',
name: '🔨 chore(构建相关的代码或工具库,如文档生成等)'
},
{
value: '⏪️revert',
name: '⏪️ revert(回退)'
},
{
value: '🎉ui',
name: '🎉 ui(更新UI)'
}
],
scopes: [
{ name: 'components' },
{ name: 'views' },
{ name: 'utils' },
{ name: 'styles' },
{ name: 'store' },
{ name: 'router' },
{ name: 'hooks' },
{ name: 'layout' },
{ name: 'mock' },
{ name: 'assets' },
{ name: 'other' }
],
messages: {
type: '请选择提交类型:(必填)',
scope: '选择一个 scope:(可选)',
customScope: '请输入影响范围:(可选)',
subject: '请输入简要描述:(必填)',
body: '请输入详细描述,使用 "|" 分行:(可选)',
breaking: '请列出所有的破坏性变更,例如:描述、理由或迁移方式等:(可选)',
footer: '请列出需关闭的 issue,例如:#31, #34:(可选)',
confirmCommit: '请确认此提交信息?'
},
subjectLimit: 100, // subject文字长度默认
allowCustomScopes: true,
allowBreakingChanges: [':sparkles: feat', ':bug: fix']
}

安装 husky

1
2
3
4
5
6
7
8
9
# 安装
pnpm add husky -D
# package.json 脚本添加
"prepare": "husky install"
# 运行命令创建 .husky 文件夹
pnpm install

# 注意:在项目 pnpm i 时候必须要有 git 仓库
# git 仓库被删除了,要重新 pnpm i 后 husky 才会生效

安装 lint-staged

1
2
3
4
5
6
7
8
9
10
11
12
13
# 安装
pnpm add lint-staged -D
# package.json 脚本添加
"lint-staged": "lint-staged"
# 根目录新建 .lintstagedrc.json
{
"*.{ts,tsx,js,jsx,cjs,mjs}": ["prettier --write", "eslint --fix"],
"*.vue": ["eslint --fix", "prettier --write", "stylelint --fix"],
"*.{scss,less,styl,html}": ["stylelint --fix", "prettier --write"],
"*.{md,json}": ["prettier --write"]
}
# 添加到 husky 钩子中
pnpm husky add .husky/pre-commit "pnpm lint-staged"

安装 commitlint

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 安装
pnpm add @commitlint/cli commitlint-config-cz -D
# 根目录新建 commitlint.config.cjs
// 直接使用 commitlint-config-cz 配置
// 注意但是在 .cz-config.js 中 types里面的 value 图标和文字必须不能加空格
module.exports = {
extends: ['cz'],
parserPreset: {
parserOpts: {
headerPattern: /^(.*?)(?:\((.*)\))?:?\s(.*)$/,
headerCorrespondence: ['type', 'scope', 'subject']
}
},
rules: {
'type-empty': [2, 'never'],
'subject-empty': [2, 'never']
}
}
# 添加到 husky 钩子中
npx husky add .husky/commit-msg "npx --no-install commitlint --edit $1"

注:commit 开头添加表情,其他方案

1
2
3
4
5
6
# 安装
pnpm add commitlint-config-git-commit-emoji -D
// 使用 commitlint-config-git-commit-emoji 支持图标 types 里面的 value 图标和文字必须加空格隔开
module.exports = {
extends: ['git-commit-emoji', 'cz']
}

create-vue 构建

1
2
# 安装
pnpm create vue@latest

项目安装时,选择对应需要的工具,可以自动集成相关依赖(如:eslint、prettier)

只需参考上面的后面安装即可。


项目集成

node 声明文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// node 声明文件
pnpm add @types/node -D
// 配置别名 vite.config.ts
import { fileURLToPath, URL } from 'node:url'
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
}
// tsconfig.json 配置
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}

jsx、tsx

1
2
3
4
pnpm add @vitejs/plugin-vue-jsx -D
// vite.config.ts
import vueJsx from '@vitejs/plugin-vue-jsx'
plugins: [vueJsx()]

pinia、router

1
pnmp add pinia vue-router

其他集成

以下插件为非必要安装的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# mitt 事件总线
pnpm add mitt

# pinia 持久化插件
pnpm add pinia-plugin-persistedstate

# svg 图标
pnpm add vite-plugin-svg-icons -D
# svgo 优化 svg 文件大小
pnpm add svgo -D
"svgo": "svgo -f src/assets/icons" # package.json 脚本
"src/assets/icons/*.svg": ["svgo"] # .lintstagedrc.json 添加

# 自动引入 unplugin-auto-import

# 自动注册 unplugin-vue-components

# gzip 插件 vite-plugin-compression

# mock 插件 vite-plugin-mock

element-plus 引入在 TypeScript5.0 下的报错

参考:掘金 issues

使用 element-plus 组件属性提示

1
2
3
4
5
6
7
{
"compilerOptions": {
// 如果使用 Bundler 无法找到对应的 element-plus/global,组件上要没有提示,需要使用 Node
"moduleResolution": "node",
"types": ["vite/client", "element-plus/global"],
}
}