項目 eslint 從零到一
eslint
在項目裏並不太陌生,通常在使用腳手架時,會默認讓你安裝執行的eslint
, 當公司項目比較規範時,常常會配置組內統一的eslint
規則,eslint
幫助我們在開發階段檢查代碼是否符合標準規範,統一了我們組內不同項目代碼風格,也可以幫助我們養成良好的代碼習慣,統一eslint
對於項目的可維護性必不可少,今天我們一起學習一下如果改進你項目的規範。
正文開始...
首先我們還是用之前搭建vue
的一個項目從 0 到 1 開始配置eslint
安裝 eslint
npm i eslint --save-dev
然後我們執行初始化eslint
命令
npm init @eslint/config
此時會讓我們選擇第三個, 並且選擇js modules
, vue
.eslintrc.js
, 由於我添加了ts
所以默認也會添加@typescript-eslint
,我們會發現package.json
多了幾個插件@typescript-eslint/eslint-plugin
、@typescript-eslint/parser
,並且要安裝npm i typescript --save-dev
eslint
規則是自己默認選擇的配置
module.exports = {
env: {
browser: true,
es2021: true
},
extends: ['eslint:recommended', 'plugin:vue/essential', 'plugin:@typescript-eslint/recommended'],
parserOptions: {
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
sourceType: 'module'
},
plugins: ['vue', '@typescript-eslint'],
rules: {
indent: ['error', 'tab'],
'linebreak-style': ['error', 'unix'],
quotes: ['error', 'single'],
semi: ['error', 'never']
}
};
默認生成的規則就是以上
我們運行npx eslint ./src/index.js
eslint
默認配置的規則
添加 eslint 規則
在.eslintrc.js
中,主要有以下 5 個部分
module.exports = {
env: {
browser: true,
es2021: true
},
extends: ['eslint:recommended', 'plugin:vue/essential', 'plugin:@typescript-eslint/recommended'],
parserOptions: {
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
sourceType: 'module'
},
plugins: ['vue', '@typescript-eslint'],
rules: {
indent: ['error', 'tab'],
'linebreak-style': ['error', 'unix'],
quotes: ['error', 'single'],
semi: ['error', 'always']
}
};
- env 支持的環境,根據
.browserslistrc
瀏覽器預設的環境預設對應的規則
module.exports = {
env: {
browser: true,
es2021: true,
es6: true
}
}
- extends 繼承第三方的規則
module.exports = {
extends: ['eslint:recommended']
}
- parserOptions 指定解析器選項
module.exports = {
parserOptions: {
ecmaVersion: 'latest',
parser: '@typescript-eslint/parser',
sourceType: 'module'
}
}
- plugins 插件
module.exports = {
plugins: ['vue', '@typescript-eslint'],
}
- rules 具體對應規則的設置
module.exports = {
rules: {
semi: 0 // 0 off,1 warn,2 error
},
}
參考一段之前業務有用到的統一eslint
配置
// eslint配置
module.exports = {
root: true,
env: {
node: true,
},
parserOptions: {
parser: '@typescript-eslint/parser',
},
extends: [
'plugin:vue/essential',
'plugin:prettier/recommended',
'@vue/airbnb',
'@vue/typescript',
],
rules: {
'no-undef': 0, // 由於eslint無法識別.d.ts聲明文件中定義的變量,暫時關閉
'no-console': process.env.NODE_ENV === 'production' ? 2 : 0,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
indent: 0,
'linebreak-style': 0,
'no-trailing-spaces': 0,
'class-methods-use-this': 0,
'import/prefer-default-export': 0,
'no-restricted-syntax': 0,
'no-tabs': 0,
'import/no-unresolved': 0,
'no-underscore-dangle': 0,
'comma-dangle': 'off',
'max-len': 'off',
camelcase: 'off',
'object-curly-newline': 0,
'operator-linebreak': 0,
'guard-for-in': 0,
'import/no-webpack-loader-syntax': 0,
// 不安全項
'no-param-reassign': 0,
'no-dupe-class-members': 0,
'no-unused-vars': 0, // ts裏面有校驗,可以把eslint 的校驗關閉
// 提示警告
'no-return-await': 1,
'import/no-cycle': 1,
'no-nested-ternary': 1,
'no-new-func': 1,
'vue/no-side-effects-in-computed-properties': 1,
'vue/no-multiple-template-root': 'off', // vue3 模板可以有多個根結點
'vue/valid-template-root': 'off',
'vue/no-v-for-template-key': 'off', // vue3 v-for 中template 可以設置key
'vue/no-v-model-argument': 0,
'vue/no-use-v-if-with-v-for': 0,
'import/no-extraneous-dependencies': 1,
'no-continue': 1,
'operator-assignment': 1,
'no-bitwise': 1,
'prefer-destructuring': 2,
'array-callback-return': 2,
'func-names': 2,
'no-plusplus': 2,
'no-shadow': 2,
'no-mixed-operators': 2,
'no-fallthrough': 2,
'default-case': 2,
'no-useless-constructor': 2,
'no-unused-expressions': ["error", { "allowShortCircuit": true }],
// 關閉iview input組件,col組件個別標籤報錯
'vue/no-parsing-error': [2, { 'x-invalid-end-tag': false }],
// 保證js、ts項目arrow風格一致
'arrow-parens': [2, 'always', { requireForBlockBody: false }],
'implicit-arrow-linebreak': [0, 'beside'],
// ts 任意枚舉報錯問題
'no-shadow': 'off',
'@typescript-eslint/no-shadow': ['error'],
},
overrides: [
{
files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)'],
env: {
jest: true,
},
},
],
};
選擇 Airbnb 風格
在自定義自己的rules
, 也可以執行npm init @eslint/config
配置社區比較流行的自定義風格,使用Airbnb
airbnb
風格後,執行npx eslint ./src/index.js
index.js
有一個規則錯誤
Expected 1 empty line after import statement not followed by another import import/newline-after-import
我們將第三行換行就行
import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
我們看下生成的.eslintrc.js
這個一般在你項目中多少有看到也可以是 json 類型
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: [
'plugin:vue/essential',
'airbnb-base',
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: [
'vue',
],
rules: {
},
};
rules
有很多的配置,可以參考官方 [1]
運行時檢測 eslint
一般正常情況當我們啓動服務時,如果我們代碼有寫得不規範,開發工具就終端就會給我們提示警告,此時我們需要 eslint-loader[2],只需要這樣配置即可
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: [
'babel-loader', 'eslint-loader'
]
}
]
}
}
但是官方已經不建議這麼用了eslint-loader
已經停止了維護,官方建議使用eslint-webpack-plugin
在webpack.config.js
我們可以這麼做
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
plugins: [
new ESLintPlugin()
]
}
當我們運行npm run server
時就會檢查代碼錯誤
utils/index.js
中不能使用console
, 很顯然,這條規則並不符合我們的初衷,我只需要在生產環境環境不打印console
纔行
當我們修改.eslintrc.js
時,
module.exports = {
rules: {
'no-console': 0,
'import/extensions': ['error', 'always']
}
}
我們將rules
規則的noconsole: 0
允許使用console
, 當我修改完時,再次運行,終端就不會報錯了
我們再加個規則,max-params:2
, 函數形參不能到過三個,如果超過三個就會報錯
module.exports = {
rules: {
'no-console': 0,
'import/extensions': ['error', 'always'],
'max-params': 2
}
}
// utils/index.js
function test(a, b, c, d) {
console.log('hello', a, b, c, d);
}
test(1, 2, 3, 4);
max-params
默認最多就是 3 個參數,所以在運行時就提示報錯了。於是你改成下面這樣就可以了
// utils/index.js
function test(a, ...rest) {
console.log('hello', ...rest);
}
test(1, 2, 3, 4);
vscode 的 eslint 插件
除了eslint-webpack-plugin
的插件幫我們在代碼運行時就可以檢測出代碼的一些不規範問題,我們通常可以結合vscode
插件幫我更友好的提示, 我們需要在寫代碼的時候,編輯器就已經給我們提示錯誤。
安裝完後,打開對應文件, 就會有對應的提示
eslint
.prettierrc 自動格式化代碼
在vscode
中裝上插件Prettier code formatter
然後在根目錄下創建.prettierrc.json
文件
{
"singleQuote": true,
"printWidth": 150
}
設置編輯器的代碼長度 printWidth 是 150, 設置 singleQuote 單引號。
我們也需要設置一下vscode
的settings.json
, 主要設置參照如下
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
}
因爲eslint
既檢查了代碼又可以根據.eslintrc.js
美化代碼,但是prettierrc
有時會與eslint
的配置格式有衝突,所以此時 vscode 格式化的狀態就是混亂的,因此有時候很奇怪,所以你需要改settings.json
默認改成eslint
, 具體可以參考知乎這篇文章 prettierrc[3]
網上關於prettierrc
的配置有很多,具體上還是看組內統一的規範,這裏我貼一份之前項目格式化所用的,估計不同團隊的配置絕大數是大同小異。
// .prettierrc.json
{
"eslintIntegration": true,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"proseWrap": "preserve",
"arrowParens": "avoid",
"bracketSpacing": true,
"disableLanguages": [
"vue"
],
"endOfLine": "auto",
"htmlWhitespaceSensitivity": "ignore",
"ignorePath": ".prettierignore",
"jsxBracketSameLine": false,
"jsxSingleQuote": false,
"requireConfig": false,
"trailingComma": "es5"
}
總結
-
eslint
在項目中的配置,主要利用npm init @eslint/config
快速初始化一份eslint
配置,在試用前先進行安裝npm i eslint --save-dev
-
開發環境使用
eslint-loader
, 現在採用更多的是eslint-webpack-plugins
-
採用
Airbnb
風格格式校驗代碼 -
.prettierrc.json 格式化代碼,不過注意與
eslint
格式衝突的問題。 -
本文示例 code example[4]
參考資料
[1] 參考官方: https://eslint.org/docs/rules/
[2]eslint-loader: https://www.npmjs.com/package/eslint-loader
[3]prettierrc: https://zhuanlan.zhihu.com/p/347339865
[4]code example: https://github.com/maicFir/lessonNote/tree/master/webpack/webpack-06-eslint
Web 技術學苑 專注前端 web 技術、分享 web 技術
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/N-F7WaBeao0DdsaYN2kX0A