简述
拿到项目后,发现项目的东西,都是别人提前配置好的,自己只需要进行相应业务的CRUD就可以了,但是一直都有一个疑惑,项目中的初始化配置是怎么完成的,因为每次看到项目中的一些配置文件,就不是很清楚这些文件都是用来干什么的,烦躁的很哦o(╥﹏╥)o
涉及到的内容有:
1、用 Vite 搭建项目
2、Vite 中使用typescript
3、Vite 中使用vue-router4和pinia
4、项目中集成eslint和prettier保证代码质量
5、规范化git提交信息
6、vite的开发环境和生产环境的配置
7、vite的环境变量的配置
8、为团队开发专属的项目模板
项目中安装的包和对应的版本号
"dependencies": {
"@vueuse/core": "^9.10.0",
"axios": "^0.27.2",
"element-plus": "^2.2.28",
"pinia": "^2.0.14",
"vue": "^3.2.45",
"vue-router": "^4.1.6"
},
"devDependencies": {
"@commitlint/cli": "^17.0.3",
"@commitlint/config-conventional": "^17.0.3",
"@types/node": "^18.11.18",
"@typescript-eslint/eslint-plugin": "^5.32.0",
"@typescript-eslint/parser": "^5.48.1",
"@vitejs/plugin-vue": "^4.0.0",
"commitizen": "^4.2.5",
"commitlint-config-cz": "^0.13.3",
"consola": "^2.15.3",
"cz-conventional-changelog": "^3.3.0",
"cz-customizable": "^7.0.0",
"eslint": "^8.32.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.9.0",
"husky": "^8.0.3",
"lint-staged": "^13.1.0",
"prettier": "^2.8.3",
"sass": "^1.57.1",
"typescript": "^4.9.3",
"unplugin-auto-import": "^0.10.3",
"unplugin-vue-components": "^0.21.2",
"vite": "^4.0.0",
"vite-plugin-style-import": "^2.0.0",
"vue-tsc": "^1.0.11"
}
1. 初始化项目
开始项目初始化:
1-1. 使用 vite-cli 命令 用npm命令创建
npm init vite@latest
说明:是基于vite创建的vue3项目,默认是不安装router 和 vuex 和 pinia 的
说明:使用的rollup来进行项目打包的
1-2. 创建项目的一些配置选项:
√ Package name: ... -vite-vue3-ts-pinia-vueuse-template //项目名字
√ Select a framework: » Vue // 选择一个框架(选Vue)
√ Select a variant: » TypeScript // 使用 typescript
1-3. 启动项目
cd ?vite_vue3_ts_pinia_vueuse_template
npm install
npm run dev
1-4. 修改一下项目创建后的配置
- 安装 @types/node
为了使用 node 相关的api,vscode编辑器,不飘红色的波浪线
npm install @types/node --save-dev
- 修改
tsconfig.json
{
"compilerOptions": {
"typeRoots": [
"node_modules/@types",
"src/types"
],
// 上面 typeRoots 是新增的
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"moduleResolution": "Node",
"strict": true,
"jsx": "preserve",
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": ["ESNext", "DOM"],
"skipLibCheck": true,
"noEmit": true
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}
使用前:
使用后:
- 修改
vite.config.ts
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import * as path from 'path';
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
//设置别名
alias: {
'@': path.resolve(__dirname, 'src')
}
},
plugins: [vue()],
server: {
port: 8080, //启动端口
hmr: {
host: '127.0.0.1',
port: 8080
},
// 设置 https 代理
proxy: {
'/api': {
target: '你的 https 地址',
changeOrigin: true,
rewrite: (path: string) => path.replace(/^\/api/, '')
}
}
}
});
2. 代码质量风格的统一
ESLint+Prettier格式化方式的思路是:ESLint规则中与Prettier重合的部分,会用Prettier的规则覆盖ESLint规则
安装eslint
- 安装 eslint和eslint-plugin-vue
npm install eslint eslint-plugin-vue --save-dev
由于 ESLint 默认使用 Espree 进行语法解析,无法识别 TypeScript 的一些语法,因此需要安装 @typescript-eslint/parser 替代掉默认的解析器
npm install @typescript-eslint/parser --save-dev
- 安装 @typescript-eslint/eslint-plugin
安装对应的插件 @typescript-eslint/eslint-plugin, 它作为 eslint 默认规则的补充,提供了一些额外的适用于 ts 语法的规则。
npm install @typescript-eslint/eslint-plugin --save-dev
- 创建配置文件:
.eslintrc.js或.eslintrc.json或.eslintrc.cjs
在项目根目录下,创建 .eslintrc.js 文件,它是对eslint进行配置的
module.exports = {
parser: 'vue-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaVersion: 2020,
sourceType: 'module',
ecmaFeatures: {
jsx: true
}
},
// 扩展配置
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
],
rules: {
// 自定义规则,也可以对许多eslint的内置规则,进行禁用
}
};
- 创建eslint的忽略文件:
.eslintignore
在项目根目录下,创建 .eslintignore 文件,eslint对于对于哪些文件不做处理
# eslint 忽略检查 (根据项目需要自行添加)
node_modules/
dist/
index.html
- 修改
package.json里面的运行命令
{
...
"scripts": {
...
"eslint-desc": "下面命令的解释:使用 ESLint 检查并自动修复 src 目录下所有扩展名为 .js 和 .vue 的文件",
"eslint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
}
...
}
安装prettier
prettier是用来自动格式化当前目录下的所有文件
- 安装
npm install prettier eslint-config-prettier eslint-plugin-prettier --save-dev
- 创建配置文件:
prettier.config.js或.prettierrc.js或.prettierrc.cjs
module.exports = {
// 一行最多 80 字符
printWidth: 80,
// 使用 2 个空格缩进
tabWidth: 2,
// 不使用 tab 缩进,而使用空格
useTabs: true,
// 行尾需要有分号
semi: false,
// 使用单引号代替双引号
singleQuote: true,
// 对象的 key 仅在必要时用引号
// 要求对象字面量属性是否使用引号包裹,(‘as-needed’: 没有特殊要求,禁止使用,'consistent': 保持一致 , preserve: 不限制,想用就用)
quoteProps: 'as-needed',
// jsx 不使用单引号,而使用双引号
jsxSingleQuote: false,
// 末尾使用逗号
trailingComma: 'all',
// 确保对象的最后一个属性后有逗号
// trailingComma: 'es5',
// 大括号内的首尾需要空格 { foo: bar }
bracketSpacing: true,
// jsx 标签的反尖括号需要换行
jsxBracketSameLine: false,
// 箭头函数,只有一个参数的时候,也需要括号
arrowParens: 'always',
// 每个文件格式化的范围是文件的全部内容
rangeStart: 0,
rangeEnd: Infinity,
// 不需要写文件开头的 @prettier 【是否严格按照文件顶部的特殊注释格式化代码】
requirePragma: false,
// 不需要自动在文件开头插入 @prettier 【是否在格式化的文件顶部插入Pragma标记,以表明该文件被prettier格式化过了】
insertPragma: false,
// 使用默认的折行标准
proseWrap: 'preserve',
// 根据显示样式决定 html 要不要折行
htmlWhitespaceSensitivity: 'css',
// html文件的空格敏感度,控制空格是否影响布局
// "htmlWhitespaceSensitivity": "ignore",
// 换行符使用 【结尾是 \n \r \n\r auto】
endOfLine: 'auto',
}
- 修改
.eslintrc.js配置
修改前:
module.exports = {
...
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
],
...
};
修改后:
module.exports = {
...
extends: [
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
// 如果同时使用了eslint和prettier发生冲突了,会关闭掉与prettier有冲突的规则,也就是使用prettier认为对的规则
'plugin:prettier/recommended'
],
// plugins 配置那些我们想要Linting规则的插件
plugins: ['prettier'], // eslint 会使用pretter的规则对代码格式化
// 自定义规则,也可以对许多eslint的内置规则,进行禁用
rules: {
'prettier/prettier': 'error',
// semi: 0, // 行末分号,根据编码习惯选择添加,这里配置的是不加分号
},
...
};
- 创建prettier的忽略文件:
.prettierignore
在项目根目录下,创建 .prettierignore 文件,prettier对于对于哪些文件不做处理
# prettier 忽略检查 (根据项目需要自行添加)
node_modules/
dist/
- 修改
package.json里面的运行命令
修改前:
{
...
"scripts": {
...
"eslint-desc": "下面命令的解释:使用 ESLint 检查并自动修复 src 目录下所有扩展名为 .js 和 .vue 的文件",
"eslint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
}
...
}
修改后:
{
...
"scripts": {
...
"eslint-desc": "下面命令的解释:使用 ESLint 检查并自动修复 src 目录下所有扩展名为 .js 和 .vue 的文件",
"eslint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
"prettier-desc": "自动格式化当前目录下的所有文件",
"prettier": "prettier --write ."
}
...
}
解决 eslint 和 prettier 冲突
解决 ESLint 中的样式规范和 prettier 中样式规范的冲突,以 prettier 的样式规范为准,使 ESLint 中的样式规范自动失效
- 安装插件 eslint-config-prettier 【前面已经安装过了】
npm install eslint-config-prettier --save-dev
配置完成后,可以运行以下命令测试下代码检查 和 代码格式化效果
eslint 检查
npm run eslint
prettier 自动格式化
npm run prettier
npm run lint 报错
Oops! Something went wrong! :(
ESLint: 8.32.0
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: C:\Users\qwd\Desktop\vue3项目初始化模板\vite_vue3_ts_pinia_vueuse_template\.eslintrc.js
require() of ES modules is not supported.
require() of C:\Users\qwd\Desktop\vue3项目初始化模板\vite_vue3_ts_pinia_vueuse_template\.eslintrc.js from C:\Users\qwd\Desktop\vue3项目初始化模板\vite_vue3_ts_pinia_vueuse_template\node_modules\@eslint\eslintrc\dist\eslintrc.cjs is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename .eslintrc.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from C:\Users\qwd\Desktop\vue3项目初始化模板\vite_vue3_ts_pinia_vueuse_template\package.json.
at new NodeError (internal/errors.js:322:7)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1102:13)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:12)
at Module.require (internal/modules/cjs/loader.js:974:19)
at Object.module.exports [as default] (C:\Users\qwd\Desktop\vue3项目初始化模板\vite_vue3_ts_pinia_vueuse_template\node_modules\import-fresh\index.js:32:59)
at loadJSConfigFile (C:\Users\qwd\Desktop\vue3项目初始化模板\vite_vue3_ts_pinia_vueuse_template\node_modules\@eslint\eslintrc\dist\eslintrc.cjs:2562:47)
at loadConfigFile (C:\Users\qwd\Desktop\vue3项目初始化模板\vite_vue3_ts_pinia_vueuse_template\node_modules\@eslint\eslintrc\dist\eslintrc.cjs:2646:20)
at ConfigArrayFactory.loadInDirectory (C:\Users\qwd\Desktop\vue3项目初始化模板\vite_vue3_ts_pinia_vueuse_template\node_modules\@eslint\eslintrc\dist\eslintrc.cjs:2856:34)
at CascadingConfigArrayFactory._loadConfigInAncestors (C:\Users\qwd\Desktop\vue3项目初始化模板\vite_vue3_ts_pinia_vueuse_template\node_modules\@eslint\eslintrc\dist\eslintrc.cjs:3848:46)
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! vite-vue3-ts-pinia-vueuse-template@0.0.0 eslint: `eslint --ext .js,.vue --ignore-path .gitignore --fix src`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the vite-vue3-ts-pinia-vueuse-template@0.0.0 eslint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\qwd\AppData\Roaming\npm-cache\_logs\2023-01-16T07_29_40_879Z-debug.log
解决方案
.eslintrc.js 重命名为 .eslintrc.cjs
VSCode需要安装插件 ESLint、Prettier、Prettier ESLint+VSCode中setting.json的配置
1、三个插件是用来编辑器保存代码的时候,自动按照配置好的要求,格式化代码
2、VSCode中setting.json文件中需要添加的配置
// 缩进格式为2个空格
"editor.tabSize": 2,
// vscode 默认启用了"editor.detectIndentation": true”根据文件类型自动设置tabsize的选项
"editor.detectIndentation": false,
//回车自动格式化
"editor.formatOnType": true,
// 保存文档时自动格式化
"editor.formatOnSave": true,
// 保存时按照哪个规则进行格式化
// "eslint.autoFixOnSave": true, 这个设置被废弃了,使用下面的editor.codeActionsOnSave的配置
"editor.codeActionsOnSave": {
// "source.fixAll": true,
"source.fixAll.eslint": true
// "source.fixAll.prettier": true
},
"eslint.format.enable": true,
// "[javascript]": {
// // "editor.defaultFormatter": "dbaeumer.vscode-eslint"
// // "editor.defaultFormatter": "esbenp.prettier-vscode"
// "editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
// // 这里也可以使用 "editor.defaultFormatter": "esbenp.prettier-vscode",但是要保证安装了prettier插件
// // 这样使用快捷键格式化 command + k \ command + f,可以进行选择部分代码进行格式化
// },
"eslint.enable": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"vue",
"typescript",
"typescriptreact"
],
// 用prettier去格式化代码
"editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
3、VSCode自身的Tab Size也要调整,这里使用的缩进2个空格来格式化代码的
4、重启VSCode,保存代码后会自动用prettier+eslint进行格式化
ESlint不要分号,Prettier却强制分号结尾的问题,解决如下(这里统一不要分号)
在package.json中加入如下代码配置(如果没有效果,重启一下编辑器和选择项目)
"prettier": {
"semi": false
}
参考的相关文章链接1:zhuanlan.zhihu.com/p/272797097
参考的相关文章链接2:blog.csdn.net/xs20691718/…
参考的相关文章链接3:blog.csdn.net/lgdaren/art…
参考的相关文章链接4:zhuanlan.zhihu.com/p/575146137
3. 安装Pinia
Pinia是 Vue 官方团队推荐代替Vuex的一款轻量级状态管理库
安装
npm install pinia --save
简单使用
- 新建 src/store 目录并在其下面创建 index.ts,导出 store
import { createPinia } from 'pinia'
const store = createPinia()
export default store
- 在 main.ts 中引入并使用
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
// 创建vue实例
const app = createApp(App)
// 挂载pinia
app.use(store)
// 挂载实例
app.mount('#app');
- 定义State: 在 src/store 下面创建一个 user.ts
import { defineStore } from 'pinia'
export const useUserStore = defineStore({
id: 'user', // id必填,且需要唯一
state: () => {
return {
name: '张三'
}
},
actions: {
// 注意:不能使用箭头函数定义action,因为this的问题
updateName(name:string) {
this.name = name
}
}
})
- 获取State: 在 src/components/usePinia.vue 中使用
<template>
<div>{{ userStore.name }}</div>
</template>
<script lang="ts" setup>
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
</script>
如果文件中提示:
找不到模块“@/store/user.js”或其相应的类型声明。ts(2307)
说明ts不识别@别名,可以修改 tsconfig.json 文件,添加 baseUrl 和 paths 2个属性:
"compilerOptions": {
...
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
}
},
paths 里面可以继续添加其他你想使用的别名路径
如果你使用了vite,还需要看看你的vite.config.ts里面有没有配置alias别名路径
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
}
},
})
- 修改State:
// 1. 直接修改 state (不建议)
userStore.name = '李四'
// 2. 通过 actions 去修改
<script lang="ts" setup>
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
userStore.updateName('李四')
</script>
详细使用指南:点击查看pinia官网
修改Pinina中State值的方式
<template>
<div>{{ userStore.name }}</div>
</template>
<script lang="ts" setup>
import { useUserStore } from '@/store/user'
const userStore = useUserStore()
// 方式一:直接修改 state (不推荐)
userStore.name = '李四'
// 方式二:如果需要修改多个数据,建议使用 $patch 批量更新
userStore.$patch({
name = '李四'
arr= [...origin, 1]
})
// 方式三:更好的批量更新的方式
userStore.$patch((state) =>{
state.name = '李四'
state.arr.push(1)
})
// 方式四:通过 actions 修改 state
userStore.updateName('李四')
</script>
4. 安装vue-router4
安装
npm install vue-router --save
使用
- 新建 src/router 目录并在其下面创建 index.ts,导出 router
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Index',
meta: {
title: '首页',
keepAlive: true,
requireAuth: true
},
component: () => import('@/view/index.vue')
}
]
const router = createRouter({
history: createWebHistory(),
routes
});
export default router;
- 在 main.ts 中引入并使用
import { createApp } from 'vue'
import './style.css';
import App from './App.vue'
import store from './store'
import router from '@/router';
// 创建vue实例
const app = createApp(App)
// 挂载router
app.use(router);
// 挂载pinia
app.use(store)
// 挂载实例
app.mount('#app');
- 修改 App.vue
<template>
<router-view></router-view>
</template>
5. 安装Vueuse
VueUse是一个基于Composition API的实用函数集合
安装
npm install @vueuse/core --save
使用
- 创建一个新的 src/view/vueUse.vue 页面来做一个简单的 demo
<template>
<h1> 测试 vueUse 的鼠标坐标 </h1>
<h3>Mouse: {{x}} x {{y}}</h3>
</template>
<script setup lang='ts'>
import { useMouse } from '@vueuse/core'
const { x, y } = useMouse()
</script>
<style scoped>
</style>
useMouse 只是 vueuse 中的一个最基本的钩子函数,更多的钩子函数:点击查看官网文档
6. 安装scss 或 less
- 安装
# .scss and .sass
npm install sass --save-dev
# .less
npm install less --save-dev
- 使用在 .vue 文件使用
// .scss
<template>
<div class="wrap_page">
<h3>欢迎使用 scss</h3>
</div>
</template>
<style lang="scss" scoped>
.wrap_page {
h3{
color:red;
}
}
</style>
// .less
<template>
<div class="wrap_page">
<h3>欢迎使用 less</h3>
</div>
</template>
<style lang="less" scoped>
.wrap_page {
h3{
color:red;
}
}
</style>
- 这是安装的是sass
npm install sass --save-dev
7. 安装axios
axios是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中
安装
npm install axios --save
使用:
- 新建 src/utils/axios.ts
import axios, { AxiosResponse, AxiosRequestConfig } from 'axios';
const service = axios.create();
// axios的请求拦截器
service.interceptors.request.use(
(config: AxiosRequestConfig) => {
// 请求前需要处理的事情
return config;
},
(error: any) => {
// 需要处理的事情
Promise.reject(error);
}
);
// axios的响应拦截器
service.interceptors.response.use(
async (response: AxiosResponse) => {
// 把数据返回给前端前需要处理的事情
},
(error: any) => {
// 需要处理的事情
return Promise.reject(error);
}
);
export default service;
- 在页面中就可以使用了
<script lang="ts">
import request from '@/utils/axios';
const requestRes = async () => {
let result = await request({
url: '/api/xxx',
method: 'get'
});
}
</script>
但是正常开发中,都需要再进行一次简单的封装,让其使用起来更加简单
- 新建
src/api/module/login.ts
import request from '@/utils/axios'; // axios的初始化(请求+响应拦截器)
// 登录接口的返回值类型
interface IResponseType {
code: number;
status: number;
msg?: string;
data: ILogin;
}
interface ILogin {
token: string;
expires: number;
}
// 登录
export const login = (username: string, password: string) => {
return request<IResponseType>({
url: '/api/auth/login',
method: 'post',
data: {
username,
password
}
});
};
写完后发现有飘红波浪线
也就是类型找不到的意思,处理方法在下面的第3点
- 新建
src/api/index.ts
import * as login from './login/login';
// 把所有的接口api整合在一起,暴露出去,方便使用
export default Object.assign({}, login,);
- 由于使用了 typescript,所以需新增
src/types/type-axios.d.ts
解决axios中返回值类型找不到的问题
import { AxiosRequestConfig } from 'axios';
/**
* 自定义扩展axios模块
* @author xxx
*/
declare module 'axios' {
export interface AxiosInstance {
<T = any>(config: AxiosRequestConfig): Promise<T>;
request<T = any>(config: AxiosRequestConfig): Promise<T>;
get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
head<T = any>(url: string, config?: AxiosRequestConfig): Promise<T>;
post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
patch<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T>;
}
}
添加上type-axios.d.ts的声明文件后,再去看第1点的文件,发现就正常了
- 在
src/views/request.vue页面中就可以正常使用了
<template>
<div></div>
</template>
<script setup lang="ts">
import API from '@/api';
const requestRes = async () => {
// 直接调用封装好的对应的api去使用即可
let result = await API.login('史珍香', '123456');
}
</script>
<style scoped>
</style>
8. 安装UI库 element-plus
1.安装
npm install element-plus --save
下面的话,全部来自于官网
需要使用额外的插件来导入要使用的组件。
自动导入推荐
首先你需要安装unplugin-vue-components 和 unplugin-auto-import这两款插件
npm install -D unplugin-vue-components unplugin-auto-import
然后把下列代码插入到你的 Vite 或 Webpack 的配置文件中
Vite
// vite.config.ts
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
export default defineConfig({
// ...
plugins: [
// ...
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
})
Webpack#
// webpack.config.js
const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
module.exports = {
// ...
plugins: [
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
}
想了解更多打包 (Rollup, Vue CLI) 和配置工具,请参考 unplugin-vue-components 和 unplugin-auto-import。
全局配置
在引入 Element Plus 时,可以传入一个包含 size 和 zIndex 属性的全局配置对象。 size 用于设置表单组件的默认尺寸,zIndex 用于设置弹出组件的层级,zIndex 的默认值为 2000。
我这里使用的是完整引入
完整引入:
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus, { size: 'small', zIndex: 3000 })
按需引入:
<template>
<el-config-provider :size="size" :z-index="zIndex">
<app />
</el-config-provider>
</template>
<script>
import { defineComponent } from 'vue'
import { ElConfigProvider } from 'element-plus'
export default defineComponent({
components: {
ElConfigProvider,
},
setup() {
return {
zIndex: 3000,
size: 'small',
}
},
})
</script>
2.使用
在使用的时候,如果发现提示如下信息
应该是兼容性问题导致的
Vite2 需要 Node.js 版本 >= 12.0.0
Vite3 需要 Node.js 版本 14.18+,16+
另外,有些模板需要依赖更高的 Node 版本才能正常运行,当你的包管理器发出警告时,请注意
升级你的 Node 版本
点击查看使用 nvm管理 node.js(windows版本)和 通过 nrm 进行 npm源 之间的切换
9. 安装 commitizen 来规范git的提交信息
Commitizen 是一个帮助我们编写规范 commit message 的工具
也就是约定式提交,一种用于给提交信息增加人机可读含义的规范
- 安装方式一,【全局安装,不推荐,可以忽略】
// 安装commitizen
npm install -g commitizen
// commitizen根据不同的`adapter`配置commit message
npm install -g cz-conventional-changelog
// 使用全局模式安装的话须要在全局根目录下创建.czrc文件,
// 而后文件中输入内容`{“path”:"cz-conventional-changelog"}`或者键入以下命令:
echo '{ "path": "cz-conventional-changelog" }' > ~/.czrc
配置完成后,在你本地进入任何的 git 管理的项目, 使用 git cz 代替 git commit 都会出现选项,用来生成符合格式的 Commit message,如下图:
// 安装前的提交命令:
git add .
git commit -m 'xxxxx'
git push
// 安装后的提交命令:
git add .
git cz
git push
但是由于项目不同,个人习惯不同,可以不推荐全局安装,只需要在用到的项目中,进行项目内独自安装就可以了
- 安装方式二,【项目内独自安装,推荐】
npm install commitizen cz-conventional-changelog --save-dev
- 配置
package.json
{
...
"scripts": {
"commit:desc": "下面命令的解释:设置规范化的提交信息的",
"commit":"git-cz",
},
"config":{
"commitizen":{
"path":"node_modules/cz-conventional-changelog"
}
}
...
}
配置完成后,在提交的代码的时候,就会让其选择提交类型、代码的影响范围、简要信息,详细信息,页脚信息,是否提交【不一一律述了,都是写完enter键下一步】,最后代码就会按照commitizen插件的约束,进行信息的提交了
- commitlint校验
进行了上面的操做,其实对于一个自觉地人来讲,已经够了,可是没有约束就表明了自由,自由就有人越界,我若是不按约束提交,照样玩的嗨起
例如 如果我们忘记使用
npm run commit命令, 直接使用了 git commit -m "xxxx", message 信息依然会被提交上去,这样就会造成项目中出现不规范的提交 message
那么怎么给这些自由加一些约束呢?
需要安装 @commitlint/config-conventional 和 @commitlint/cli
npm install @commitlint/config-conventional @commitlint/cli --save-dev
然后在项目更目录下创建配置文件 commitlint.config.js 或者 .commitlintrc.js 或者 .commitlintrc.cjs
配置 commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
},
};
你可使用官网的方式测试一下你的提交是否符合规范
由于commitlint默认的提示信息,是英文的
所以就想对commitlint进行自定义的提交规范
若是想自己定义提交规范也是可以实现的,前提是需要安装 commitlint-config-cz 和 cz-customizable
npm install commitlint-config-cz cz-customizable --save-dev
重新配置 commitlint.config.js 或 commitlint.config.cjs
module.exports = {
extends: ['@commitlint/config-conventional', 'cz'],
rules: {
// <type>枚举
'type-enum': [
2,
'always',
[
'feature', // 新功能(feature)
'bug', // 此项特别针对bug号,用于向测试反馈bug列表的bug修改情况
'fix', // 修补bug
'ui', // 更新 ui
'docs', // 文档(documentation)
'style', // 格式(不影响代码运行的变动)
'perf', // 性能优化
'release', // 发布
'deploy', // 部署
'refactor', // 重构(即不是新增功能,也不是修改bug的代码变动)
'test', // 增加测试
'chore', // 构建过程或辅助工具的变动
'revert', // feat(pencil): add ‘graphiteWidth’ option (撤销之前的commit)
'merge', // 合并分支, 例如: merge(前端页面): feature-xxxx修改线程地址
'build', // 打包
],
],
// <type> 格式 小写
'type-case': [2, 'always', 'lower-case'],
// <type> 不能为空
'type-empty': [2, 'never'],
// <scope> 范围不能为空
'scope-empty': [2, 'never'],
// <scope> 格式 小写
'scope-case': [2, 'always', 'lower-case'],
// <scope> 范围格式
// 'scope-case': [0],
// <subject> 主要 message 不能为空
'subject-empty': [2, 'never'],
// <subject> 以什么为结束标志,禁用
'subject-full-stop': [0, 'never'],
// <subject> 以.为结束标志
// 'subject-full-stop': [2, 'never', '.'],
// subject 大小写不做校验 和 <subject>格式,禁用
'subject-case': [0, 'never'],
// <subject> 格式
// 可选值
// 'lower-case' 小写 lowercase
// 'upper-case' 大写 UPPERCASE
// 'camel-case' 小驼峰 camelCase
// 'kebab-case' 短横线 kebab-case
// 'pascal-case' 大驼峰 PascalCase
// 'sentence-case' 首字母大写 Sentence case
// 'snake-case' 下划线 snake_case
// 'start-case' 全部首字母大写 start-case
// 'subject-case': [2, 'never', []],
// <body> 以空行开头
'body-leading-blank': [1, 'always'],
// <footer> 以空行开头
'footer-leading-blank': [1, 'always'],
// Header
'header-max-length': [2, 'always', 72],
},
};
重新配置package.json
"config": {
"commitizen": {
"path": "node_modules/cz-customizable"
}
}
新增配置文件cz-config.js 或者 cz-config.cjs(这是我自定义的配置)
module.exports = {
types: [
{value: 'feature', name: 'feature: 增加新功能'},
{value: 'bug', name: 'bug: 测试反馈bug列表中的bug号'},
{value: 'fix', name: 'fix: 修复bug'},
{value: 'ui', name: 'ui: 更新UI'},
{value: 'docs', name: 'docs: 文档变更'},
{value: 'style', name: 'style: 代码格式(不影响代码运行的变动)'},
{value: 'perf', name: 'perf: 性能优化'},
{value: 'refactor', name: 'refactor: 重构(既不是增加feature,也不是修复bug)'},
{value: 'release', name: 'release: 发布'},
{value: 'deploy', name: 'deploy: 部署'},
{value: 'test', name: 'test: 增加测试'},
{value: 'chore', name: 'chore: 构建过程或辅助工具的变动(更改配置文件)'},
{value: 'revert', name: 'revert: 回退'},
{value: 'build', name: 'build: 打包'}
],
scopes: [],
// override the messages, defaults are as follows
messages: {
type: '请选择提交类型:',
customScope: '请输入您修改的范围(可选):',
subject: '请简要描述提交 message (必填):',
body: '请输入详细描述(可选):',
footer: '请输入要关闭的issue(可选):',
confirmCommit: '确认使用以上信息提交?(y/n)'
},
allowCustomScopes: true,
// 跳过问题
skipQuestions: ['body', 'footer'],
// subject文字长度默认是72
subjectLimit: 72
};
- 进行测试,查看配置是否生效
执行命令:npm run commit
npm run commit
到目前为止,只是规范了 git 的提交信息,我们对提交前代码的检查还没有做到位,例如 ESLint、Prettier等,这时候,就需要 husky了
10. 安装 husky + Git hooks 配置提交校验
注意:写文章时候是依赖于 husky v8.0.3版本,而且 husky 更新的太快了,所以使用 husky 时建议区分下版本
如果想用最新版的 husky,建议参考官网去配置
- Git Hooks
整体的hooks非常多,但是我们用的比较多的其实只有两个
- commit-msg
由 git commit 和 git merge 调用
可以使用 git commit --no-verify 绕过
- pre-commit
由 git commit 调用
可以使用 git commit --no-verify 绕过
在获取建议的提交日志消息和进行提交之前被调用
- husky
husky 是一个 Git Hook 工具
husky 的具体使用可以参考:这篇大佬文章
- 安装husky
npm install husky --save-dev
// vue-cli脚手架创建的项目,自动安装了lint-staged,vite的项目需要手动安装一下lint-staged
npm install lint-staged --save-dev
注意:推荐使用 npm 安装 eslint 和 husky,因为在 windows 操作系统下, 用 yarn 安装依赖,不会触发 husky pre-commit 钩子命令
- 把项目用git管理起来,否则无法生成 .husky 文件夹
使用 git init 进行初始化环境(把这个目录变成Git可以管理的仓库)
- 启动 hooks, 生成 .husky 文件夹
- 方式一:
npx husky install
- 方式二: 在 package.json 中生成 prepare指令
npm set-script prepare "husky install"
注意:这个需要 npm > 7.0 版本
可以使用npm install -g npm升版本
- 方式三: 直接配置
然后执行 prepare 指令 npm run prepare
npm run prepare
- 添加 hooks,执行下面的命令,会在 .husky 目录下生成一个 commit-msg 脚本文件
mac电脑下执行命令:
向commit-msg 脚本文件中 添加命令 npx --no-install commitlint --edit "$1", 用来commit-msg 时进行校验
- 因为这条语句里包含着
$1,它是在shell命令中代表的是参数
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
windows电脑下执行命令:
Windows系统的cmd是没有$1这种操作符,如果要依然执行,就会显示下面的内容
windows系统中直接把步骤分开执行就可以解决
(1)添加一个文件commit-msg在.husky文件夹下, 执行下面命令
npx husky add .husky/commit-msg
因为我们没有用到shell命令符 上面的指令肯定能执行创建
(2)在创建后的文件夹commit-msg文件里直接填充你的指令即可
此时,不符合规范的 commit 将不会被允许提交,如下图:
可以看到,我们配置的
commitlint功能已经生效了,(哇,流弊了,终于弄出来了~~~)
- 添加 hooks,执行下面的命令,会在 .husky 目录下生成一个 pre-commit 脚本文件
同时向 pre-commit 脚本文件中 添加命令 npx --no-install lint-staged, 用来pre-commit 时进行校验代码是否规范
mac电脑下执行命令:
// npx husky add .husky/pre-commit "npx eslint --ext .js,.ts,.vue src"
npx husky add .husky/pre-commit "npx --no-install lint-staged"
windows电脑下执行命令:
(1)添加一个文件pre-commit在.husky文件夹下, 执行下面命令
npx husky add .husky/pre-commit
因为我们没有用到shell命令符 上面的指令肯定能执行创建
(2)在创建后的文件夹pre-commit文件里直接填充你的指令即可
此时提交代码,如果项目中有错误,无法提交,想要提交代码,必须解决所有的错误信息
- lint-staged自动修复格式错误 (修复的是Git暂存区的代码)
lint-staged可以让你当前的代码检查只检查本次修改更新的代码,并在出现错误的时候,自动修复并推送
- 修改
package.json配置,添加如下代码
添加第7步中的 pre-commit文件中的 lint-staged 命令的配置
// 用这个就可以
"lint-staged": {
"src/**/*.{js,ts,vue}": [
"npm run eslint",
"npm run prettier",
]
},
"lint-staged": {
"src/**/*.{js,ts,vue}": [
"npm run eslint",
"npm run prettier",
// git add . 这个一定要写,否则就算代码提交到远程仓库了,
// 用 git status 命令查看,
// 有时候还会发现有个别文件没有 git add 到暂存区,和git commit 到本地库
"git add ."
// 这3个命令是从上到下依次执行的
]
},
"lint-staged": {
"*.{js,ts}": [
"npm run eslint",
"npm run prettier"
]
},
"lint-staged": {
"**/*.less": "stylelint --syntax less",
"**/*.{js,jsx,ts,tsx}": "eslint --ext .js,.jsx,.ts,.tsx",
"**/*.{js,jsx,tsx,ts,less,md,json}": [
"prettier --write",
"git add ."
]
}
// "*.js": "项目中所有的 js 文件"
// "**/*.js": "项目中所有的 js 文件"
// "src/*.js": "src目录中所有的 js 文件"
// "src/**/*.js": "src文件夹中所有的 js 文件"
如上配置,每次它在你本地 commit 之前,校验你所提的内容是否符合你本地配置的 eslint 规则 和 自动格式化当前目录下的所有文件
符合规则,提交成功
不符合规则,他会自动执行 npm run eslint 尝试帮你自动修复 (eslint命令 在package.json中配置过了)
修复成功: 则会自动帮你把修复好的代码提交
修复失败: 提示你错误,让你修复好才可以提交代码
- 使用git命令提交代码到远程仓库,进行测试
1.使用 git add . 将本地修改的所有文件同步到git暂存区
2.使用 git commit -m '提交记录' 命令将暂存区的改动提交到本地
(1) git add . 可以通过
(2) git commit -m '完成项目初始化' 无法通过
这是因为之前在上面配置了 commitlint 包的一系列内容,用来检测提交信息是否符合格式
(3) 用 commitlint 规定好的格式,来commit
校验规则在 commitlint.config.cjs 中配置
'feature', // 新功能(feature)
'bug', // 此项特别针对bug号,用于向测试反馈bug列表的bug修改情况
'fix', // 修补bug
'ui', // 更新 ui
'docs', // 文档(documentation)
'style', // 格式(不影响代码运行的变动)
'perf', // 性能优化
'release', // 发布
'deploy', // 部署
'refactor', // 重构(即不是新增功能,也不是修改bug的代码变动)
'test', // 增加测试
'chore', // 构建过程或辅助工具的变动
'revert', // feat(pencil): add ‘graphiteWidth’ option (撤销之前的commit)
'merge', // 合并分支, 例如: merge(前端页面): feature-xxxx修改线程地址
'build', // 打包
因为设置了 范围不能为空
// <scope> 范围不能为空
'scope-empty': [2, 'never'],
所以正确的提交格式是:类型名字(范围): 描述信息
git commit -m 'feature(all): 完成项目初始化' // 可以通过
3.使用 git remote add origin github.com/xxx/xxx.git 进行本地和远程关联
4.使用 git push -u origin master 命令创建远程master分支,同时进行推送到远程仓库上
这样就将一个新项目成功创建到GitHub上了
11.vite的开发环境和生产环境的配置
- 把
vite.config.ts文件拆分成vite.config.ts、vite.base.config.ts、vite.dev.config.ts、vite.prod.config.ts4个文件
vite.config.ts文件内容:
import { defineConfig } from 'vite'; // 用来做vite的语法提示的
import viteBaseConfig from './vite.base.config';
import viteDevConfig from './vite.dev.config';
import viteProdConfig from './vite.prod.config';
const envResolver = {
build: () => {
return { ...viteBaseConfig, ...viteProdConfig }; // 写法一
// return Object.assign({}, viteBaseConfig, viteProdConfig); // 写法二
},
serve: () => {
console.log('开发环境');
return Object.assign({}, viteBaseConfig, viteDevConfig);
},
};
// https://vitejs.dev/config/
export default defineConfig(({ command, mode, ssrBuild }) => {
// command === 'serve'是开发环境 command === 'build'是生产环境
return envResolver[command]();
});
vite.base.config.ts文件内容:
import { defineConfig } from 'vite'; // 用来做vite的语法提示的
import vue from '@vitejs/plugin-vue';
import * as path from 'path';
// element plus的按需引入
import AutoImport from 'unplugin-auto-import/vite';
import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
// element plus的按需引入
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
//设置别名,用来快速指定文件
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
});
vite.dev.config.ts文件内容:
import { defineConfig } from 'vite'; // 用来做vite的语法提示的
// https://vitejs.dev/config/
export default defineConfig({
server: {
port: 8080, //启动端口
hmr: {
host: '127.0.0.1',
port: 8080,
},
// 设置 https 代理
proxy: {
'/api': {
target: '要代理的 http 地址',
changeOrigin: true,
rewrite: (path: string) => path.replace(/^\/api/, ''),
},
},
},
});
vite.prod.config.ts文件内容:
import { defineConfig } from 'vite'; // 用来做vite的语法提示的
// https://vitejs.dev/config/
export default defineConfig({});
- 修改
tsconfig.node.json文件
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
// 添加上新增的文件
"include": ["vite.config.ts","vite.base.config.ts","vite.dev.config.ts","vite.prod.config.ts"]
}
12.vite的环境变量的配置
环境变量等定义: 会根据当前的代码的环境,产生值的变化的变量 就叫做 环境变量
vite内置了dotenv这个第三方库
- 如何在vite.config.ts文件中获取自己定义的环境变量
dotenv这个第三方库,会默认自动读取.env文件,并解析该文件中的对应的环境变量,并将其注入到node中的process这个全局的对象内,(但是vite考虑到和其他配置的一些冲突问题,它是不会直接注入到process对象内)
vite考虑到和其他配置的一些冲突问题,例如:
root:
项目根目录(`index.html` 文件所在的位置)。可以是一个绝对路径,
或者一个相对于该配置文件本身的相对路径,默认是`process.cwd()`
envDir:
用来配置当前环境变量的文件地址
在项目根目录下新建一个.env文件
APP_KEY: 110
BASE_URL: 'http://tongyong/api/v1'
尝试在vite.config.ts文件中获取自己定义的环境变量
// https://vitejs.dev/config/
export default defineConfig(({ command, mode, ssrBuild }) => {
console.log('process===>', process); // 这里是拿不到自己定义的环境变量的
console.log('process===>', process.env.NODE_ENV); // 执行 npm run dev 命令,可以拿到,值是development
return envResolver[command]();
});
想要在vite.config.ts文件中获取自己定义的环境变量,vite给我们提供了一个补偿手段,就是可以调用loadEnv来手动确认和获取env文件中的环境变量
// https://vitejs.dev/config/
export default defineConfig(({ command, mode, ssrBuild }) => {
// command === 'serve'是开发环境 command === 'build'是生产环境
// mode===>就是开发模式,例如:development、production
// console.log('process===>', process.env.NODE_ENV);
// 当前env文件所在的目录,loadEnv()方法中第二个参数不是必须使用process.cwd()的
// process.cwd()方法 返回当前node进行的工作目录
const env = loadEnv(mode, process.cwd(), '');
console.log('env===>', env); // 这里可以拿到自己在.env文件中定义的环境变量
return envResolver[command]();
});
当我们调用loadEnv的时候,它会做如下几件事情:
1、直接找到.env文件,然后解析文件中的环境变量,并放进一个对象里面
2、会将vite.config.ts文件中defineConfig函数中传入的mode这个变量的值拼接成:
.env.development,并根据我们提供的目录去取对应的配置文件,然后去解析文件,并放进一个对象里面
3、我们可以理解为
const envConfig = 读取.env的配置文件
const devConfig = 读取.env.development的配置文件
const finalConfig = {...envConfig, ...devConfig} // 进行合并和覆盖,相同内容,后面的会覆盖前面的
- 配置可以获取不同环境下的自身的环境变量
例如:
生产环境下,自动获取自己定义的生产环境的环境变量
开发环境下,自动获取自己定义的开发环境的环境变量
等等...
只需要创建对应的.env.xxx文件就可以了
创建开发环境下的环境变量文件.env.development和生产环境下的环境变量文件.env.production
.env.development文件
APP_KEY: 119
BASE_URL: 'http://dev/api/v1'
执行命令,获取环境变量:
npm run dev
成功获取到自己定义的开发环境的环境变量
.env.production文件
APP_KEY: 120
BASE_URL: 'http://prod/api/v1'
执行命令,获取环境变量:
npm run build
成功获取到自己定义的生产环境的环境变量
.env文件:所有环境都需要用到的环境变量
.env.development文件:开发环境需要用到的环境变量,(默认情况下vite将开发环境取名为development),其中
npm run dev --mode develop会将开发环境取名develop
.env.production文件:生产环境需要用到的环境变量,(默认情况下vite将生产环境取名为production)
.env.test文件:测试环境需要用到的环境变量,只需要在package.json文件中的scripts对象下添加一个
"test": "--mode test",命令,然后执行npm run test就可以获取测试环境需要用到的环境变量
- 如何在其他的ts文件中获取自己定义的环境变量
官网地址:cn.vitejs.dev/guide/env-a…
使用 `import.meta.env.xxx` 来获取
但是你会发现,没有获取到开发环境下自己定义的环境变量APP_KEY: 119 和 BASE_URL: http://dev/api/v1
这里就要说明一下,尤大大是真的对咱们不放心啊
官网原话:为了防止意外地将一些环境变量泄漏到客户端,只有以 VITE_ 为前缀的变量才会暴露给经过 vite 处理的代码
所以要把.env文件、.env.development文件、.env.production文件中的环境变量都加上前缀 VITE_,这样就可以获取到了
- 如何自定义
.env文件、.env.development文件、.env.production文件中的环境变量的前缀
官网地址:cn.vitejs.dev/config/shar…
在vite.base.config.ts中使用`envPrefix`,来声明自定义的前缀
vite.base.config.ts文件中代码
import { defineConfig } from 'vite'; // 用来做vite的语法提示的
// https://vitejs.dev/config/
export default defineConfig({
// ...省略其他配置
envPrefix: 'MYPROJECT_', // 这里就是声明自定义的前缀
});
把.env文件、.env.development文件、.env.production文件中的环境变量的前缀都变成MYPROJECT_
13.为什么vite.config.ts文件中可以书写esmodule形式的代码?
vite.config.ts文件是在服务端(也就是node端)执行,那它应该只能书写commonjs形式的代码才对
这是因为vite它在读取这个vite.config.js文件的时候,会率先用node去解析这个文件,如果发现你是用esmodule规范来书写的,vite会直接将你的esmodule规范替换成commonjs规范
项目模板地址:点击获取项目模板
✿✿ヽ(°▽°)ノ✿
到此为止,一个基于 vite + vue3 + ts + pinia + element-plus + vueuse 创建的前端项目模板,就完成了
✿✿ヽ(°▽°)ノ✿