Firebase Functions でTSLintではなくTypeScript ESLint + Prettierを使う場合の設定例

TSLintが非推奨なので、Cloud Functions for FirebaseでTypeScriptを使う場合に、
リンターにTypeScript ESLint、コードフォーマッターにPrettierを設定する例です。
毎回やるので備忘録としてまとめます。


# プロジェクトの作成
Firebase 初期化時にFunctionsの言語を`TypeScript`に。TSLintを`No`に設定します。

```
firebase init
..
? What language would you like to use to write Cloud Functions? TypeScript
? Do you want to use TSLint to catch probable bugs and enforce style? No
...
```

以下すべての設定は、初期化時に作成された`./functions`のディレクトリで行います。

# ESLintの設定

ESLintを追加します。

```
npx eslint --init
```

初期設定への回答は下記のように答えました。

```
? How would you like to use ESLint? To check syntax and find problems
? What type of modules does your project use? JavaScript modules (import/export)
? Which framework does your project use? None of these
? Does your project use TypeScript? Yes
? Where does your code run? Node
? What format do you want your config file to be in? JSON
```

# Prettierの設定

続いてPrettierを設定します。

```
npm i --save-dev prettier eslint-config-prettier eslint-plugin-prettier
```

ESLintの設定で自動生成された`.eslintrc.json`にPrettierの設定を追記します。

```diff:.eslintrc.json
{
    "env": {
        "node": true,
        "es6": true
    },
    "extends": [
        "eslint:recommended",
+       "plugin:@typescript-eslint/eslint-recommended",
+       "plugin:@typescript-eslint/recommended",
+       "plugin:prettier/recommended"
    ],
    "globals": {
        "Atomics": "readonly",
        "SharedArrayBuffer": "readonly"
    },
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaVersion": 2018,
        "sourceType": "module"
    },
    "plugins": [
        "@typescript-eslint"
    ]
}
```

# `import/prefer-default-export`をOFFに設定
このままで、初期の関数をチェックすると、`import/prefer-default-export`でerrorとなります。
こちらは、一つのファイルでexportする関数がひとつの場合は`export default`の使用を強制するルールです。
Firebase Functionsの場合は名前付きexportが使用されるので、こちらをOFFにします。

`.eslintrc.json`を以下のように修正します。

```diff:.eslintrc.json
{
    "env": {
        "node": true,
        "es6": true
    },
    "extends": [
        "eslint:recommended",
       "plugin:@typescript-eslint/eslint-recommended",
       "plugin:@typescript-eslint/recommended",
       "plugin:prettier/recommended"
    ],
    "globals": {
        "Atomics": "readonly",
        "SharedArrayBuffer": "readonly"
    },
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
        "ecmaVersion": 2018,
        "sourceType": "module"
    },
    "plugins": [
        "@typescript-eslint"
    ],
+   "rules": {
+       "import/prefer-default-export": "off"
+   }
}
```

# `package.json`にLintのscriptを追記
毎回コマンドで指定するのが面倒なので、scriptを設定します。
`package.json`に以下のように修正します。

```diff:package.json
{
  "name": "functions",
  "scripts": {
    "build": "tsc",
    "serve": "npm run build && firebase serve --only functions",
    "shell": "npm run build && firebase functions:shell",
    "start": "npm run shell",
    "deploy": "firebase deploy --only functions",
    "logs": "firebase functions:log",
+   "lint": "eslint ./src/**/*.{js,ts} --fix"
  },
  "engines": {
    "node": "10"
  },
...
```

これでnpm scriptsでESLintを実行できます。

```
npm run lint
```

# 終わりに

以上、Firebase Functions でTSLintではなくTypeScript ESLint + Prettierを使う場合の設定例でした。
標準でTSLintではなくESLint TypeScriptに対応してくれると良いな。