企业级前端工程化配置指南:vite4 + vue3 + ts + pinia + vue-router + axios + commit规范 + 代码质量检验 - 掘金

大家好,我是苏先生,一名热爱钻研、乐于分享的前端工程师,跟大家分享一句我很喜欢的话:人活着,其实就是一种心态,你若觉得快乐,幸福便无处不在

github与好文

你可以学到什么?

  • 如何使用 vite 搭建项目
  • 如何集成与使用 web-localstorage-plus
  • 如何集成与使用 vue-router4
  • 如何集成与使用 pinia
  • 如何集成与使用 element-plus
  • 如何封装axios
  • 如何借力 eslint 和 prettier 保证代码质量
  • 如何借力 commitlint 规范git提交信息

源码地址

传送门

1.创建项目

按提示选择:

1.运行vite

js

复制代码

yarn create vite

2.输入自定义的项目名称

js

复制代码

name: › your-project-name

3.选择你想要的技术框架

js

复制代码

`? Select a framework: › - Use arrow-keys. Return to submit.
❯ Vanilla
Vue
React
Preact
Lit
Svelte
Others`

4.选择ts模板

js

复制代码

`? Select a variant: › - Use arrow-keys. Return to submit.
❯ TypeScript
JavaScript
Customize with create-vue ↗
Nuxt ↗`

5.按提示安装并运行项目

js

复制代码

`Done. Now run:
cd vite-project
yarn
yarn dev`

一键初始化

除了上述问答形式创建外,vite官方也提供了快捷语法:通过命令行参数创建

js

复制代码

`# npm 6.x
npm create vite@latest my-vue-app --template vue

npm 7+, extra double-dash is needed:

npm create vite@latest my-vue-app -- --template vue

yarn

yarn create vite my-vue-app --template vue

pnpm

pnpm create vite my-vue-app --template vue`

2.优化项目结构

修剪vite默认生成的项目结构

1.保留public文件夹,删除vite.svg文件,同时删除index.html中对该文件的引入

2.删除HelloWorld.vue文件,同时从App.vue中删除引入

3.删除App.vue中的默认代码,只保留默认的三个根元素

我个人习惯将template放到最前边

vue

复制代码

`<template>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>`

4.清空assets文件夹

定制化目录

1.创建store文件夹

放置关于pinia的数据状态

2.创建directive文件夹

放置我们的自定义指令,如:v-auth

3.创建utils文件夹

项目中的公共方法或常量

4.创建styles文件夹

管理公共css样式文件,如:reset.css

5.创建http文件夹

处理axios的封装和调用

6.创建router文件夹

管理vue-router的路由模块

7.创建pages文件夹

管理业务代码

3.配置vite.config.ts

配置别名

项目中,不同模块之间往往需要互相引入,使用别名能够帮助我们省去一级一级查找的繁琐

ts

复制代码

`...
import { resolve } from 'node:path'
export default defineConfig({
plugins: [vue()],
resolve:{
alias:{
'@':resolve(__dirname,'src')
}
}
})`

此时,node:path__dirname会报错,我们还需要安装下对应的ts类型包

js

复制代码

yarn add @types/node --D

设置代理

我们本地开发完跟后端联调阶段,经常会遇到跨域的问题,需要我们暂时的在前端进行下处理

js

复制代码

`export default defineConfig({
...
server: {
proxy: {
"/api": {
target: "http url",
changeOrigin: true,
rewrite: (path: string) => path.replace(/^/api/, ""),
},
},
},
});`

其中"/api"是我们要代理的接口标识,target是我们实际要访问的接口地址

设置自动导入

每次都手动导入依赖项是一件很麻烦的事情,幸运的是,我们可以借助第三方库来帮我们实现,它内置了常见的库,比如vue

1.安装

js

复制代码

yarn add unplugin-auto-import -D

2.在vite.config.ts中导入并作为plugin使用

ts

复制代码

`...
import AutoImport from 'unplugin-auto-import/vite'
export default defineConfig({
plugins: [...,AutoImport()],
...
});`

4.集成web-storage-plus

对于需要使用到持久缓存的地方,localstorage是优选的方案,不过原生接口比较难用,而该npm包对其进行了二次封装,使其支持了命名空间、过期时间、监听变化、批量操作等特性,且其为我们提供了发布订阅模式来弥补vue3中对bus的缺失,文档看这里:传送门

1.安装

js

复制代码

yarn add web-localstorage-plus

2.在main.ts中引入并初始化根存储

js

复制代码

`...
import createStorage from 'web-localstorage-plus'
createStorage({
rootName:'spp-storage'
})
...`

3.在.vue文件中引入并使用

vue

复制代码

`<script lang="ts" setup>
import { useStorage } from 'web-localstorage-plus'
const storage = useStorage()
storage.setItem('user',{
name:'spp',
age:28
})
</script>`

5.集成pinia

对于非持久化数据,我们选择使用pinia来进行管理,它帮我们托管了全局状态并且提供了响应式能力,文档看这里:传送门

1.安装pinia

js

复制代码

yarn add pinia

2.在store文件夹下新建index.ts文件作为pinia的根仓库文件

ts

复制代码

`import { createPinia } from "pinia";
const pinia = createPinia()
export default pinia`

3.在main.ts中导入并将 pinia 作为 plugin 注册给 vue

ts

复制代码

`import { createApp } from 'vue'
...
import pinia from '@/store'
...
const app = createApp(App)
app.use(pinia)
...`

4.在store文件夹下新建xxx.ts文件作为子存储模块

ts

复制代码

`import { defineStore } from 'pinia'
export default defineStore('spp', {
state() {
return {
spp:''
}
},
actions:{
updateSpp(spp:string){
this.spp = spp
}
}
})`

5.在.vue文件中使用或修改pinia的状态

vue

复制代码

`<script lang="ts" setup>
...
import useLoginStore from '@/store/login.ts'
// 获取状态
const store = useLoginStore()
// 修改状态
store.updateSpp('spp')
...
</script>`

6.集成vue-router4

作为spa项目,路由是我们进行页面切换的必备工具,文档看这里:传送门

1.使用yarn安装

js

复制代码

yarn add vue-router@4

2.在router文件夹下新建index.ts文件作为根路由

ts

复制代码

`import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
const routes: Array<RouteRecordRaw> = [
{
path: "/login",
name: "Login",
component: () => import("@/pages/login/index.vue")
},
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;`

3.在main.ts中导入并作为plugin注册给vue

ts

复制代码

`import { createApp } from 'vue'
import router from '@/router';
...
const app = createApp(App)
app.use(router)
...`

4.将根App.vue作为路由出口

vue

复制代码

`<template>
<RouterView/>
</template>`

7.集成less

1.安装

js

复制代码

yarn add less -D

2.使用

vue

复制代码

`<style lang="less" scoped>
.root-app {
.spp {
// 自定义样式
}
}
</style>`

8.集成element-plus

element-plus是vue侧比较流行的pc端ui框架之一,文档看这里:传送门

1.安装

js

复制代码

yarn add element-plus

2.按需自动导入

  • 安装依赖包

js

复制代码

yarn add unplugin-vue-components unplugin-auto-import -D

  • 修改vite.config.ts

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()],
}),
],
...
});`

3.在.vue文件夹下直接使用即可

9.集成axios(仅提供封装思路,可选)

axios是目前最流行的前端发起ajax请求的库,其基于promise实现,同时支持在浏览器和nodejs中使用,文档看这里:传送门

1.安装

js

复制代码

yarn add axios

2.在http文件夹下新建index.ts文件

该文件对我们业务中的请求进行基类封装

ts

复制代码

`import request from "./request";
import getPrefix from "./urlPrefix";
import { TgroupType } from '@/utils/types'
import { warn } from '@/utils/function'
class Http{
protected prefix:string=getPrefix(undefined);
protected config:any={}
constructor(group?:TgroupType){
this.prefix = getPrefix(group)
}
private combineUrl(url:string){
return this.prefix + url
}
setExtraConfig(config:any){
this.config = config
}
get<T>(url: string, arg?: T,message?:string){
return new Promise((resolve, reject) => {
request
.get(this.combineUrl(url), {
params: arg,
...this.config
})
.then((res:any)=>{
// 根据与后端的约定format数据,并做resolve或reject
...
})
.catch(reject)
.finally(()=>{
this.config={}
})
});
}
post<T>(url: string, message?: string | T, arg?: T) {
const isFull = arguments.length === 3
if (!isFull) {
arg = message as T;
}
const errMessage = '你的自定义错误'
return new Promise((resolve, reject) => {
request
.post(this.combineUrl(url), arg,{
...this.config,
})
.then((res: any) => {
// 根据与后端的约定format数据,并做resolve或reject
...
})
.catch(()=>{
warn(errMessage)
reject(errMessage);
})
.finally(()=>{
this.config={}
})
});
}
}
export const http = new Http()
export const httpRequest = Http
export const usePrefix = getPrefix`

3.在http文件夹下新建request.ts文件

该文件用于配置axios,并通过拦截器对接口状态进行检测和错误的统一处理

ts

复制代码

`import axios from "axios";
axios.defaults.timeout = 10000000;
axios.defaults.withCredentials = true;
axios.interceptors.request.use(
(config) => {
config.headers = Object.assign(config.headers,{
// 配置header
})
return config;
},
(error) => {
// 处理错误
return Promise.reject(error);
}
);
axios.interceptors.response.use(
(response) => {
// 统一拦截验证
return response;
},
(error) => {
// 处理错误
return Promise.reject(error);
}
);
export default axios;`

4.在http文件夹下新建urlPrefix.ts文件

该文件用于统一管理不同域名对应的不同环境下的url

ts

复制代码

`import { IurlConfig,TgroupType} from '@/utils/types'
const mode = import.meta.env.MODE;
const urlConfig:IurlConfig = {
// 前缀-{dev:'',pro:''}
}
const getPrefix = (key:TgroupType)=>{
if(key === undefined){
key = ''
urlConfigkey
}
return urlConfigkey
}
export default getPrefix;`

5.在业务中引入并使用

ts

复制代码

`import { http } from "@/http";
http
.post<传递与当前接口参数匹配的类型>(url, "添加成功", params)
.then(() => {
// 请求成功的业务处理
});`

10.常用工具推荐

  • 时间处理:moment

文档地址

  • 万能工具库:lodash-es

文档地址

11.代码质量与提交规范

eslint

因为eslint无法识别.vue文件,因此我们还需要一个定制化插件:eslint-plugin-vue,文档看这里:传送门

1.安装依赖

js

复制代码

yarn add eslint eslint-plugin-vue -D

2.创建.eslintignore忽略文件

.eslintignore

复制代码

`node_modules
dist
yarn.lock
index.html`

3.添加ts支持

eslint-plugin-vue只针对.vue文件或者.js文件中的vue写法,我们还需要对ts进行兼容

文档传送门:@typescript-eslint/parser@typescript-eslint/eslint-plugin

js

复制代码

yarn add @typescript-eslint/parser @typescript-eslint/eslint-plugin -D

4.在根目录下创建.eslintrc.cjs配置文件

js

复制代码

`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: {
"no-console": "error",
}
};`

5.按环境区分

实际项目中,我们一般会根据不同的开发环境来区分规则,比如console应在开发阶段可用,生产时禁用

1-安装依赖

文档看这里:cross-env@rollup/plugin-eslint

js

复制代码

yarn add cross-env @rollup/plugin-eslint -D

2-修改命令行

在打包阶段配置环境变量,我这里以production为例子

json

复制代码

`"scripts": {
...
"build": "cross-env NODE_ENV=production && vue-tsc --noEmit && vite build"
},`

3-将rollup插件加入vite的plugin

ts

复制代码

`...
import eslint from '@rollup/plugin-eslint';
export default defineConfig({
plugins: [
...
eslint({
include:['src/**']
})
],
...
});`

4-修改.eslintrc.cjs

cross-env会将定义的环境变量暴露在env上,我们获取并做三元判断即可

js

复制代码

`const mode = process.env.NODE_ENV
module.exports = {
...
rules: {
"no-console": mode === 'production' ? "error" : "off",
...
}
};`

prettier

相关文档看这里:prettiereslint-config-prettiereslint-plugin-prettier

1.安装依赖

js

复制代码

yarn add prettier eslint-config-prettier eslint-plugin-prettier -D

2.创建配置文件:.prettierrc.js

以我司的某个项目为例

js

复制代码

`module.exports = {
// 一行最多 150 个字符
printWidth: 150,
// 使用 4 个空格缩进
tabWidth: 4,
// 不使用 tab 缩进,而使用空格
useTabs: false,
// 行尾需要有分号
semi: true,
// 使用单引号代替双引号
singleQuote: true,
// 末尾使用逗号
trailingComma: 'es5',
// 箭头函数,只有一个参数的时候,也需要括号
arrowParens: 'always',
}`

3.修改 .eslintrc.js 配置

强制当和eslint冲突时,以prettier为准

js

复制代码

`module.exports = {
...
extends: [
...
'prettier',
'plugin:prettier/recommended'
],
...
};`

提交规范

我们需要在提交代码前对代码质量、代码格式和commit信息进行约束,为此,我们需要先注册commit提交前钩子

1-安装husky

文档看这里:传送门

js

复制代码

yarn add husky -D

2-初始化husky

在package.json文件夹下新增prepare脚本,并立即运行一次

json

复制代码

`"scripts": {
...
"prepare": "husky install"
},`

3-注册hook

我们使用pre-commit钩子来拦截提交行为,

js

复制代码

`npx husky add .husky/pre-commit "npm run check"
git add .husky/pre-commit`

此时,当git commit发生时,将会调用check脚本,但这默认事针对全部文件的,因此我们需要借助另一个npm包帮我们把当前更改的文件提取出来单独校验

1-安装lint-staged

文档看这里:传送门

js

复制代码

yarn add lint-staged -D

2-修改package.json配置

json

复制代码

`"lint-staged": {
"*.{js,ts,vue}": [
"npm run eslint",
"prettier --parser=typescript --write"
]
}`

3-与husky关联

将lint-staged作为check的指向脚本

json

复制代码

`"scripts": {
...
"check": "lint-staged"
},`

最后我们来对commit提交格式进行约束,这可以通过commitlint来帮我们完成,文档看这里:传送门

1-安装

js

复制代码

yarn add @commitlint/config-conventional @commitlint/cli -D

2-将其校验位置放在check脚本执行前

js

复制代码

npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'

3-创建配置文件commitlint.config.cjs

cjs

复制代码

`module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'feature', // 迭代功能
'conf', // 修改构建配置
'fixbug', // 修复bug
'refactor', // 代码重构
'optimize', // 代码优化
'style', // 仅修改样式文件
'docs', // 文档补充说明
],
],
'header-max-length': [0, 'always', 72], //限制最长72
},
};`

4-测试使用

迭代更新

2023-6-28

有jy反馈使用less会报错(将eslint插件替换成了@nabla/vite-plugin-eslint),已修复,需要的jy重新从仓库clone哦🥰

2023-7-28

增加pinia持久化存储

  • 安装依赖

ts

复制代码

yarn add @web-localstorage-plus/pinia

  • main.ts中设置持久化

ts

复制代码

`import createStorage from 'web-localstorage-plus';
import setPiniaPersist from '@web-localstorage-plus/pinia';
// 设置根存储库
createStorage({
rootName: 'spp-storage',
});
// 将pinia中的数据持久化到本地
setPiniaPersist(pinia);`

  • vite.config.ts中引入热更新插件

ts

复制代码

`import { getPlugin } from '@web-localstorage-plus/pinia';
const piniaHmrPlugin = getPlugin('vite');
export default defineConfig({
...,
plugins:[piniaHmrPlugin(resolve(__dirname, 'src/store'))]
})`

    • *

如果本文对您有用,希望能得到您的点赞和收藏

订阅专栏,每周更新2-3篇类型体操,等你哟😎

    • *

原网址: 访问
创建于: 2023-10-08 14:49:31
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论