React

【React】ViteでReactをCDNから読み込む

更新日:2026/05/13

ViteでReactアプリを作成すると、Reactの本体がJSファイル内に組み込まれます。
普段なら問題ないのです。
しかし一つのサイトで複数のアプリを公開するとなると、React本体を分離してブラウザキャッシュを利用したほうが転送量低減になり効率がいいですね。

そこで今回は、ViteでReactをCDNから読み込む方法を紹介します。

 

概要:importmapを使用する

ReactをCDNから読み込む場合、ビルド時に生成されるJSファイルにReactモジュールがバンドルされないようにvite.config.tsで設定します。
その上でブラウザ側の機能である、importmapを使用してimport宣言のインポート元モジュール名と実際にインポートするファイルのURLを対応付けします。

例えば次のようにreactをインポートしている場合、開発モードなら実行可能です。

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'

しかしReactモジュールをバンドルしないで本番ビルドすると、実行時エラーになります。

そこで、html内に次のように記述します。

<script type="importmap">{
  "imports": {
    "react": "https://esm.sh/react@19.2.6",
    "react-dom/client": "https://esm.sh/react-dom@19.2.6/client"
  }
}
</script>

これによりブラウザは、import宣言のインポート元モジュール名をimportmapの値と置き換えてファイルを読み込んでくれます。

 

vite.config.tsで設定

vite.config.tsで、バンドルから外す設定と、importmapをhtmlに挿入します。
ただし開発モード時は、デフォルトのまま動作させます。

vite.config.ts

import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import type { ConfigEnv } from "vite";

const REACT_VER = "19.2.6";

const IMPORTMAP = {
  imports: {
    react: `https://esm.sh/react@${REACT_VER}`,
    "react-dom/client": `https://esm.sh/react-dom@${REACT_VER}/client`,
  },
};

export default defineConfig(({ command }: ConfigEnv) => {
  const isBuild = command === "build";

  return {
    build: {
      rollupOptions: { // Reactをバンドルから外す
        external: isBuild ? ["react", "react-dom/client"] : [],
      },
    },
    plugins: [
      react(),
      //   babel({ presets: [reactCompilerPreset()] }),
      {
        name: "inject-importmap",
        transformIndexHtml(html: string) { // importmapの挿入
          if (!isBuild) {
            return html;
          }

          return html.replace(
            "<!--IMPORTMAP-->",
            `<script type="importmap">${JSON.stringify(IMPORTMAP, null, 2)}</script>`,
          );
        },
      },
    ],
  };
});

index.htmlに置き換え先のコメントを記述しておきましょう。

  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />

    <!--IMPORTMAP-->
  </head>

 

React Compilerがエラーの原因

前述のvite.config.tsは、 babel({ presets: [reactCompilerPreset()] }) の行がコメントアウトされています。
これはViteのインストール時に、TypeScript + React Compilerを選択したことで挿入されたものです。

コメントアウトせずにビルドしてブラウザで表示したら、次のようなエラーが表示されました。

Error: Calling require for "react" in an environment that doesn't expose the require function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.

ブラウザで使用できないrequire()関数を呼び出していることによるエラーです。

React Compilerは比較的新しいのでimportmapを考慮していないらしく、最終的にrequire()関数を出力するコードを生成しているようです。
今後は改善されるかもしれませんね。

更新日:2026/05/13

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。