如何替 Vue Vite 專案加上 ESLint?

前言

這一篇將會記錄一下該如何替自己的 Vue Vite 專案安裝上 ESLint,並且使用 Airbnb 或 Standard 的規範。

環境準備

首先這邊先準備一個 Vue3 Vite 的開發環境,準備方式很簡單,只需要在終端機輸入

1
npm init [email protected]

就可以依照提示選項建立出一個 Vue3 的 Vite 開發環境。

如果你想建立的是一個 Vue2 的開發環境的話,只需要輸入以下即可

1
npm init [email protected]

那麼這邊我就示範建立一個 Vue3 的開發環境,而這邊第一個環境就是使用 Airbnb 的規範。

環境準備

以下也附上文字版訊息

1
2
3
4
5
6
7
8
9
✔ Project name: … vue3-eslint-airbnb
✔ Add TypeScript? … No(✅) / Yes
✔ Add JSX Support? … No(✅) / Yes
✔ Add Vue Router for Single Page Application development? … No / Yes(✅)
✔ Add Pinia for state management? … No / Yes(✅)
✔ Add Vitest for Unit Testing? … No(✅) / Yes
✔ Add Cypress for both Unit and End-to-End testing? … No(✅) / Yes
✔ Add ESLint for code quality? … No / Yes(✅)
✔ Add Prettier for code formatting? … No(✅) / Yes

那麼為了方便讀者閱讀,所以以上我也翻譯成中文

1
2
3
4
5
6
7
8
9
✔ 專案名稱: … vue3-eslint-airbnb
✔ 加入 TypeScript? … No(✅) / Yes
✔ 加入 JSX 支援? … No(✅) / Yes
✔ 是否是為了開發單頁式應用加入 Vue Router? … No / Yes(✅)
✔ 加入 Pinia 狀態管理? … No(✅) / Yes
✔ 加入 Vitest 進行單元測試? … No(✅) / Yes
✔ 加入 Cypress 進行 End-to-End 測試? … No(✅) / Yes
✔ 加入 ESLint 提供程式碼品質? … No / Yes(✅)
✔ 加入 Prettier 替程式碼格式化? … No(✅) / Yes

那麼接下來直接準備來介紹安裝 ESLint 囉。

提醒一下,這邊之所以不安裝 Prettier 是因為我們會使用 ESLint 的規範來格式化程式碼,所以不需要再安裝 Prettier,如果你選取了 Pretter 的話,那麼就會出現兩個格式化的工具,這樣就會造成衝突,所以這邊我們不安裝 Prettier。

安裝 ESLint Airbnb

再開始安裝 ESLint 之前,我們先來看一下我們的專案目錄結構,這邊請打開 package.json 檔案,可以看到目前專案已經有安裝 ESLint 了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"name": "vue3-template-airbnb",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview --port 4173",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
},
"dependencies": {
"pinia": "^2.0.21",
"vue": "^3.2.38",
"vue-router": "^4.1.5"
},
"devDependencies": {
"@vitejs/plugin-vue": "^3.0.3",
"eslint": "^8.22.0",
"eslint-plugin-vue": "^9.3.0",
"vite": "^3.0.9"
}
}

並且目錄也有一個 .eslintrc.cjs 的檔案

1
2
3
4
5
6
7
8
9
10
11
/* eslint-env node */
module.exports = {
root: true,
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended'
],
parserOptions: {
ecmaVersion: 'latest'
}
}

目前來講,當前這個專案預設是採用 Vue3 本身的規範,請注意目前僅僅只有基本的 Vue3 規範,因此還沒有加入 Airbnb 的規範。

那麼接下來我們就來準備安裝 Airbnb 的規範,首先我們先安裝 Airbnb 的相關套件

1
npm install --save-dev eslint-config-airbnb-base

我們可以看到上方指令中安裝了 eslint-config-airbnb-base 這個套件,這個套件是 Airbnb 的核心規範套件,因此我們必須要安裝這個套件。

如果你是想安裝 Standard 規範,那麼你可以安裝 eslint-config-standard 這個套件,如果你是想安裝 Google 規範,那麼你可以安裝 eslint-config-google 這個套件。

但這篇會主要介紹 Airbnb 的規範,因此我們就先安裝 eslint-config-airbnb-base 這個套件。

修改 .eslintrc.cjs

接著我們來修改 .eslintrc.cjs 檔案,目前預設設定檔案如下

1
2
3
4
5
6
7
8
9
10
11
/* eslint-env node */
module.exports = {
root: true,
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended'
],
parserOptions: {
ecmaVersion: 'latest'
}
}

那麼為了讓 ESLint 支援 Airbnb 的規範,我們需要修改成下面這樣

1
2
3
4
5
6
7
8
9
10
11
12
13
/* eslint-env node */

module.exports = {
root: true,
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'airbnb-base',
],
parserOptions: {
ecmaVersion: 'latest',
},
};

如果是 Standard 規範,就只需要將 airbnb-base 改成 standard 即可。

這邊要注意 extends 的順序,因為 ESLint 會依照順序去檢查規範,所以我們需要把 airbnb-base 放在最後面,這樣才能確保 ESLint 會先檢查 Vue3 的規範,再來才是 Airbnb 的規範,反之如果我們把 airbnb-base 放在最前面,那麼 ESLint 會先檢查 Airbnb 的規範,再來才是 Vue3 的規範,這樣就會造成 ESLint 會噴錯。

而這一點也可以參照 Vue Cli 的專案怎麼放

1
2
3
4
5
6
7
8
9
10
module.exports = {
root: true,
extends: [
'plugin:vue/vue3-essential',
'@vue/airbnb',
],
parserOptions: {
ecmaVersion: 'latest',
},
};

可以看到 Vue Cli 的專案是把 @vue/airbnb 放在最後面,這樣就能確保 ESLint 會先檢查 Vue3 的規範,再來才是 Airbnb 的規範。

題外話一下 @vue/airbnb 是 Vue 針對 Airbnb 的規範做了一些調整,如果你不想要使用 @vue/airbnb,也可以直接使用 airbnb-base,但是你可能要花很多時間去調整規範。

到目前為止,我們已經把 ESLint 設定好了,接下來我們就來測試一下看看 ESLint 是否有正常運作,讓我們打開 main.js 檔案,你應該會看到一大推的紅字都是關於「Missing semicolon.eslint

eslint

有沒有一種熟悉的紅字最對味的感覺?這邊我也提供「VSCode 自動修正 ESLint 錯誤」的文章,讓你可以快速修正 ESLint 的錯誤。

接著你也可以打開 App.vue,然後刻意刪除 template 的裡面的東西,並且刻意宣告一些沒有使用的變數驗證是否正常運作

ESLint

安裝 eslint-import-resolver-alias

接著由於 Airbnb 較嚴格的關係,所以我們要安裝 eslint-import-resolver-alias 這個套件,而這個套件主要用途在於讓 ESLint 可以正常解析 @ 的路徑,因為我們在 vite.config.js 裡面有設定 @ 的路徑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { fileURLToPath, URL } from 'node:url';

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
});

所以如果你不安裝這個套件的話,那麼 ESLint 是會發生錯誤,如以下這一段程式碼就會出現錯誤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script setup>
import { RouterLink, RouterView } from 'vue-router';
import HelloWorld from '@/components/HelloWorld.vue'; // Unable to resolve path to module '@/components/HelloWorld.vue'.eslint(import/no-unresolved)
</script>

<template>
<header>
<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />

<div class="wrapper">
<HelloWorld msg="You did it!" />

<nav>
<RouterLink to="/">Home</RouterLink>
<RouterLink to="/about">About</RouterLink>
</nav>
</div>
</header>

<RouterView />
</template>

接著請替專案安裝 eslint-import-resolver-alias 套件

1
npm install --save-dev eslint-import-resolver-alias

接著打開 .eslintrc.cjs,並且在 extends 的下面新增 settings,並且在 settings 裡面新增 import/resolver,最後在 import/resolver 裡面新增 alias,並且在 alias 裡面新增 mapextensions,如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* eslint-env node */

module.exports = {
root: true,
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'airbnb-base',
],
parserOptions: {
ecmaVersion: 'latest',
},
settings: {
'import/resolver': {
alias: {
map: [
['@', './src'],
],
extensions: ['.js', '.vue'],
},
},
},
};

接著你在打開剛剛噴錯的 App.vue,你會發現 ESLint 會正常運作了

ESLint

安裝 eslint-plugin-import

eslint-plugin-import 是一個專門給 ESLint 的套件,因為我這邊所使用的規範是 Airbnb,所以這個套件是必須要安裝的,而這個套件主要是用來檢查 import 的相關規範,例如:import 的順序、import 的檔案是否存在等等

1
npm install --save-dev eslint-plugin-import

如果你沒有安裝的話,那麼你就有可能遇到這類錯誤訊息

1
The plugin "eslint-plugin-import" was referenced from the config file in ".eslintrc.cjs » eslint-config-airbnb-base » /home/runner/work/project-name/project-name/node_modules/eslint-config-airbnb-base/rules/imports.js".

所以如果你遇到這類型錯誤訊息時,只需要安裝 eslint-plugin-import 即可。

解決 vite.config.js 錯誤

接下來你打開 vite.config.js 會出現一段很奇妙的錯誤

‘vite’ should be listed in the project’s dependencies, not devDependencies. eslint(import/no-extraneous-dependencies)
‘@vitejs/plugin-vue’ should be listed in the project’s dependencies, not devDependencies. eslint(import/no-extraneous-dependencies)

vite.config.js

而這個錯誤非常的奇怪,因為官方所提供的 Vite 預設環境下這兩個套件就是安裝在 devDependencies 裡面,因此我們要做的事情就是告訴 ESLint 這兩個套件是可以安裝在 devDependencies 裡面的。

接著打開 .eslintrc.cjs,並且在 settings 裡面新增 import/core-modules,並且在 import/core-modules 裡面新增 vite@vitejs/plugin-vue,如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/* eslint-env node */

module.exports = {
root: true,
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended',
'airbnb-base',
],
parserOptions: {
ecmaVersion: 'latest',
},
settings: {
'import/resolver': {
alias: {
map: [
['@', './src'],
],
extensions: ['.js', '.vue'],
},
},
'import/core-modules': [
'vite',
'@vitejs/plugin-vue',
],
},
};

接著你在打開 vite.config.js,你會發現 ESLint 會正常運作了

vite.config.js

import/core-modules 的用途是告訴 ESLint 這些套件是可以安裝在 devDependencies 裡面的,而不是 dependencies 裡面。

範例程式碼

接著底下這邊我也提供一下我所準備好的範例程式碼,如果你有興趣的話可以參考一下