🔖

副作用インポートと polyfill を正しく理解する

に公開

はじめに

フロントエンド開発をしていると、次のようなコードを目にすることがあります。

import "./setup";
import "./polyfills";

「何も import していないのに、なぜ必要なのか?」
この記事では、副作用インポートpolyfill という概念をセットで整理し、
なぜ現代の JavaScript 開発で重要なのかを解説します。


副作用インポートとは?

副作用インポート(side-effect import) とは、

値(変数・関数・クラス)を使うためではなく、
モジュールが読み込まれたときに実行される処理そのものを目的としたimport

のことです。

基本形

import "./setup";

この書き方では、

  • setup.js のトップレベルコードが実行される
  • export された値は一切使わない

という特徴があります。


「副作用」とは何か?

JavaScript における副作用とは、次のような処理です。

  • グローバル変数や window / globalThis の変更
  • イベントリスナーの登録
  • 初期化処理の実行
  • CSS の適用
  • polyfill の適用

つまり、

import しただけで、アプリの状態や実行環境が変わること

これが副作用です。


副作用インポートの具体例

初期化処理

// setup.js
console.log("アプリ初期化");
initAnalytics();
// main.js
import "./setup";

setup.js の実行自体が目的なので、副作用インポートになります。


CSS の読み込み

import "./global.css";

CSS ファイルは値を export しませんが、
import することでスタイルが適用されます。

これも典型的な副作用インポートです。


通常の import との違い

通常の import(値を使う)

import { add } from "./math";

add(1, 2);
  • 目的:関数や変数などの値を使うこと

副作用インポート(実行が目的)

import "./math";
  • 目的:モジュールが実行されること
  • export は使わない

polyfill とは?

polyfill(ポリフィル) とは、

実行環境に存在しない JavaScript の機能を、後から追加して使えるようにするコード

のことです。

ブラウザや実行環境によっては、新しい API が存在しない場合があります。

[1, 2, 3].includes(2); // 古い環境ではエラーになる可能性

この差を埋めるために polyfill を使います。


polyfill の基本的な考え方

if (!Array.prototype.includes) {
  Array.prototype.includes = function (value) {
    return this.indexOf(value) !== -1;
  };
}
  • 機能がなければ追加する
  • すでにあれば何もしない

既存コードを壊さず、環境だけを補強するのがポイントです。


polyfill はなぜ副作用インポートで読み込まれるのか?

polyfill は、

  • グローバルオブジェクトを書き換える
  • JavaScriptのprototypeプロパティを拡張する

といった強い副作用を持ちます。

そのため、多くの場合次のように読み込まれます。

import "./polyfills";
// polyfills.js
import "core-js/es/array/includes";
import "regenerator-runtime/runtime";

import した瞬間に、実行環境が拡張されます。


polyfill と transpile の違い

ここは非常に混同されやすいポイントです。

polyfill(機能を追加する)

対象例:

  • Promise
  • Array.prototype.includes
  • fetch

実行時に API を追加します。


transpile(構文を変換する)

// before
const add = (a, b) => a + b;

// after
var add = function (a, b) {
  return a + b;
};

コードの書き方(構文)を、古い JavaScript でも動く形に変換します。


polyfill が使えないケース

  • 新しい構文(?., ?? など)

    • polyfill では対応できない
    • transpile が必要
  • JavaScript で表現できない低レベルな機能


副作用インポートの注意点

1. 依存関係が分かりにくくなる

import "./setup";

この1行からは、何が起きるのか分かりません。
乱用すると可読性や保守性が下がります。


2. Tree Shaking されにくい

副作用があると、ビルドツールは

「消すと挙動が変わるかもしれない」

と判断し、不要コードの削除(最適化)ができなくなります。


現代フロントエンドでの考え方

  • モダンブラウザ前提の Web アプリ
    → polyfill は最小限、もしくは不要
  • 業務システムや古い端末対応
    → polyfill が重要

大切なのは、

なぜこの副作用インポートが必要なのかを説明できること


まとめ

  • 副作用インポート
    → 実行させること自体が目的の import
  • polyfill
    → 存在しない機能を後付けで追加する仕組み
  • polyfill は副作用インポートで読み込まれることが多い
  • transpile とは役割が異なる
  • 便利だが、使いどころと理由を明確にすることが重要

「なんとなく import していたコード」を、
意味を理解して扱えるようになることが、設計力の向上につながります。

GitHubで編集を提案

Discussion