一、前言
在团队开发中,保持代码风格的一致性和代码质量的高度,对于项目的可维护性和可读性非常重要。为了实现这一目标,我们可以使用工具来自动格式化代码并进行代码校验,在开发过程中捕获潜在的问题,并提供修复建议。
本示例中,我们将使用 Vite 来创建一个新的 Vue 3 项目。我们将使用 Prettier 来统一格式化代码,并集成 ESLint 和 Stylelint 进行代码校验规范。ESLint 用于检测 JavaScript 代码中的潜在问题和错误,而 Stylelint 则用于检测 CSS/SCSS 代码中的潜在问题和错误。
这样的配置能够帮助我们在开发过程中更早地捕获问题,并提供规范的修复建议,从而提高代码质量和团队合作效率。
二、创建项目
1、环境准备
- node v18.17.1
- pnpm 8.15.5
2、初始化项目
本项目使用vite进行构建,vite官方中文文档参考:cn.vitejs.dev/guide/
使用pnpm进行项目创建以及依赖下载等。(当然npm、yarn也行)
pnpm:performant npm ,意味“高性能的 npm”。pnpm由npm/yarn衍生而来,解决了npm/yarn内部潜在的bug,极大的优化了性能,扩展了使用场景。被誉为“最先进的包管理工具”
pnpm安装指令
npm i -g pnpm
项目初始化命令:
cmd里执行或者在VSCode终端执行即可
pnpm create vite
项目目录结构如下:
进入到项目根目录pnpm install安装全部依赖.安装完依赖运行程序:pnpm run dev
运行完毕项目跑在http://127.0.0.1:5173/,可以访问你得项目啦
三、项目配置
1、eslint配置
eslint中文官网:http://eslint.cn/
ESLint最初是由Nicholas C. Zakas 于2013年6月创建的开源项目。它的目标是提供一个插件化的javascript代码检测工具
首先安装eslint
pnpm i eslint -D
1.1、 生成配置文件:.eslintrc.cjs
npx eslint --init
该命令会向我们提几个问题,然后根据我们的回答生成配置文件
安装配置完成之后,src文件夹下面会多一个.eslintrc.cjs配置文件
.eslintrc.cjs配置文件内容
module.exports = { //运行环境 env: { browser: true, //浏览器端 es2021: true, //es2021 }, //规则继承 extends: [ //全部规则默认是关闭的,这个配置项开启推荐规则,推荐规则参照文档 //比如:函数不能重名、对象不能出现重复key "eslint:recommended", "plugin:@typescript-eslint/recommended", //ts语法规则 "plugin:vue/vue3-essential", //vue3语法规则 ], //要为特定类型的文件指定处理器 overrides: [ { env: { node: true, }, files: [".eslintrc.{js,cjs}"], parserOptions: { sourceType: "script", }, }, ], /** * 指定解析器:解析器 * Esprima 默认解析器Babel-ESLint babel解析器 * @typescript-eslint/parser ts解析器 */ parserOptions: { ecmaVersion: "latest", //校验ECMA最新版本 parser: "@typescript-eslint/parser", sourceType: "module", //设置为"script"(默认),或者"module"代码在ECMAScript模块中 }, /** * ESLint支持使用第三方插件。在使用插件之前,您必须使用npm安装它 * 该eslint-plugin-前缀可以从插件名称被省略 */ plugins: ["@typescript-eslint", "vue"], //eslint规则 rules: {}, };
1.2、vue3环境代码校验插件
vue3环境代码校验插件
# 让所有与prettier规则存在冲突的Eslint rules失效,并使用prettier进行代码检查 "eslint-config-prettier": "^9.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-node": "^11.1.0", # 运行更漂亮的Eslint,使prettier规则优先级更高,Eslint优先级低 "eslint-plugin-prettier": "^5.1.3", # vue.js的Eslint插件(查找vue语法错误,发现错误指令,查找违规风格指南 "eslint-plugin-vue": "^9.24.0", # 该解析器允许使用Eslint校验所有babel code "@babel/eslint-parser": "^7.24.1",
安装指令
pnpm install -D eslint-plugin-import eslint-plugin-vue eslint-plugin-node eslint-plugin-prettier eslint-config-prettier eslint-plugin-node @babel/eslint-parser
1.3、修改.eslintrc.cjs
配置文件
module.exports = { //运行环境 env: { browser: true, //浏览器端 es2021: true, //es2021 node: true, jest: true, }, //规则继承 extends: [ //全部规则默认是关闭的,这个配置项开启推荐规则,推荐规则参照文档 //比如:函数不能重名、对象不能出现重复key 'eslint:recommended', 'plugin:@typescript-eslint/recommended', //ts语法规则 'plugin:vue/vue3-essential', //vue3语法规则 'plugin:prettier/recommended', ], //要为特定类型的文件指定处理器 overrides: [ { env: { node: true, }, files: ['.eslintrc.{js,cjs}'], parserOptions: { sourceType: 'script', }, }, ], /* 指定如何解析语法 */ parser: 'vue-eslint-parser', /** 优先级低于 parse 的语法解析配置 */ /** * 指定解析器:解析器 * Esprima 默认解析器Babel-ESLint babel解析器 * @typescript-eslint/parser ts解析器 */ parserOptions: { ecmaVersion: 'latest', //校验ECMA最新版本 parser: '@typescript-eslint/parser', sourceType: 'module', //设置为"script"(默认),或者"module"代码在ECMAScript模块中 jsxPragma: 'React', ecmaFeatures: { jsx: true, }, }, /** * ESLint支持使用第三方插件。在使用插件之前,您必须使用npm安装它 * 该eslint-plugin-前缀可以从插件名称被省略 */ plugins: ['@typescript-eslint', 'vue'], /* * eslint规则 * "off" 或 0 ==> 关闭规则 * "warn" 或 1 ==> 打开的规则作为警告(不影响代码执行) * "error" 或 2 ==> 规则作为一个错误(代码不能执行,界面报错) */ rules: { // eslint(https://zh-hans.eslint.org/docs/latest/rules/) 'no-var': 'error', // 要求使用 let 或 const 而不是 var 'no-multiple-empty-lines': ['warn', { max: 1 }], // 不允许多个空行 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', 'no-unexpected-multiline': 'error', // 禁止空余的多行 'space-before-function-paren': 'off', // 函数括号前面是否需要空格 'no-use-before-define': 'off', // 禁止在变量定义前使用变量 'no-unused-vars': 'off', // 禁止未使用过的变量 'no-undef': 'off', // 禁止使用未定义的变量 'no-useless-escape': 'off', // 禁止不必要的转义字符 'prettier/prettier': 'error', // 代码格式化 'comma-dangle': 'off', // 对象或数组最后一个元素后面是否需要加逗号 // 结尾必须有分号; semi: [ 'error', 'always', { omitLastInOneLineBlock: true, }, ], // typeScript (https://typescript-eslint.io/rules) '@typescript-eslint/no-unused-vars': 'error', // 禁止定义未使用的变量 '@typescript-eslint/prefer-ts-expect-error': 'off', // 禁止使用 @ts-ignore '@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型 '@typescript-eslint/no-var-requires': 'off', // 允许使用 require() 函数导入模块 '@typescript-eslint/no-empty-function': 'off', // 禁止空函数 '@typescript-eslint/no-use-before-define': 'off', // 禁止在 函数/类/变量 定义之前使用它们 '@typescript-eslint/ban-types': 'off', // 禁止使用特定类型 '@typescript-eslint/no-non-null-assertion': 'off', // 不允许使用后缀运算符的非空断言(!) '@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。 '@typescript-eslint/explicit-module-boundary-types': 'off', // 要求函数和类方法的显式返回类型 '@typescript-eslint/ban-ts-comment': 'error', // 禁止在类型注释或类型断言中使用 // @ts-ignore '@typescript-eslint/semi': 'off', // eslint-plugin-vue (https://eslint.vuejs.org/rules/) 'vue/multi-word-component-names': 'off', // 要求组件名称始终为 “-” 链接的单词 'vue/no-v-model-argument': 'off', // 禁止在 v-model 指令中使用 argument 选项 'vue/no-reserved-component-names': 'off', // 禁止使用保留字命名组件 'vue/attributes-order': 'off', // 禁止组件的属性顺序不一致 'vue/one-component-per-file': 'off', // 要求每个文件只有一个组件 'vue/no-multiple-template-root': 'off', // 禁止在单个文件中使用多个根元素 'vue/max-attributes-per-line': 'off', // 限制每行属性的最大数量 'vue/multiline-html-element-content-newline': 'off', // 限制多行 HTML 元素内容的缩进 'vue/singleline-html-element-content-newline': 'off', // 限制单行 HTML 元素内容的缩进 'vue/require-default-prop': 'off', // 禁止在 props 定义中不指定默认值 'vue/require-explicit-emits': 'off', // 要求显式声明 emits 事件 'vue/html-closing-bracket-newline': 'off', // 禁止在 HTML 结束标签的前后都有换行符 'vue/attribute-hyphenation': 'off', // 强制属性命名使用连字符线分隔 'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用 'vue/no-mutating-props': 'off', // 不允许组件 prop的改变 'vue/no-v-html': 'off', // 禁止使用v-html指令 'vue/custom-event-name-casing': 'error', // 自定义事件名称必须使用驼峰式命名法 }, };
1.4、创建 .eslintignore
忽略文件
编辑 .eslintignore
,添加不需要校验的目录、文件
/dist dist /node_modules node_modules tsconfig.json *.svg *.png *.jpg *.jpeg *.scss *.gif *.webp *.ttf index.html *.md
1.5、运行脚本
package.json新增两个运行脚本
"scripts": { "lint": "eslint src", "fix": "eslint src --fix", }
2、prettier配置
官网:https://prettier.io/docs/en/install
有了eslint,为什么还要有prettier?eslint针对的是javascript,他是一个检测工具,包含js语法以及少部分格式问题,在eslint看来,语法对了就能保证代码正常运行,格式问题属于其次;
而prettier属于格式化工具,它看不惯格式不统一,所以它就把eslint没干好的事接着干,另外,prettier支持
包含js在内的多种语言。
总结起来,eslint和prettier这俩兄弟一个保证js代码质量,一个保证代码美观。
2.1、安装依赖包
pnpm install -D eslint-plugin-prettier prettier eslint-config-prettier
2.2、创建 .prettierrc
项目根目录下创建 .prettierrc
文件,并添加对应的规则
//命令创建 node --eval "fs.writeFileSync('.prettierrc','{}\n')"
添加对应规则:参考官网:https://prettier.io/docs/en/options
{ "singleQuote": true, "semi": false, "bracketSpacing": true, "htmlWhitespaceSensitivity": "ignore", "endOfLine": "auto", "trailingComma": "all", "tabWidth": 2 }
2.3、创建.prettierignore
忽略文件
在项目根目录下创建 .prettierignore
文件
以下文件夹下内容不需要被格式化
# 忽略格式化文件 (根据项目需要自行添加) /dist/* /html/* .local /node_modules/** **/*.svg **/*.sh /public/* .idea .vscode .hbuilderx src/manifest.json src/pages.json *.md *.woff *.ttf *.yaml /docs .husky /bin
*通过pnpm run lint
去检测语法,如果出现不规范格式,通过pnpm run fix
修改
3、stylelint配置
stylelint为css的lint工具。可格式化css代码,检查css语法错误与不合理的写法,指定css书写顺序等。
3.1、安裝依赖
pnpm add sass sass-loader stylelint postcss postcss-scss postcss-html stylelint-config-prettier stylelint-config-recess-order stylelint-config-recommended-scss stylelint-config-standard stylelint-config-standard-vue stylelint-scss stylelint-order stylelint-config-standard-scss -D
3.2、创建.stylelintrc.cjs
配置文件
参考:https://stylelint.io/user-guide/configure
// @see https://stylelint.bootcss.com/ module.exports = { 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属性书写顺序插件, 'stylelint-config-prettier', // 配置stylelint和prettier兼容 ], overrides: [ { files: ['**/*.(scss|css|vue|html)'], customSyntax: 'postcss-scss', }, { files: ['**/*.(html|vue)'], customSyntax: 'postcss-html', }, ], ignoreFiles: [ '**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts', '**/*.json', '**/*.md', '**/*.yaml', ], /** * null => 关闭该规则 * always => 必须 */ rules: { 'value-keyword-case': null, // 在 css 中使用 v-bind,不报错 'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器 'function-url-quotes': 'always', // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)" 'no-empty-source': null, // 关闭禁止空源码 'selector-class-pattern': null, // 关闭强制选择器类名的格式 'property-no-unknown': null, // 禁止未知的属性(true 为不允许) 'block-opening-brace-space-before': 'always', //大括号之前必须有一个空格或不能有空白符 'value-no-vendor-prefix': null, // 关闭 属性值前缀 --webkit-box 'property-no-vendor-prefix': null, // 关闭 属性前缀 -webkit-mask 'selector-pseudo-class-no-unknown': [ // 不允许未知的选择器 true, { ignorePseudoClasses: ['global', 'v-deep', 'deep'], // 忽略属性,修改element默认样式的时候能使用到 }, ], }, }
3.3、创建.stylelintignore
忽略文件
/node_modules/* /html/* /dist/* /public/* public/* /dist* /docs/**/*
3.4、运行脚本
"scripts": { "lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix" }
"scripts": { "dev": "vite --open", "build": "vue-tsc && vite build", "preview": "vite preview", "lint": "eslint src", "fix": "eslint src --fix", "format": "prettier --write \"./**/*.{html,vue,ts,js,json,md}\"", "lint:eslint": "eslint src/**/*.{ts,vue} --cache --fix", "lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix" },
当我们运行pnpm run format
的时候,会把代码直接格式化