Nuxt3 から eslint を使おう

# はしがき

typescript を導入しましたし、開発効率（github PR の時間短縮、lint で自己反省ができるので）をあげるために、ESLint も使うようにしました。

`package.json` や `nuxt.config.ts`、git の履歴を確認したら、5年まえ、うちのプロジェクトは少し eslint を使っていた気がしました。

単純に module upgrade と code migration をしたら、使えるとおもいましたが、ある module は deprecated になったり、ある module は version によって、ほかの module と conflict になったりしました。

「今まで使っていなかったし、eslint が8から9になって、config file の extension も変わったし、やり直してみるか？」とおもって、最初からやりなおしました。

# Lint はなに？

```
Lint is the computer science term for a static code analysis tool used to flag programming errors, bugs, stylistic errors and suspicious constructs.
```

コードのエラー、bug、スタイルなど疑問がある部分に flag をつけること、もしくは、このような機能のプログラムを linter といいます。

これは言語 C のソースコードをチェックする Unix Utility をもとしました。

# ESLint はなに？

https://eslint.org/

```
ESLint is an open source project that helps you find and fix problems with your JavaScript code.
It doesn't matter if you're writing JavaScript in the browser or on the server, with or without a framework.
```

ECMA script + lint、javascript むけの lint です。

# migration の方法

## 最初

最初自分がチェックした状態は以下でした。

```javascript
// package.json
{
  "scripts": {
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore."
  },
  ...
  "devDependencies": {
    "eslint": "^5.0.1",
    "babel-eslint": "^8.2.1",
    "eslint-config-vue": "^8.0.0",
    eslint-config-prettier: "^3.1.0"
  }
}
```

```javascript
// .eslint.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
  },
  parseOptions: {
    parser: 'babel-parser'
  },
  extends: [
    'standard',
    'plugin:vue/vue-recommended'
  ],
  plugins: [
    'vue',
    'prettier'
  ],
  rules: {
    ...
  }
}
```

なんで、5.0.1... 幸いに？5年前作られて、いまは全然使っていない状態でした。

rules とか config modules も結構使っていたので、かくの module の npm や github に入って、deprecated したことを確認しながら、変更しました。

https://eslint.vuejs.org/rules/#removed
https://eslint.org/docs/latest/use/migrating-to-6.0.0
https://eslint.org/docs/latest/use/migrating-to-7.0.0
https://eslint.org/docs/latest/use/migrate-to-8.0.0
https://eslint.org/docs/latest/use/migrate-to-9.0.0

## 5 -> 9 の migration をしてみよう！

```javascript
// package.json
{
  "scripts": {
    "lint": "eslint"
  },
  ...
  "devDependencies": {
    "eslint": "^9.0.0",
    "@babel/eslint-parser": "^7.24.5",
    "eslint-config-vue": "^9.0.0",
    "eslint-config-prettier": "^3.1.0"
  }
}
```

eslint の `--ignore-path` は `v9.0.0` 以前はある file を読んで使える気がしますが、`v9.0.0` になって、使えなくなりました。

https://eslint.org/docs/latest/use/configure/ignore

それ代わりに、config file に全部記入すべきらしいです。

babel-eslint（`babel-parser`） は deprecated になったので、`@babel/eslint-parser`と変更しました。

https://www.npmjs.com/package/babel-eslint

```javascript
// .eslint.js -> eslint.config.js
import babelEslintParser from '@/babel/eslint-parser'
import pluginVue from 'eslint-plugin-vue'
import eslintConfigPrettier from 'eslint-config-prettier'

export default [
  {
    ignores: ['**/node_modules', ...], // .gitignore を全部書き込みました。
    files: ['**/*.js', '**/*.vue'],
    languageOptions: {
      parser: babelEslintParser,
    },
    plugins: {
      vue: pluginVue,
      prettier: eslintConfigPrettier
    },
    ...pluginVue.configs('flat/recommend'),
    rules: { ... }
  }
]
```

`v9.0.0` から、`eslint.config.js` を使うようになったので、file を変更しました。
また、commonJs -> es6 への書き方が変更しましたので、export の書き方も変更しました。

https://eslint.org/docs/latest/use/configure/configuration-files

ignore はこれでできそうですが、eslint 導入するとき確認しなかったので、`.gitignore` を全部カピペーしました。

https://eslint.org/docs/latest/use/configure/ignore#including-gitignore-files

eslint をアップグレードしましたし、config file が変更しましたので、eslint-plugin-vue の書き方も変更しました。

https://eslint.vuejs.org/user-guide/#configuration-eslint-config-js

幸いか rules には deprecated されたことがなかったので、変更しませんでした。

## テストしてみた

```javascript
// project_path_folder/test.js
const helloWorld = "hello world!"
```

これだけでは「この変数はどこでも使われません」というエラーがでるはずです。

これで、ちゃんとできるか！terminal から試してみましたが、失敗しました。
あのときのエラーログをのこせずにしましたので...たぶん、vite と parser が conflict している状態でした。

nuxt3 になって、vite を使っていたし、babel parser をどのぐらい触ったらいいか、わからない状態でした。

## 最初から使用 + nuxt のおすすめ！

上司と相談しながら、得た結論ですが、５年前作って、今はだれも使っていなかったら、全部消して、最初から作ったら？

ということです。

また、nuxt からの official module があるので、それを確認しました。

https://nuxt.com/modules/eslint

`@nuxt/eslint` を install した、build するとき、作られる `project_path/.nuxt/.eslint.config.mjs` を参考しながら、既存の config も使えるような気がしました。

まず、eslint に関連した module を全部削除しました。

```bash
$ yarn remove eslint関連module...

$ yarn add -D @nuxt/eslint eslint
```

```javascript
// package.json
{
  "scripts": {
    "lint": "eslint"
  },
  ...
  "devDependencies": {
    "eslint": "^9.0.0",
    "@nuxt/eslint": "^0.3.13"
  }
}
```

それで、以下の公式のように試してみました。

https://eslint.nuxt.com/packages/module

```javascript
// eslint.config.js
import withNuxt from './.nuxt/eslint.config.mjs'

export default defineNuxtConfig({
  modules: [
    '@nuxt/eslint'
  ],
  eslint: {
    // options here
  }
})
```

```bash
$ yarn run lint
=> ./project_path_folder/test.js
Error:   1:7  error  'helloWorld' is assigned a value but never used  no-unused-vars
```

できました！それではさっさともともとも設定を追加してみましょうか。

```javascript
// package.json
{
  "scripts": {
    "lint": "eslint"
  },
  ...
  "devDependencies": {
    "eslint": "^9.0.0",
    "@nuxt/eslint": "^0.3.13",
    "eslint-config-vue": "^9.0.0",
    "eslint-config-prettier": "^3.1.0"
  }
}
```

`@babel/eslint-parser` はエラーになったので、抜けました。

```javascript
// eslint.config.js
import withNuxt from './.nuxt/eslint.config.mjs'
import eslintConfigPrettier from 'eslint-config-prettier'

export default defineNuxtConfig([
  {
    rules: { ... }
  },
  eslintConfigPrettier
]).prepend([
  {
    ignores: ['nuxt.config.ts']
  }
])
```

nuxt eslint なので基本的に vue と js, ts は検知して lint。
この project は無視する js, ts, vue は config file のみ
config file を優先して、むししますので、config customize

https://eslint.nuxt.com/packages/module#config-customizations

rules はもとのことをカピペー

nuxt が公式で支援しますので、結構簡単に実装できました。

# 参考&関連 URL

https://eslint.org/docs/latest/use/getting-started

https://nuxt.com/modules/eslint

https://eslint.nuxt.com/packages/module