🌊

Ionic Angularプロジェクトで便利なESLintルールをプラグインにしてリリースしました🎉

2023/04/27に公開

概要

@rdlabo/eslint-plugin-rules をリリースしました🎉
私はIonicとAngularを使ってアプリを作っていますが、その際に必要になったESLintルールをプラグインにまとめました。一部機能についてはまじで仕事の効率化半端なかった。大きなアプリケーションだと2日3日を覚悟しないといけないマイグレーション作業が一瞬で終わりました。ばんざい!

使い方

  • @angular/core >= 15 を想定しています。14でも動くと思いますが、13だと動きません。
  • @angular-eslint パッケージ群をプロジェクトに適用してる必要があります。まだの場合は、 こちら を参考にインストールしてください。
  • prettier を使ってる人は、prettier も最新版にしておいてください。prettier が古いと、 ジェネリック型つきのオブジェクトを inject するところでエラーがでます。

インストール

% npm install @rdlabo/eslint-plugin-rules --save-dev

設定

.eslintrc* に以下のように設定してください。ここではおすすめの設定にしていますが、もちろん使わないものは使わなくて大丈夫です。

json
  {
    ...
+   "plugins": ["@rdlabo/rules"],
    "overrides": [
      {
        "files": [
          "*.ts"
        ],
      ...
        "rules": {
+         "@rdlabo/rules/deny-constructor-di": "error",
+         "@rdlabo/rules/import-inject-object": "error",
        }
      },
      {
        "files": [
          "*.html"
        ],
        "rules": {
+         "@rdlabo/rules/deny-element": [
+           "error",
+           {
+             "elements": [
+               "ion-modal",
+               "ion-popover",
+               "ion-toast",
+               "ion-alert",
+               "ion-loading",
+               "ion-picker",
+               "ion-action-sheet"
+             ]
+           }
+         ]
          ]
        }
      }
    ]
  }

ルール一覧

@rdlabo/rules/deny-constructor-di

Angular 14から導入された inject 関数に移行するためのルールです。 constructor でのDIから移行する時にご利用ください。現状ではどちらも使えますが、以下の記事を読むと移行したくなりますよ!

https://zenn.dev/lacolaco/articles/why-inject-function-wins

移行前: constructor でDIするとエラーになります。

@Component({
  selector: 'app-confirm',
  templateUrl: './confirm.page.html',
  styleUrls: ['./confirm.page.scss'],
})
export class SigninPage {
  constructor(public platform: Platform) {} // Error: Do not use constructor DI.
}

移行後: inject 関数を使います。

@Component({
  selector: 'app-confirm',
  templateUrl: './confirm.page.html',
  styleUrls: ['./confirm.page.scss'],
})
export class SigninPage {
  public readonly platform = inject(Platform); // OK

  constructor() {}
}

このルールはauto fixに対応しているので、 npm run lint -- --fix で自動的に移行が完了します。上記でいえばこういった差分が自動的に生成されます。

ts
    @Component({
      selector: 'app-confirm',
      templateUrl: './confirm.page.html',
      styleUrls: ['./confirm.page.scss'],
    })
    export class SigninPage {
-     constructor(public platform: Platform) {}
+     public readonly platform = inject(Platform); // OK
+
+     constructor() {}
    }
ts
    @Component({
      selector: 'app-confirm',
      templateUrl: './confirm.page.html',
      styleUrls: ['./confirm.page.scss'],
    })
    export class SigninPage {
-     constructor(
-       public platform: Platform,
-       private store: Store<IApp>,
-       private navCtrl: NavController,
-       public helper: HelperService,
-     ) {}      
+     public readonly platform = inject(Platform);
+     private readonly store = inject(Store<IApp>);
+     private readonly navCtrl = inject(NavController);
+     public readonly helper = inject(HelperService);
+     
+     constructor() {}
    }

大きなプロジェクトだと100を超えるファイル、数千のDIがあるのでそれを手作業で修正するのは現実的ではありません。死ねる。自動化で楽をしましょう!

@rdlabo/rules/import-inject-object

inject 関数を使ってるのに、インポートしてないとエラーになります。上の @rdlabo/rules/deny-constructor-di のauto fixで inject 関数のインポートの生成を行うのが難しかったので分離しました。npm run lint -- --fix で自動的にインポートが生成されます。

ts
+   import { inject } from '@angular/core';

    @Component({
      selector: 'app-confirm',
      templateUrl: './confirm.page.html',
      styleUrls: ['./confirm.page.scss'],
    })
    export class SigninPage {
      public readonly platform = inject(Platform);
    }
ts
-   import { Component } from '@angular/core';
+   import { Component, inject } from '@angular/core';

    @Component({
      selector: 'app-confirm',
      templateUrl: './confirm.page.html',
      styleUrls: ['./confirm.page.scss'],
    })
    export class SigninPage {
      public readonly platform = inject(Platform);
    }

@rdlabo/rules/deny-element

Ionic6 から、インラインでのModalやActionSheetがサポートされました。私の参画してるプロジェクトでは、Controllerでの生成に統一してるので、間違ってインラインで生成しないようにするためにルールをつくりました。他にも特定のHTML要素を禁止したい場合にも使えます。

{
  "rules": {
    "@rdlabo/rules/deny-element": [
      "error",
      {
        "elements": ["ion-modal"]
      }
    ]
  }
}
<ion-modal></ion-modal><!-- エラーになります -->

まとめ

開発において「がんばる」「気をつける」はどうしてもつらみがましていくので、ルール化して自動化することで、開発者の負担を減らすことができます。ぜひご利用ください。そして、使って楽できた!!という方は、また酒でも奢ってください(笑)

Discussion