本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前端自动化 之 Eslint+Prettier 篇 (二)
目录结构
├─.vscode
│ ├─extensions.json
│ └─settings.json
├─library
│ ├─build
│ │ └─plugins
│ │ └─unplugin
│ │ │ └─index.ts
│ │ ├─gzip.ts
│ │ ├─imagemin.ts
│ │ ├─index.ts
│ │ ├─styleImport.ts
│ │ └─svgSprite.ts
│ └─layouts
├─public
└─src
│ ├─assets
│ │ └─svg
│ └─components
│ │ └─HelloWorld.vue
│ └─main.ts
├─.editorconfig
├─.eslintrc.js
├─.gitignore
├─index.html
├─package.json
├─prettier.config.js
├─tsconfig.json
├─tsconfig.node.json
└─vite.config.ts
Eslint
ESLint是一个代码
检查工具,主要用来发现代码错误、统一代码风格,目前已被广泛的应用于各种 JavaScript 项目中。它通过插件化的特性极大的丰富了适用范围,搭配@typescript-eslint/parser之后,甚至可以用来检查TypeScript代码。续接上一篇开始Eslint整合TypeScript、Vue
cnpm i eslint eslint-plugin-vue@latest @typescript-eslint/parser@latest @typescript-eslint/eslint-plugin@latest -D
.eslintrc.js 添加配置
module.exports = {
root: true,
env: {
browser: true, // 浏览器环境中的全局变量。
es2021: true,
node: true, // Node.js 全局变量和 Node.js 作用域。
},
// 继承共享的配置
extends: [
'vue-global-api',
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
],
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2021,
parser: '@typescript-eslint/parser',
sourceType: 'module',
},
plugins: ['vue', '@typescript-eslint'],
rules: {
'no-undef': 'off',
'no-console': 'off',
'no-debugger': 'off',
'vue/no-v-html': 'off',
'省略.....'
},
}
package.json 添加配置
"scripts": {
"lint:eslint": "eslint {library,src}/**/*.{vue,ts,tsx} --fix",
},
执行
lint:eslint检查匹配{library,src}/**/*.{vue,ts,tsx}文件是否存在错误代码.eslintrc.js配置文件 rules 配置规则
npm run lint:eslint
Prettier
Prettier的中文意思是漂亮的、机灵的,也是一个流行的代码格式化工具的名称,它能够解析代码,使用你自己设定的规则来重新打印出格式规范的代码。根据规范,自动格式化代码。具有比 eslint auto-fix 更加强大的代码规范性修复能力Eslint整合Prettier之前先安装VSCode插件Prettier - Code formatter和ESLint
cnpm i prettier eslint-config-prettier eslint-plugin-prettier vue-eslint-parser @vue/eslint-config-prettier -D
prettier.config.js
module.exports = {
printWidth: 80,
tabWidth: 2,
useTabs: false,
semi: false,
singleQuote: true,
quoteProps: 'as-needed',
jsxSingleQuote: false,
trailingComma: 'es5',
bracketSpacing: true,
bracketSameLine: false,
arrowParens: 'always',
htmlWhitespaceSensitivity: 'ignore',
vueIndentScriptAndStyle: true,
endOfLine: 'lf',
}
.eslintrc.js 添加配置
module.exports = {
...
// 继承共享的配置
extends: [
'vue-global-api',
'plugin:prettier/recommended',
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'@vue/eslint-config-prettier',
],
...
rules: {
'prettier/prettier': 'warn',
...
}
}
package.json 添加配置
"scripts": {
"lint:prettier": "prettier {src,mock}/**/*.{html,vue,css,sass,scss,ts,md} --write",
},
npm run lint:prettier
插件冲突
Prettier与Eslint发生冲突可以安装eslint-config-prettier与eslint-plugin-prettier解决
cnpm i eslint-config-prettier eslint-plugin-prettier -D
.eslintrc.js 最终配置
module.exports = {
root: true,
env: {
browser: true, // 浏览器环境中的全局变量。
es2021: true,
node: true, // Node.js 全局变量和 Node.js 作用域。
},
// 继承共享的配置
extends: [
'vue-global-api',
'plugin:prettier/recommended',
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'@vue/eslint-config-prettier',
],
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2021,
parser: '@typescript-eslint/parser',
sourceType: 'module',
},
plugins: ['vue', '@typescript-eslint'],
/**
* 关闭: "off"或者0 警告: "warn"或者1 错误: "error"或者2
*/
rules: {
'prettier/prettier': 'warn',
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', // 禁止使用console
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', // 禁止使用debugger
'no-undef': 'off', // 不能有未定义的变量
'no-multi-spaces': 'error', // 禁止多个空格
/**
* eslint-plugin-vue
* https://eslint.vuejs.org/rules
* 此规则包含 "plugin:vue/vue3-recommended"
*/
'vue/no-v-html': 'off', // 不使用v-html
'vue/html-self-closing': [
'error',
{
html: {
void: 'any',
normal: 'any',
component: 'always',
},
svg: 'always',
math: 'always',
},
],
'vue/multiline-html-element-content-newline': 'off', // 强制在多行元素的内容前后加换行符
'vue/singleline-html-element-content-newline': 'off', // 强制在单行元素的内容前后加换行符
// Vue.js风格指南 https://v3.cn.vuejs.org/style-guide/
// Vue组件排序
'vue/order-in-components': [
'warn',
{
order: ['el', 'name', 'key', 'parent', 'functional'],
},
],
// Vue属性排序
'vue/attributes-order': [
'warn',
{
order: ['DEFINITION', 'LIST_RENDERING', 'CONDITIONALS'],
},
],
'@typescript-eslint/no-explicit-any': ['off'],
},
}
package.json 最终配置
{
"name": "admin-risun-vite",
"version": "1.0.0-beta.1",
"private": true,
"author": {
"name": "SunHongYu",
"email": "17600616235@163.com",
"url": "https://juejin.cn/"
},
"description": "Admin-Risun 前端框架",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "npm run build && vite preview",
"preview:dist": "vite preview",
"lint:eslint": "eslint {library,mock,src}/**/*.{vue,ts,tsx} --fix",
"lint:prettier": "prettier {library,src,mock}/**/*.{html,vue,css,sass,scss,ts,md} --write",
"clean": "rimraf node_modules",
"prepare": "husky install"
},
"dependencies": {
"element-plus": "^2.0.1",
"vue": "^3.2.30",
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.10.1",
"@typescript-eslint/parser": "^5.10.1",
"@vitejs/plugin-legacy": "^1.7.0",
"@vitejs/plugin-vue": "^2.2.0",
"@vue/compiler-sfc": "^3.2.30",
"@vue/eslint-config-prettier": "^7.0.0",
"@vue/eslint-config-typescript": "^10.0.0",
"eslint": "^8.7.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.3.0",
"prettier": "^2.5.1",
"svg-sprite-loader": "^6.0.11",
"typescript": "^4.5.4",
"unplugin-auto-import": "^0.5.11",
"unplugin-vue-components": "^0.17.18",
"vite": "^2.8.0",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-imagemin": "^0.6.1",
"vite-plugin-style-import": "^1.4.1",
"vite-plugin-svg-icons": "^2.0.1",
"vite-plugin-vue-setup-extend": "^0.4.0",
"vite-plugin-style-import": "^1.4.1",
"vue-eslint-parser": "^8.2.0",
"vue-global-api": "^0.4.1",
"vue-tsc": "^0.31.1"
}
}
settings.json 最终配置
{
"window.zoomLevel": 1.5,
"workbench.editor.enablePreview": false,
"workbench.sideBar.location": "left",
"workbench.colorTheme": "Dracula Soft",
"workbench.iconTheme": "vscode-icons",
"editor.detectIndentation": false,
"editor.fontFamily": "Consolas, 'Courier New', monospace,'微软雅黑'",
"editor.fontSize": 16,
"editor.tabSize": 2,
"editor.minimap.enabled": false, // 关闭快速预览
"editor.lineHeight": 24, // 设置文字行高
"editor.lineNumbers": "on", // 开启行数提示
"editor.suggest.snippetsPreventQuickSuggestions": false,
"editor.codeActionsOnSave": {
"source.fixAll.stylelint": true,
"source.fixAll.eslint": true
},
"editor.quickSuggestions": {
// 开启自动显示建议
"other": true,
"comments": true,
"strings": true
},
// 配置 ESLint 检查的文件类型
"eslint.validate": ["typescript", "vue", "html"],
"eslint.options": {
//指定vscode的eslint所处理的文件的后缀
"extensions": [".ts", ".vue"]
},
// 搜索忽略内容
"search.exclude": {
"**/node_modules": true,
"**/dist": true
},
"git.enableSmartCommit": true,
"git.autofetch": true,
"git.confirmSync": false,
"files.exclude": {
"**/.idea": true
},
"files.eol": "\n",
"path-intellisense.mappings": {
"@": "${workspaceRoot}/src"
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[scss]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[markdown]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
}
.editorconfig
EditorConfig for VS Code和Prettier - Code formatter一样,都是用来配置格式化你的代码的,这个格式化代码,要和你lint配置相符!否则会出现你格式化代码以后,却不能通过你的代码校验工具的检验
# 表示是最顶层的 EditorConfig 配置文件
root = true
[*]
charset = utf-8 # 设置文件字符集为 utf-8
end_of_line = lf # 控制换行类型(lf | cr | crlf)
indent_size = 2 # 缩进大小
indent_style = space # 缩进风格(tab | space)
insert_final_newline = true # 始终在文件末尾插入一个新行
max_line_length = 100
[*.{yml,yaml,json}]
indent_style = space
indent_size = 2
[*.md]
max_line_length = off
trim_trailing_whitespace = false # 去除行首的任意空白字符
[Makefile]
indent_style = tab