ESLint で Global 変数を正しく扱う方法

ESLint でコードを書いていると、突然「'console' is not defined
」や「'window' is not defined
」というエラーに遭遇して、「あれ?これって普通に使えるはずなのに...」と困惑した経験はありませんか?
実は、これらのエラーは ESLint がグローバル変数を認識していないことが原因です。今回は、ESLint でグローバル変数を正しく扱う方法について、実際のエラーケースから解決策まで詳しく解説していきます。
背景
ESLint が厳格な理由
ESLint は、JavaScript の静的解析ツールとして、コードの品質を保つために非常に厳格なルールを適用します。特に、未定義の変数の使用は重大なバグの原因となるため、デフォルトで厳しくチェックされます。
しかし、JavaScript 開発では避けて通れないのがグローバル変数の存在です。ブラウザ環境ではwindow
、document
、console
などが、Node.js 環境ではprocess
、global
、Buffer
などが標準で利用できますが、これらは ESLint にとっては「どこからともなく現れた未定義の変数」として認識されてしまいます。
開発現場での実際の困りごと
多くの開発者が経験する典型的な困りごとをご紹介しましょう。
javascript// ブラウザ環境でのよくあるコード
console.log('デバッグ情報'); // ESLintエラー!
window.location.href = '/login'; // ESLintエラー!
document.getElementById('app'); // ESLintエラー!
// Node.js環境でのよくあるコード
process.env.NODE_ENV; // ESLintエラー!
global.myGlobalVar = 'test'; // ESLintエラー!
このような基本的なコードでエラーが発生すると、開発の流れが止まってしまい、非常にストレスフルな体験となります。
課題
実際に発生するエラーコード
ESLint でグローバル変数を使用した際に発生する代表的なエラーコードをご紹介します。これらのエラーコードを覚えておくと、問題の特定が素早く行えます。
no-undef エラー
最も頻繁に遭遇するエラーです。
javascript// エラーコード例
console.log('Hello World');
bash1:1 error 'console' is not defined no-undef
no-global-assign エラー
グローバル変数を再代入しようとした際に発生します。
javascript// エラーコード例
window = {};
bash1:1 error Read-only global 'window' should not be modified no-global-assign
no-implicit-globals エラー
スクリプトファイルでグローバル変数を作成する際に発生します。
javascript// エラーコード例
var myGlobalVar = 'test';
bash1:1 error Implicit global variable, assign as global property instead no-implicit-globals
開発者が陥りがちな対処法の問題点
多くの開発者が最初に試す対処法には、実は問題があります。
問題のある対処法 1: エラーの無視
javascript// 悪い例:エラーを無視するだけ
/* eslint-disable no-undef */
console.log('Hello World');
これは根本的な解決にならず、本当に未定義の変数を使った場合のエラーも見逃してしまいます。
問題のある対処法 2: 無制限なグローバル許可
javascript// 悪い例:すべてのグローバル変数を許可
/* global console, window, document, process, global, Buffer */
必要以上にグローバル変数を許可すると、タイポや実際の未定義変数の検出ができなくなります。
解決策
1. env(環境)設定による解決
最も推奨される解決方法は、ESLint のenv
設定を使用することです。これにより、特定の環境で利用可能なグローバル変数を一括で許可できます。
.eslintrc.js での設定
javascriptmodule.exports = {
env: {
browser: true, // ブラウザ環境のグローバル変数を許可
node: true, // Node.js環境のグローバル変数を許可
es2021: true, // ES2021のグローバル変数を許可
},
// その他の設定...
};
この設定により、以下のグローバル変数が自動的に認識されます:
環境設定 | 利用可能になるグローバル変数(例) |
---|---|
browser | window, document, console, alert, confirm |
node | process, global, Buffer, **dirname, **filename |
es2021 | Promise, Symbol, Map, Set, WeakMap |
package.json での設定
json{
"eslintConfig": {
"env": {
"browser": true,
"node": true,
"es2021": true
}
}
}
2. globals 設定による個別対応
特定のグローバル変数のみを許可したい場合は、globals
設定を使用します。
読み取り専用グローバル変数の設定
javascriptmodule.exports = {
globals: {
console: 'readonly', // 読み取り専用で許可
window: 'readonly', // 読み取り専用で許可
document: 'readonly', // 読み取り専用で許可
process: 'readonly', // 読み取り専用で許可
},
// その他の設定...
};
書き込み可能なグローバル変数の設定
javascriptmodule.exports = {
globals: {
myGlobalVar: 'writable', // 書き込み可能で許可
APP_CONFIG: 'writable', // 書き込み可能で許可
},
// その他の設定...
};
3. TypeScript 環境での対応
TypeScript 環境では、型定義の問題も考慮する必要があります。
@typescript-eslint/parser の設定
javascriptmodule.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 2021,
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
env: {
browser: true,
node: true,
es2021: true,
},
// その他の設定...
};
TypeScript 用のグローバル変数定義
typescript// globals.d.ts
declare global {
interface Window {
myCustomProperty: string;
}
var myGlobalFunction: () => void;
}
export {};
4. インラインコメントによる部分的対応
特定の行でのみグローバル変数を使用する場合は、インラインコメントを使用します。
単一行での対応
javascript/* global console */
console.log('Hello World');
複数行での対応
javascript/* global console, window, document */
console.log('Hello World');
window.location.href = '/login';
document.getElementById('app');
eslint-disable-next-line の使用
javascript// eslint-disable-next-line no-undef
console.log('Hello World');
具体例
React + TypeScript プロジェクトでの設定例
React + TypeScript 環境でよく使用される設定をご紹介します。
.eslintrc.js の完全な設定例
javascriptmodule.exports = {
env: {
browser: true,
es2021: true,
node: true,
jest: true,
},
extends: [
'eslint:recommended',
'@typescript-eslint/recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12,
sourceType: 'module',
},
plugins: ['react', '@typescript-eslint'],
globals: {
React: 'readonly',
JSX: 'readonly',
},
rules: {
'no-undef': 'error',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': 'error',
},
};
対応する package.json の dependencies
json{
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.0.0",
"eslint-plugin-react": "^7.32.0",
"eslint-plugin-react-hooks": "^4.6.0"
}
}
この設定により、以下のコードがエラーなく動作します:
typescript// ブラウザ環境のグローバル変数
console.log('デバッグ情報');
window.location.href = '/dashboard';
document.title = 'My App';
// React関連のグローバル変数
const App: React.FC = () => {
return <div>Hello World</div>;
};
Node.js + Express プロジェクトでの設定例
Node.js 環境でのサーバーサイド開発における設定例です。
.eslintrc.js の設定
javascriptmodule.exports = {
env: {
node: true,
es2021: true,
commonjs: true,
},
extends: ['eslint:recommended'],
parserOptions: {
ecmaVersion: 12,
sourceType: 'module',
},
globals: {
__dirname: 'readonly',
__filename: 'readonly',
exports: 'writable',
module: 'writable',
require: 'readonly',
},
rules: {
'no-undef': 'error',
'no-unused-vars': 'error',
},
};
動作確認用のコード例
javascript// Node.js環境のグローバル変数
console.log('サーバー起動中...');
console.log('現在のディレクトリ:', __dirname);
console.log('Node.js バージョン:', process.version);
// Express の設定
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`サーバーがポート ${PORT} で起動しました`);
});
Next.js プロジェクトでの環境別設定
Next.js プロジェクトでは、サーバーサイドとクライアントサイドで異なるグローバル変数が必要となります。
.eslintrc.js の設定
javascriptmodule.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: ['eslint:recommended', 'next/core-web-vitals'],
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12,
sourceType: 'module',
},
globals: {
React: 'readonly',
JSX: 'readonly',
},
overrides: [
{
files: [
'pages/**/*.js',
'pages/**/*.ts',
'pages/**/*.tsx',
],
env: {
browser: true,
node: true,
},
},
{
files: ['lib/**/*.js', 'lib/**/*.ts'],
env: {
node: true,
},
},
],
};
実際の使用例
javascript// pages/index.js (クライアントサイド)
export default function Home() {
const handleClick = () => {
// ブラウザ環境のグローバル変数
window.alert('ボタンがクリックされました!');
console.log('クリックイベント発生');
};
return (
<button onClick={handleClick}>
クリックしてください
</button>
);
}
// pages/api/hello.js (サーバーサイド)
export default function handler(req, res) {
// Node.js環境のグローバル変数
console.log('API呼び出し:', process.env.NODE_ENV);
res.status(200).json({
message: 'Hello from API',
timestamp: new Date().toISOString()
});
}
実践的なトラブルシューティング
開発中によく遭遇する問題と、その解決方法をご紹介します。
問題 1: jQuery 使用時のエラー
javascript// エラーが発生するコード
$('#myElement').click(function () {
console.log('クリックされました');
});
bash1:1 error '$' is not defined no-undef
解決方法:
javascript// .eslintrc.js
module.exports = {
env: {
browser: true,
jquery: true, // jQuery環境を有効化
},
// または globals で個別設定
globals: {
$: 'readonly',
jQuery: 'readonly',
},
};
問題 2: Web API 使用時のエラー
javascript// エラーが発生するコード
fetch('/api/data')
.then((response) => response.json())
.then((data) => console.log(data));
bash1:1 error 'fetch' is not defined no-undef
解決方法:
javascript// .eslintrc.js
module.exports = {
env: {
browser: true,
es2021: true, // fetch APIを含むES2021の機能を有効化
},
// または globals で個別設定
globals: {
fetch: 'readonly',
},
};
問題 3: テスト環境でのエラー
javascript// エラーが発生するテストコード
describe('テストスイート', () => {
it('正常に動作する', () => {
expect(true).toBe(true);
});
});
bash1:1 error 'describe' is not defined no-undef
2:3 error 'it' is not defined no-undef
3:5 error 'expect' is not defined no-undef
解決方法:
javascript// .eslintrc.js
module.exports = {
env: {
browser: true,
node: true,
jest: true, // Jest環境を有効化
mocha: true, // Mocha環境を有効化(必要に応じて)
},
// または overrides で特定ディレクトリのみ設定
overrides: [
{
files: ['**/*.test.js', '**/*.spec.js'],
env: {
jest: true,
},
},
],
};
パフォーマンス最適化のコツ
ESLint のグローバル変数設定は、パフォーマンスにも影響を与えます。
最適化のポイント
- 必要な環境のみを有効化
javascript// 良い例:必要な環境のみ指定
module.exports = {
env: {
browser: true, // ブラウザ環境のみ
},
};
// 悪い例:不要な環境まで指定
module.exports = {
env: {
browser: true,
node: true,
worker: true,
serviceworker: true,
// 使わない環境まで指定するのは非効率
},
};
- overrides の活用
javascriptmodule.exports = {
// 基本設定
env: {
es2021: true,
},
overrides: [
{
// ブラウザ用ファイルのみに適用
files: ['src/**/*.js'],
env: {
browser: true,
},
},
{
// Node.js用ファイルのみに適用
files: ['server/**/*.js'],
env: {
node: true,
},
},
],
};
まとめ
ESLint でグローバル変数を正しく扱うことは、コードの品質を保ちながら開発効率を向上させる重要なスキルです。
今回ご紹介した内容を整理すると:
推奨される解決方法の優先順位
- env 設定による環境指定(最も推奨)
- globals 設定による個別指定
- overrides による詳細な制御
- インラインコメントによる部分的対応(最小限に使用)
開発現場での実践ポイント
- チーム共通の ESLint 設定を作成し、統一されたルールで開発を行う
- プロジェクトの特性に応じた環境設定を適切に選択する
- 過度にグローバル変数を許可しないことで、本来の ESLint の恩恵を受ける
- エラーメッセージを恐れずに、適切な設定で解決していく
ESLint のグローバル変数設定をマスターすることで、開発中のストレスが大幅に軽減され、より集中してコードの本質的な部分に取り組めるようになります。
特に、実際のプロジェクトでは複数の環境(ブラウザ、Node.js、テスト環境など)を組み合わせて使用することが多いため、overrides 機能を使った詳細な設定が重要になります。
皆さんも、今回ご紹介した方法を実際のプロジェクトで試してみて、より快適な JavaScript/TypeScript 開発を実現してください。きっと、「あのエラーに悩まされる時間」が大幅に短縮されるはずです!
関連リンク
- review
今の自分に満足していますか?『持たざる者の逆襲 まだ何者でもない君へ』溝口勇児
- review
ついに語られた業界の裏側!『フジテレビの正体』堀江貴文が描くテレビ局の本当の姿
- review
愛する勇気を持てば人生が変わる!『幸せになる勇気』岸見一郎・古賀史健のアドラー実践編で真の幸福を手に入れる
- review
週末を変えれば年収も変わる!『世界の一流は「休日」に何をしているのか』越川慎司の一流週末メソッド
- review
新しい自分に会いに行こう!『自分の変え方』村岡大樹の認知科学コーチングで人生リセット
- review
科学革命から AI 時代へ!『サピエンス全史 下巻』ユヴァル・ノア・ハラリが予見する人類の未来