Webサイト制作でトランスパイル環境のない生のJavaScriptを書く機会があり、そこそこ古いバージョンのブラウザでも動くようにLintでコードチェックできたらなーと思って調べてみました。導入手順とかんたんな使い方を紹介します。
環境
- Node.js v20
- VS Code v1.82
TL;DR
国内シェア1%以上、かつES6サポートのブラウザをターゲットとした例:
{
"scripts": {
"lint": "eslint .; exit 0"
},
"devDependencies": {
"eslint": "^8.51.0",
"eslint-plugin-compat": "^4.2.0"
},
"browserslist": [
">= 1% in JP and not dead"
]
}
module.exports = {
env: {
browser: true,
},
extends: ["eslint:recommended", "plugin:compat/recommended"],
overrides: [
{
env: {
node: true,
},
files: [".eslintrc.{js,cjs}"],
parserOptions: {
sourceType: "script",
},
},
],
parserOptions: {
ecmaVersion: 6,
sourceType: "module",
},
rules: {},
plugins: ["compat"],
settings: {
polyfills: [],
},
};
セットアップ
package.jsonを作成します。
npm init -y
ESLintをセットアップします。
npm init @eslint/config
✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · none
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser
✔ What format do you want your config file to be in? · JavaScript
Local ESLint installation not found.
The config that you've selected requires the following dependencies:
eslint@latest
✔ Would you like to install them now? · No / Yes
✔ Which package manager do you want to use? · npm
ESLintのプラグインをインストールします。
npm install -D eslint-plugin-compat
- 参考)ESLintのセットアップ https://eslint.org/docs/latest/use/getting-started
- 参考)プラグインのインストール https://github.com/amilajack/eslint-plugin-compat
CLIでかんたんにLintが呼び出せるようにスクリプトを追加しておきましょう。
"scripts": {
"lint": "eslint .; exit 0"
}
VS Codeエクステンションの追加もオススメします。コードを書くとリアルタイムでチェックが実行されます。
ターゲットを決める
すでに公開済みのサイトであれば、Googleアナリティクスなどを参考にアクセスの多いブラウザやバージョンの目処をつけておきます。
これから公開するサイトであれば、主要なブラウザの最新5バージョンなど制作者サイドでルールを決めるのも良いでしょう。
以降、サイトの訪問を意図したブラウザおよびバージョンを「ターゲット」と記載します。
APIのチェック
Browserslistのサイトで、ターゲットに該当するブラウザとバージョンを確認してみましょう。
最新5バージョンをターゲットとした例:
last 5 versions and not dead
特定のブラウザをターゲットとした例:
Chrome >= 116 or FireFox >= 115
not dead
は過去1年間にアップデートされたブラウザのみ対象とします。これを指定しておくと、サポート終了してもなお使われ続けているブラウザを除外できます。
コードベース上のターゲット指定はpackage.jsonで行います。
ここではシェア1%以上をターゲットとしました。
"browserslist": [
">= 1% and not dead"
]
ESLintプラグイン「eslint-plugin-compat」を有効化します。
このプラグインはターゲット指定を読み込んでサポートしていないAPIをエラーとして検出します。
extends: [
"eslint:recommended",
"plugin:compat/recommended"
],
plugins: ["compat"],
任意のファイルを作成して、試しにfetchAPIを使ってみましょう。
VSCodeエクステンションによりリアルタイムでエラーが検出されます。
CLIでは以下のようにエラーが検出されます。
記事執筆時点のシェア1%にはOperaモバイル版の「Opera Mini」が含まれ、これがfetchAPIをサポートしていません。 in JP
を追加して国内シェアに絞り込んでみましょう。
"browserslist": [
">= 1% in JP and not dead"
]
Opera Miniは国内シェアが低いためターゲットから外れ、エラーは検出されなくなりました。
サイトのターゲットとするべきブラウザやバージョン、それらがサポートするAPI群を記憶しておくことは、人間にとってとんでもなく困難です。Lintでチェックできるなんて最高に便利ですね!
ここでひとつ注意事項があります。
「eslint-plugin-compat」はグローバルに存在するAPI(URLSearchParamsオブジェクトや、fetch関数など)をチェックしてくれますが 言語構文(letやスプレッド構文など)についてはチェックしない ようです。理由についてissueの中で「トランスパイルできるものは対応の優先度が低いから」と述べられています。
https://github.com/amilajack/eslint-plugin-compat/issues/454
試しにオプショナルチェーンを使ってみても、エラーは何も検出されません。
言語構文のチェック
言語構文についてはESLintの設定の中でECMAScriptレベルの指定ができます。browserslistの指定とはリンクしませんが、これだけでも大きな助けとなります。
デフォルトの設定は比較的新しいものになっているので、ES6レベルに下げてみましょう。
env: {
browser: true,
},
...
parserOptions: {
ecmaVersion: 6,
...
},
- 参考)ESLint https://eslint.org/docs/latest/use/configure/language-options#using-configuration-files
- 参考)サバイバルTypeScript https://typescriptbook.jp/tutorials/eslint#parseroptions
オプショナルチェーンはES2020で導入された構文です。ES6では解釈できずパースエラーとして検出されるようになりました。
CLIでも同じエラーが検出されます。
おまけ
eslint-plugin-compatに付随してインストールされる「browserslist」コマンドを叩くと、ターゲットのブラウザとバージョンがリスト表示されます。User Agent Client Hintsと組み合わせてサイト訪問者にブラウザアップデートの補足を表示するなど活用できそうですね。
./node_modules/.bin/browserslist
> and_chr 117
> chrome 117
> chrome 116
> edge 117
> edge 116
> firefox 117
> ios_saf 17.0
> ios_saf 16.6
> safari 16.6
おわりに
思い出せばAPIをひとつずつ Can I use で調べながらコードを書いていた時代もありましたが、機械的なチェックが格段に進化を遂げていて衝撃的でした。ESLintやプラグイン開発者の方々に感謝です!