条件付きインポートのパターン

通常の import 文は静的で、条件分岐の中では使用できません。しかし、動的インポート import() を活用することで、条件に応じたモジュールの読み込みが可能になります。

静的インポートの制約

import 文はモジュールのトップレベルでしか使用できず、条件分岐内では構文エラーになります。

// これはエラーになる
if (condition) {
  import { func } from './module.js'; // SyntaxError
}

動的インポートによる条件付き読み込み

import() 関数を使えば、実行時に条件に応じてモジュールを読み込めます。

async function loadFeature(isAdvanced) {
  if (isAdvanced) {
    const module = await import('./advanced.js');
    return module.AdvancedFeature;
  } else {
    const module = await import('./basic.js');
    return module.BasicFeature;
  }
}

環境に応じたインポート

開発環境と本番環境で異なるモジュールを読み込むパターンです。

async function getLogger() {
  if (process.env.NODE_ENV === 'development') {
    const { DevLogger } = await import('./DevLogger.js');
    return new DevLogger();
  } else {
    const { ProdLogger } = await import('./ProdLogger.js');
    return new ProdLogger();
  }
}

プラットフォーム検出

ブラウザと Node.js で異なるモジュールを使用する例です。

async function getStorage() {
  if (typeof window !== 'undefined') {
    // ブラウザ環境
    const { BrowserStorage } = await import('./BrowserStorage.js');
    return new BrowserStorage();
  } else {
    // Node.js 環境
    const { FileStorage } = await import('./FileStorage.js');
    return new FileStorage();
  }
}

機能検出によるポリフィル読み込み

必要な場合のみポリフィルを読み込むことで、バンドルサイズを最適化できます。

async function ensureIntlSupport() {
  if (typeof Intl.Segmenter === 'undefined') {
    await import('intl-segmenter-polyfill');
    console.log('Intl.Segmenter polyfill loaded');
  }
}

ユーザー設定に基づくインポート

ユーザーの選択に応じて、必要なモジュールだけを読み込むパターンです。

async function loadTheme(themeName) {
  const themes = {
    light: () => import('./themes/light.js'),
    dark: () => import('./themes/dark.js'),
    system: () => import('./themes/system.js')
  };
  
  const loader = themes[themeName] || themes.light;
  const theme = await loader();
  return theme.default;
}

遅延初期化パターン

初回使用時にのみモジュールを読み込む遅延初期化のパターンです。

let heavyModule = null;

async function getHeavyModule() {
  if (!heavyModule) {
    heavyModule = await import('./heavyModule.js');
  }
  return heavyModule;
}

// 必要になった時だけ呼び出す
document.getElementById('btn').addEventListener('click', async () => {
  const module = await getHeavyModule();
  module.doHeavyWork();
});

複数候補からのフォールバック

優先順位を付けて、利用可能なモジュールを読み込む例です。

async function loadImageProcessor() {
  try {
    // まず WebAssembly 版を試す
    return await import('./imageProcessor.wasm.js');
  } catch {
    try {
      // 次に最適化された JS 版を試す
      return await import('./imageProcessor.optimized.js');
    } catch {
      // 最後にフォールバック版を使用
      return await import('./imageProcessor.fallback.js');
    }
  }
}
メリット

初期読み込みを高速化し、必要なコードだけをオンデマンドで読み込める。

注意点

動的インポートは非同期なので、await が必要。エラーハンドリングも忘れずに。

条件付きインポートを活用することで、アプリケーションのパフォーマンスと柔軟性を両立できます。