サイドエフェクトのみのインポート

モジュールをインポートするだけで、その中のコードを実行させることができます。これを「サイドエフェクトのみのインポート」と呼びます。

基本的な構文

波括弧もデフォルトインポートも使わず、パスだけを指定します。

import './setup.js';
import './polyfill.js';
import './styles.css'; // バンドラー経由の場合

この場合、モジュール内のコードは実行されますが、何も変数にバインドされません。

使用例:ポリフィル

古いブラウザに新しい機能を追加するポリフィルは、典型的なサイドエフェクトインポートの例です。

// polyfill.js
if (!Array.prototype.at) {
  Array.prototype.at = function(index) {
    // ポリフィルの実装
  };
}
// main.js
import './polyfill.js'; // 実行されるだけでOK

const arr = [1, 2, 3];
console.log(arr.at(-1)); // 3(ポリフィルが適用されている)

使用例:グローバルな初期化

アプリケーション全体に影響する初期化処理を行う場合に使います。

// analytics.js
window.analytics = {
  track(event) {
    console.log('Tracking:', event);
  }
};

document.addEventListener('click', (e) => {
  window.analytics.track('click');
});
// main.js
import './analytics.js'; // 初期化処理が実行される

使用例:スタイルシートの読み込み

バンドラー(Webpack、Vite など)を使用している場合、CSS ファイルもインポートできます。

import './styles.css';
import './components/Button.css';

バンドラーがこれらのインポートを検出し、CSS をバンドルに含めます。

サイドエフェクトの注意点

Tree Shaking への影響

サイドエフェクトがあるモジュールは、バンドラーが不要と判断しても削除されません。package.json の sideEffects フィールドで明示できます。

実行順序

インポートの順序に依存する場合があります。ポリフィルは他のモジュールより先にインポートする必要があります。

{
  "name": "my-package",
  "sideEffects": ["./src/polyfill.js", "*.css"]
}

明示的なサイドエフェクト

モジュールの目的がサイドエフェクトであることを明確にするため、コメントを付けることが推奨されます。

// main.js

// サイドエフェクト:グローバルにポリフィルを追加
import './polyfill.js';

// サイドエフェクト:スタイルを適用
import './global.css';

// 通常のインポート
import { App } from './App.js';

サイドエフェクトを避けるべき場合

サイドエフェクトが適切な場合

ポリフィル、グローバル設定、CSS の読み込み

サイドエフェクトを避けるべき場合

ライブラリ、ユーティリティ関数、再利用可能なコンポーネント

ライブラリやユーティリティは、インポートしただけで何かが起こるのではなく、明示的に関数を呼び出して初めて動作するように設計すべきです。

// 悪い例:インポートしただけでログ出力
// logger.js
console.log('Logger initialized');
export function log(msg) { /* ... */ }

// 良い例:明示的に初期化
// logger.js
export function initLogger() {
  console.log('Logger initialized');
}
export function log(msg) { /* ... */ }

サイドエフェクトのみのインポートは、適切な場面で使用すると便利ですが、乱用するとコードの理解が難しくなります。