⚠️

Next.jsで使える機能を制限するESLintプラグイン(eslint-plugin-no-next-restricted)を作ってみた

に公開

先日、こちらのESLint Pluginを作成したのでご紹介します。

https://www.npmjs.com/package/eslint-plugin-no-next-restricted

実装したLintルール

以下の2つのLintルールを実装しています。

作ろうと思った背景

Fastly IO(Image Optimizer)imgixを使用して画像の最適化を行なっているサービスでは、next/imageを使用する意味がないため、使用を制限したいケースがあります。また、Server Side RenderingをしているページをCDNでキャッシュしている場合や、一部のページだけでNext.jsを使用している場合に、next/linkの使用を制限したいケースもあります。

参考記事
https://hack.nikkei.com/blog/denshiban-ssr/

https://speakerdeck.com/apple_yagi/pr-timesniokerunext-dot-jstocachenofu-kihe-ifang

このような背景から、Next.jsのnext/imageおよびnext/linkの使用を制限するESLint Pluginを作成しました。

eslint-plugin-no-next-restrictedの実装コードの推しポイント

ここからは本Pluginを実装した時の推しポイントについて紹介します。

node --experimental-strip-types --test

Unitテストを実行する時にnode --experimental-strip-types --testを使用し、TypeScriptのコードをNode.js組込みのテストランナーで実行しています。これにより、VitestやJestを入れずにテストを回すことができます。

https://github.com/apple-yagi/eslint-plugin-no-next-restricted/blob/6caac9090a6bc5677f786c4685599b785aa2ff83/package.json#L13

注意点として、Node.jsでTypeScriptを直接実行するにはtsconfig.jsonの設定でallowImportingTsExtensionsを有効にしたりする必要があります。今回はnpmに公開するためにTypeScriptのコードをtscでJavaScriptにトランスパイルする必要があったため、rewriteRelativeImportExtensionsを有効にしました。

https://github.com/apple-yagi/eslint-plugin-no-next-restricted/blob/6caac9090a6bc5677f786c4685599b785aa2ff83/tsconfig.json#L13

ただこのオプションは特定のケースでバグが発生するため、注意が必要です(参考↓)。

https://zenn.dev/uhyo/articles/rewrite-relative-import-extensions-read-before-use

今回はとてもミニマムな開発だったため、試しに使用しています。

LintルールのUnitテスト方法

実装したLintルールのUnitテストを作成する際にmizdraさんが開発しているcss-modules-kitのeslint-pluginを参考にしました。

https://github.com/mizdra/css-modules-kit/tree/main/packages/eslint-plugin/src/rules

no-next-imageのテストコード↓

https://github.com/apple-yagi/eslint-plugin-no-next-restricted/blob/6caac9090a6bc5677f786c4685599b785aa2ff83/src/rules/no-next-image.test.ts#L1-L48

ESLintの公式ドキュメントではRuleTesterを使用してテストを書く例が紹介されていますが、上記のテスト方法の方がdescribeなどを使うことができ、普段書いているUnitテストと同じように書くことができるため、好きです。

https://eslint.org/docs/latest/contribute/tests

おわりに

Next.jsは多機能なオールインワンフレームワークですが、業務では使用を避けたい機能もあります。今回作成したESLint Pluginによって、Next.jsへの依存をコントロールし、将来のメンテナンス性を向上させたいところです。

Discussion