前期專案中忽略了 eslint 檢查,導致一執行 npm run lint
出現兩千多條錯誤(இдஇ; ) 造孽啊
花了兩三天搞完,做個錯誤彙總。
環境和配置
專案用 vue@3.2 + vite + ant-design@6.0
關於eslint 配置的用法可參考:ESLint中文
eslint 有專門應用於 vue 的外掛:eslint-plugin-vue
大致貼一下版本依賴
devDependencies: {
"@babel/eslint-parser": "^7.18.2",
"eslint": "^8.7.0",
"eslint-config-prettier": "^8.3.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^25.7.0",
"eslint-plugin-vue": "^8.3.0",
}
eslint 的配置採用 JS 檔案格式,經過幾次修改已經忘了一開始的內容,只貼基礎配置如下:
// .eslintrc.js
module.exports = {
// 只作用於當前目錄
root: true,
// 執行環境
env: {
node: true,
es6: true,
},
// 解析器
parser: '@babel/eslint-parser',
// 解析器選項
parserOptions: {
sourceType: 'module',
},
// 外掛
plugins: ['import'],
// 擴充套件配置
extends: [
'plugin:vue/vue3-recommended',
'plugin:import/recommended',
'prettier',
],
// 啟用規則
rules: {},
// 全域性變數
globals: {
h: true,
},
// 為指定檔案指定處理器
overrides: [
{
files: ['*.vue', '*.jsx'],
parser: 'vue-eslint-parser',
parserOptions: {
ecmaVersion: 2018,
},
rules: {}
}
],
}
ERROR: Parsing error: Unexpected token .
錯誤程式碼:
const isOpen = data?.form?.isOpen || false;
原來是無法識別可選鏈操作符(?.
),但是擴充套件運算子沒問題,看了eslint 的配置,發現是 ECMAScript 的版本設定了2018(ES9),而可選鏈操作符是 ES2020(如果沒記錯),修改配置就可以了
// .eslintrc.js
module.exports = {
parserOptions: {
// ES版本,最新可設定 2022 or "latest",overrides 中配置了有需要也要同步修改
ecmaVersion: 2020,
sourceType: 'module',
}
}
ERROR: Unable to resolve path to module
錯誤程式碼:
import Upload from '@/components/upload/index.vue'
路徑引用錯誤??看起來沒毛病,vite.config.js
中明明配置了短鏈
resolve: {
alias: {
'@': pathResolve('src'),
}
}
但 eslint 並不會自動讀取 vite 的配置,因此 eslint 也要加上對應配置:
// .eslintrc.js
module.exports = {
settings: {
'import/resolver': {
alias: {
map: ['@': './src']
}
}
}
}
另外引入 vue 檔案需要加上字尾.vue
,否則也會報相同錯誤。
ERROR: 'ref' is not defined
錯誤程式碼:
setup(){
const isOpen = ref(false);
return {
isOpen,
}
}
執行都沒報錯,怎麼突然 undefined 了??
等等,因為偷懶,vue 的語法糖都是unplugin-auto-import
每個檔案自動引入的:
// vite.config.js
import autoImport from 'unplugin-auto-import/vite';
autoImport({
imports: [
'vue',
'vue-router',
]
})
所以也要讓 eslint 知道,先生成一個包含所有變數的檔案:
// vite.config.js
autoImport({
...last,
eslintrc: {
// 已存在檔案設定預設 false,需要更新時再開啟,防止每次更新都重新生成
enabled: false,
// 生成檔案地址和名稱
filepath: './.eslintrc-auto-import.json',
globalsPropValue: true,
}
})
上面的enabled
在生成檔案後建議關閉,否則每次更新都會重新生成。
擴充套件到 eslint:
// .eslintrc.js
module.exports = {
extends: [
'plugin:vue/vue3-recommended',
'plugin:import/recommended',
'prettier',
'./.eslintrc-auto-import.json'
],
}
ERROR: vue/no-mutating-props
錯誤程式碼:
<!-- parent.vue -->
<template>
<Child v-model:open="openModal" />
</template>
<script>
export default{
setup(){
const openModal = ref(false);
return {
openModal,
}
}
}
</script>
<!-- child.vue -->
<template>
<a-modal v-model:visible="open"></a-modal>
</template>
<script>
export default{
props: {
open: {
type: Boolean,
default: true,
}
},
}
</script>
這是個低階錯誤,vue3支援多個引數雙向繫結,但是子元件不能直接修改props
,需要轉換一下:
方法一:用
computed
代替<template> <a-modal v-model:visible="isOpen"></a-modal> </template> <script> export default{ props: { open: { type: Boolean, default: true, } }, setup(props, { emit }){ const isOpen = computed({ get: () => { return props.open; }, set: (value) => { emit('update:open', value); }, }); return { isOpen, } }, } </script>
方法二:用
watch
監聽<template> <a-modal v-model:visible="isOpen"></a-modal> </template> <script> export default{ props: { open: { type: Boolean, default: true, } }, setup(props, { emit }){ const isOpen = ref(props.open); watch( () => isOpen.value, (value) => emit('update:open', value) ); return { isOpen, } }, } </script>
ERROR: no-console
錯誤程式碼:
console.log(data);
eslint 的規則設定了不能有console
,當然可以改配置:
// .eslintrc.js
rules: {
'no-console': 'off',
// or:
'no-console': [2, { allow: ['warn', 'error'] }],
// or:
'no-console': process.env.NODE_ENV === 'production' ? [2, { allow: ['warn', 'error'] }] : 'off'
}
提這個錯誤是為了引入下面的問題,在某些地方需要列印但不希望 eslint 報錯,可以讓其忽略檢查:
// 忽略整個檔案在第一行加
/* eslint-disable */
// 忽略一段程式碼檢查
/* eslint-disable */
...this our codes;
/* eslint-enable */
// 忽略一行程式碼檢查
console.log(data); // eslint-disable-line
// 忽略下一行程式碼檢查
// eslint-disable-next-line
console.log(data);
那麼在<template>
中呢?
<template>
<!-- eslint-disable -->
<div v-for="item in options">{{ item }}</div>
</template>
然後發現不行,會報vue/require-v-for-key
錯誤,註釋失敗。
找了各種文章最後發現是自己的鍋Ծ‸Ծ,找不出問題的時候還是要看官方文件,在eslint-plugin-vue已有說明vue/comment-directive
規則就是用於忽略程式碼檢查,一看 eslint 的檔案配置果然是關閉了:
// .eslintrc.js
rules: {
'vue/comment-directive': 'off',
}
改為error
,完美؏؏☝ᖗ乛◡乛ᖘ☝؏؏
收工。