为什么需要搭建一套团队用脚手架
- 团队开发,为了约束成员的代码行为
- 养成相同的代码习惯
- 便于团队人员迭代的代码交接
- 利于后期代码维护
项目结构
- api 统一封装网络请求,配置请求拦截和响应拦截
- assets 存放静态资源
- common 存放公共资源
- components 存放非路由组件
- router 存放路由
- store 状态管理仓库
- utils 存放工具类文件
- views 存放路由组件,也就是页面组件
下面开始从头进行代码风格配置
使用 vite 快速创建脚手架
npm init vite@latest
按提示进行操作,然后打开项目
npm install
npm run dev
配置网络请求
在src下新建api文件夹,index.js文件
npm i axios
import axios from 'axios';
import { ElMessage } from 'element-plus';
const PORT = 4000;
const baseURL = `http://localhost:${PORT}`;
const service = axios.create({
baseURL,
timeout: 2000,
});
// 请求拦截器
service.interceptors.request.use(
res => {
return res;
},
error => {
return Promise.reject(error);
},
);
// 响应拦截器
service.interceptors.response.use(
res => {
return res;
},
error => {
if (error.response && error.response.data) {
const code = error.response.status;
const msg = error.response.data.message;
ElMessage.error(`Code: ${code}, Message: ${msg}`);
// console.error(`[Axios Error]`, error.response);
} else {
ElMessage.error(`${error}`);
}
return Promise.reject(error);
},
);
export default service;
配置路由
在src下新建router文件夹,index.js文件
npm install vue-router@4
import { createRouter, createWebHashHistory } from 'vue-router';
import Home from '@/views/HomeView.vue';
const routes = [
{
path: '/',
name: 'home',
component: Home,
},
{
path: '/demo',
name: 'demo',
component: () => import('@/views/demoView.vue'),
},
{
path: '/todo',
name: 'todo',
component: () => import('@/views/todoList.vue'),
},
];
const router = createRouter({
history: createWebHashHistory(),
routes,
});
export default router;
配置状态管理机
在src下新建store文件夹,index.js文件,再分别建立各个对应的仓库
npm install pinia
// src/store/index.js
import { createPinia } from 'pinia';
const store = createPinia();
export default store;
// src/store/demo.js
import { defineStore } from 'pinia';
const demoStore = defineStore({
id: 'user',
state: () => {
return {
name: 'demo',
};
},
});
export default demoStore;
入口文件引入
在入口文件引入并use仓库和路由还有其他UI库
// src/main.js
import { createApp } from 'vue';
import ElementPlus from 'element-plus';
import App from './App.vue';
import router from './router';
import store from './store';
import 'element-plus/theme-chalk/index.css';
createApp(App).use(router).use(store).use(ElementPlus).mount('#app');
集成 CSS 预编译器 Sass/Less
npm i sass -D
npm i less -D
开始各种配置
一、修改 Vite 配置文件
1.Vite 配置文件 vite.config.ts 位于根目录下,项目启动时会自动读取。
2.简单配置:设置 @ 指向 src 目录、 服务启动端口、打包路径、代理等。
3.关于 Vite 更多配置项及用法,请查看 Vite 官网 vitejs.dev/config/ 。
// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
// 如果编辑器提示 path 模块找不到,则可以安装一下 @types/node -> npm i @types/node -D
import { resolve } from 'path';
const pathResolve = dir => {
return resolve(__dirname, dir);
};
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': pathResolve('src'),
},
extensions: ['.js', '.jsx'],
},
base: './', // 设置打包路径
server: {
port: 4000, // 设置服务启动端口号
open: true, // 设置服务启动时是否自动打开浏览器
cors: true, // 允许跨域
// 设置代理,根据我们项目实际情况配置
// proxy: {
// '/api': {
// target: 'http://XXX.XXX.XXX.XXX:8000',
// changeOrigin: true,
// secure: false,
// rewrite: path => path.replace('/api/', '/'),
// },
// },
},
});
二、集成 EditorConfig 配置
1.去插件市场下载插件 EditorConfig for VS Code 。
2.在项目根目录下增加 .editorconfig 文件:
# Editor configuration, see http://editorconfig.org
# 表示是最顶层的 EditorConfig 配置文件
root = true
[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行首的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行
[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false
三、集成 Prettier 配置
1.安装 Prettier,并下载插件 Prettier - Code formatter
npm i prettier -D
2.在本项目根目录下创建 .prettierrc.js 文件
module.exports = {
printWidth: 100, // 超过最大值换行
semi: true, // 行尾添加分号
tabWidth: 2, // 缩进字节数
useTabs: false, // 缩进不使用tab,使用空格
singleQuote: true, // 使用单引号代替双引号
arrowParens: 'avoid', // (x) => {} 箭头函数参数只有一个时是否要有小括号。avoid:省略括号 | always
bracketSpacing: true, // 在对象,括号与无序k-v之间加空格 "{ foo: bar }"
bracketLine: true, // 标签 > 不单独一行
tslintIntegration: false, // 不让prettier使用tslint的代码格式进行校验
vueIndentScriptAndStyle: true,
quoteProps: 'as-needed',
jsxBracketSameLine: true,
insertPragma: false,
requirePragma: false,
proseWrap: 'never',
htmlWhitespaceSensitivity: 'strict',
endOfLine: 'lf',
trailingComma: 'all',
}
四、集成 ESLint 配置
1.安装 ESLint,并下载插件ESLint
2.配置 ESLint
ESLint 安装成功后,执行 npx eslint --init,然后按照终端操作提示完成一系列设置来创建配置文件。
-
How would you like to use ESLint? (你想如何使用 ESLint?)我们这里选择 To check syntax, find problems, and enforce code style(检查语法、发现问题并强制执行代码风格)
-
What type of modules does your project use?(你的项目使用哪种类型的模块?)我们这里选择 JavaScript modules (import/export)
-
Which framework does your project use? (你的项目使用哪种框架?)我们这里选择 Vue.js
-
Does your project use TypeScript?(你的项目是否使用 TypeScript?)我们这里选择 No
-
Where does your code run?(你的代码在哪里运行?)我们这里选择 Browser 和 Node(按空格键进行选择,选完按回车键确定)
-
How would you like to define a style for your project?(你想怎样为你的项目定义风格?)我们这里选择 Use a popular style guide(使用一种流行的风格指南)
-
Which style guide do you want to follow?(你想遵循哪一种风格指南?)我们这里选择 Airbnb: github.com/airbnb/java…
-
What format do you want your config file to be in?(你希望你的配置文件是什么格式?)我们这里选择 JavaScript
-
Would you like to install them now with npm?(你想现在就用 NPM 安装它们吗?)根据上面的选择,ESLint 会自动去查找缺失的依赖,我们这里选择 Yes,使用 NPM 下载安装这些依赖包。
注意:如果自动安装依赖失败,那么需要手动安装npm i @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-airbnb-base eslint-plugin-import eslint-plugin-vue -D
3.ESLint 配置文件 .eslintrc.js
在上一步操作完成后, 配置.eslintrc.js 文件:
module.exports = {
root: true,
env: {
browser: true,
es2021: true,
node: true,
},
extends: ['plugin:vue/essential', 'airbnb-base', 'plugin:prettier/recommended'],
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaFeatures: {
globalReturn: false,
impliedStrict: false,
jsx: true,
},
},
plugins: ['vue'],
rules: {
'no-plusplus': 'off', // 允许使用一元运算符++和--
'vue/no-multiple-template-root': 'off', // 支持vue3添加多个根节点
'no-unused-expressions': 'off', // 允许使用&&运算符
'import/no-extraneous-dependencies': ['error', { devDependencies: true }], // 忽略devDependencies校验
'import/no-unresolved': 'off', // 禁用绝对路径
'import/extensions': 'off', // 导入校验
'no-underscore-dangle': 'off', // 下划线开头命名校验
'no-debugger': process.env.NODE_ENV === 'production' ? 1 : 0,
endOfLine: 0,
'array-bracket-newline': 0, // 在数组开括号后和闭括号前强制换行
'array-bracket-spacing': 1, // 强制数组方括号中使用一致的空格
'block-spacing': [2, 'always'], // 禁止或强制在代码块中开括号前和闭括号后有空格
'comma-dangle': 0, // 要求或禁止末尾逗号
'comma-spacing': [
// 强制在逗号前后使用一致的空格
2,
{
before: false,
after: true,
},
],
'keyword-spacing': [
// 强制在关键字前后使用一致的空格
2,
{
before: true,
after: true,
},
],
'no-delete-var': 2, // 禁止删除变量
'no-fallthrough': 2, // 禁止 case 语句落空
'no-lone-blocks': 2, // 禁用不必要的嵌套块
'no-multiple-empty-lines': [
// 禁止出现多行空行
2,
{
max: 1,
},
],
'no-trailing-spaces': 2, // 禁用行尾空格
'no-with': 2, // 禁用 with 语句
quotes: [
// 强制使用一致的反勾号、双引号或单引号
2,
'single',
{
avoidEscape: true,
allowTemplateLiterals: true,
},
],
'spaced-comment': 2, // 强制在注释中 // 或 /* 使用一致的空格
'max-len': [
'error',
{
code: 300, // 强制行的最大长度
comments: 300, // 强制注释的最大长度;默认长度同 code
ignoreUrls: true, // 忽略含有链接的行
ignoreStrings: true, // 忽略含有双引号或单引号字符串的行
ignoreTemplateLiterals: true, // 忽略包含模板字面量的行
},
],
'no-multi-assign': 2, // 禁止连续赋值
'no-var': 2, // 要求使用 let 或 const 而不是 var
'symbol-description': 2,
'no-self-assign': 2, // 禁止自我赋值
'no-self-compare': 2, // 禁止自身比较
'no-param-reassign': 0, // 禁止对 function 的参数进行重新赋值
'no-implied-eval': 2, // 禁止使用类似 eval() 的方法
'no-empty-function': 2, // 禁止出现空函数
'default-case': 2, // 要求 switch 语句中有 default 分支
'no-unused-vars': 2, // 禁止未使用过的变量
'vue/comment-directive': 0,
'vue/multi-word-component-names': 0, // 组件命名随意
'vue/no-async-in-computed-properties': 2, // 禁止在计算属性处理异步线程
'vue/no-duplicate-attributes': [
'error',
{
allowCoexistClass: true,
allowCoexistStyle: true,
},
],
'vue/require-component-is': 2, // 禁止component内置组件没有is属性
'vue/require-render-return': 2, // render创建VNode不能void
'vue/no-deprecated-slot-attribute': 0,
'vue/no-deprecated-slot-scope-attribute': 0,
'vue/no-deprecated-v-on-native-modifier': 0,
'vue/no-v-for-template-key': 0,
'vue/no-mutating-props': 0,
'vue/no-template-key': 0,
'vue/no-v-for-template-key-on-child': 0,
},
};
4.VSCode 在 settings.json 设置文件中,增加以下代码:
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
五、解决 Prettier 和 ESLint 的冲突
解决两者冲突问题,需要用到 eslint-plugin-prettier 和 eslint-config-prettier。
eslint-plugin-prettier将 Prettier 的规则设置到 ESLint 的规则中。eslint-config-prettier关闭 ESLint 中与 Prettier 中会发生冲突的规则。
最后形成优先级:Prettier 配置规则 > ESLint 配置规则。
- 安装插件
npm i eslint-plugin-prettier eslint-config-prettier -D
- 在
.eslintrc.js添加 prettier 插件
module.exports = {
...
extends: [
'plugin:vue/essential',
'airbnb-base',
'plugin:prettier/recommended' // 添加 prettier 插件
],
...
}
六、忽略语法检测
在根目录下新建.eslintignore文件
# 忽略eslint检测
build/*
node_modules
jsconfig.json
七、配置js规则文件
在根目录下新建jsconfig.json文件
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
],
"@c/*": [
"src/components/*"
]
},
"target": "ES6",
"module": "commonjs",
"allowSyntheticDefaultImports": true
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"dist"
],
"vueCompilerOptions": {
"experimentalCompatMode": 2
}
}