「Webpack React 環境構築」で検索すると、今はもう動かない古い手順が大量にヒットします。babel-preset-es2015babel-coreを使う記事は、その時点で情報が数年前で止まっているサインです。
先に結論です。2026年の新規React開発はViteかNext.jsが標準で、Webpackを自前で組む機会はほぼありません。それでも、既存案件の保守やバンドラの仕組み理解のために、一度は手組みしてみる価値が今もあります。この記事では、React 19が実際に動く2026年時点の最小構成を、1コマンド・1ファイルずつ解説します。

この記事でわかること
・2026年にWebpackを学ぶ価値と限界(新規開発はVite標準)
・React 19が動くWebpack最小構成(全ファイルコピペ可)
・webpack.config.jsの各設定(mode / entry / output / devServer / loader)の意味
・古い記事に載っている廃止済みパッケージの見分け方

独学に限界を感じたら

プログラミング教室がおすすめ。挫折せず最短で実力を伸ばせます。

PR

2026年にWebpackを手組みする意味はあるのか

正直に書きます。新しくReactアプリを作るならViteを使ってください

かつての定番だったcreate-react-app(CRA)はすでに非推奨となり、React公式もViteやNext.jsなどへの移行を案内しています。理由の詳細はViteがWebpack構成より優れている5つの理由にまとめています。

それでもWebpackの知識が今も現場で生きる場面は、はっきり3つあります。

  • 既存案件の保守:現場でよくあるのは、数年前にCRAやWebpack手組みで作られたアプリの改修です。webpack.config.jsが読めないと、ビルドエラーひとつ直せません。
  • バンドラの仕組み理解:entry・loader・pluginという概念は、ViteにもRspackにもTurbopackにも共通します。Webpackで一度手を動かすと、他のツールの設定が一気に読めるようになります。
  • 面接での差別化:私がレビューする側で見てきた限り、「Viteは使えるが中で何が起きているかは説明できない」人は多いです。バンドルの流れを自分の言葉で説明できるだけで評価が変わります。

Viteしか知らない人より、Viteが何を隠してくれているかを知っている人の方が強い。これがこの記事の立ち位置です。なおWebpack自体も止まったツールではなく、2026年もロードマップが公開されv6の開発が進んでいる現役のバンドラです。

目的選ぶべきツール
新規のSPA開発Vite
新規のWebサービス(SSR・ルーティング込み)Next.js
既存Webpack案件の保守Webpack(この記事)
バンドラの仕組みを学ぶWebpack手組み(この記事)

今回つくる構成(2026年7月時点の最新)

使用するパッケージと役割を先に整理します。ここが古い記事と最も違うところです。

パッケージバージョン目安役割
react / react-dom19系React本体
webpack5.108系バンドラ本体
webpack-cli6系webpackコマンド
webpack-dev-server5系開発サーバー(ホットリロード)
babel-loader10系webpackとBabelの橋渡し
@babel/core8系Babel本体(JSX等を変換)
@babel/preset-env8系モダンJSをブラウザ向けに変換
@babel/preset-react8系JSXの変換(最重要)
html-webpack-plugin5系HTMLへのscript自動挿入
style-loader / css-loader最新CSSの読み込み

⚠️ 注意:Babelは2026年6月にメジャーバージョン8がリリースされ、Node.js 24以上が必須になりました。Node.jsが古い場合は、現行LTSであるNode.js 24に上げてから進めてください。

バージョン管理にはnvmが便利です。どうしても古いNodeで動かす場合は、Babel関連を@babel/core@^7のように7系に固定すれば同じ手順で動きます。

💡 なお、変換器(トランスパイラ)にはBabelの代わりにRust製で高速なSWCswc-loader)を使う選択肢もあります。ただし情報量と教材の多さではBabelが圧倒的なので、学習用途では今回のBabel構成をおすすめします。

手順:React 19が動くWebpack最小構成

ステップ1:プロジェクトの作成

mkdir webpack-react-practice
cd webpack-react-practice
npm init -y
mkdir src public
touch webpack.config.js babel.config.json src/index.js src/App.jsx src/styles.css public/index.html

上から順に実行すると、次のディレクトリ構成ができます。

webpack-react-practice
├── package.json
├── babel.config.json
├── webpack.config.js
├── public
│   └── index.html
└── src
    ├── App.jsx
    ├── index.js
    └── styles.css

ステップ2:ライブラリのインストール

# React本体
npm install react react-dom

# webpack本体と開発サーバー
npm install -D webpack webpack-cli webpack-dev-server html-webpack-plugin

# Babel(JSXをブラウザが読めるJSに変換する)
npm install -D babel-loader @babel/core @babel/preset-env @babel/preset-react

# CSSを読み込むためのloader
npm install -D style-loader css-loader

ここで古い記事との違いをひとつ。「babel-core」と「@babel/core」は別物です

babel-corebabel-loader@7babel-preset-es2015babel-preset-reactといったハイフン時代の旧パッケージはすべて廃止済みで、現在のReactでは動きません。

@babel/で始まるスコープつきパッケージが現行版です。検索で出てきた記事がどちらを使っているかで、情報の鮮度を一発で見分けられます。

ステップ3:設定ファイルを書く

まずBabelの設定です。「モダンJSを主要ブラウザ向けに変換する」「JSXを変換する」という2つのプリセットを指定します。

{
  "presets": [
    ["@babel/preset-env", { "targets": "defaults" }],
    ["@babel/preset-react", { "runtime": "automatic" }]
  ]
}

runtime: "automatic"は、ファイルごとにimport React from 'react'を書かなくてもJSXが使える現行方式です。これを指定し忘れて(もしくはBabel 7系の古い既定値のまま)「React is not defined」エラーに悩む、というのが定番のハマりどころです。

次が本丸のwebpack.config.jsです。mode・entry・output・loader・plugin・devServerという、Webpack理解に必要な要素をすべて含んだ最小構成にしました。

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // development=速さ優先 / production=圧縮・最適化。CLIの --mode が優先される
  mode: 'development',

  // バンドルの起点になるファイル
  entry: './src/index.js',

  // バンドル結果の出力先。clean: true で毎回dist内を掃除する
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js',
    clean: true,
  },

  module: {
    rules: [
      // .js / .jsx をBabelで変換する(JSX → ブラウザが読めるJS)
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: 'babel-loader',
      },
      // CSSを読み込む。loaderは配列の「右から左」に適用される
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },

  // import時に拡張子を省略できるようにする
  resolve: {
    extensions: ['.js', '.jsx'],
  },

  // public/index.html を雛形に、scriptタグ入りのHTMLを自動生成する
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
    }),
  ],

  // 開発サーバー。hot: true で保存時に自動反映される
  devServer: {
    static: path.resolve(__dirname, 'public'),
    port: 8080,
    open: true,
    hot: true,
  },
};

💡 プロのコツ:CSSのloaderは['style-loader', 'css-loader']の順で書きますが、実行は右から左です。

css-loaderがCSSをJSに取り込み、style-loaderがそれをstyleタグとしてページに注入します。順番を逆にすると動かないので、Webpack案件のレビューでも本当によく見る間違いです。

ステップ4:HTMLとReactのコードを書く

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>React × webpack</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

scriptタグは書きません。HtmlWebpackPluginがビルド時に自動で挿入してくれるからです。手書きのscriptタグでパスがずれて白画面、という事故を防げます。

import './styles.css';

export default function App() {
  return <h1 className="title">React × webpack</h1>;
}
.title {
  font-family: sans-serif;
}
import { createRoot } from 'react-dom/client';
import App from './App';

const root = createRoot(document.getElementById('root'));
root.render(<App />);

ステップ5:起動コマンドを追加して動作確認

package.jsonのscriptsに開発用・本番用の2コマンドを追加します。

"scripts": {
  "start": "webpack serve --mode development",
  "build": "webpack --mode production"
}
npm start

開発サーバーが立ち上がり、http://localhost:8080 が自動で開きます。下記のような画面が出れば成功です。App.jsxを編集して保存すると、リロードなしで即座に反映されることも確認してみてください。

ステップ6:本番ビルド

npm run build

distディレクトリに以下のファイルが生成されれば完了です。--mode productionにより、コードは圧縮・最適化された状態で出力されます。この中身をそのまま静的サーバーに置けば公開できます。

dist
├── index.html
├── main.js
└── main.js.LICENSE.txt

初心者がハマるポイント3つ

①JSXでSyntaxErrorが出る

Module parse failed: Unexpected tokenと出たら、ほぼ確実にBabelがJSXを変換できていません。

@babel/preset-reactのインストール漏れ、babel.config.jsonの置き場所(プロジェクト直下)、webpack.config.jsのtest: /\.(js|jsx)$/の書き間違いの3点を順に確認してください。

②古い記事のパッケージ名で消耗する

前述のとおり、babel-preset-es2015などの旧世代パッケージは廃止済みです。エラー解決のために検索した記事がさらに古い、という無限ループに入りがちなので、「@babel/」で始まらないBabelパッケージが出てきた記事はその場で閉じると決めておくのが最短です。

③Node.jsのバージョン不一致

Babel 8はNode.js 24以上が必須です。インストール時にengines関連の警告やエラーが出たら、まずnode -vを確認しましょう。nvmを使えばプロジェクトごとにNodeバージョンを切り替えられるので、複数案件を抱える人は必ず入れておくべきツールです。

まとめ

  • 2026年の新規React開発はVite / Next.jsが標準。Webpack手組みは「保守」と「学習」のための技術
  • 現行構成はwebpack 5 + babel-loader 10 + @babel/core(+ preset-env / preset-react)。ハイフン時代の旧Babelパッケージは全廃止
  • webpack.config.jsはmode / entry / output / loader / plugin / devServerの6要素を押さえれば読める
  • entry・loader・pluginの概念はVite等の現行ツールにもそのまま通じる

次のアクションとしては、今回の構成にTypeScriptやESLintを足してみるのがおすすめです。手順はVite + React(TypeScript)のESLint & Prettier導入ガイドが参考になります。また、これからReactを本格的に学ぶ段階ならReact入門の学習方法から進めてください。

ビルドツールまわりは独学だと「動いたけど理由が分からない」で止まりやすい領域です。

環境構築で何日も溶かしてしまうタイプの人は、質問できるメンターがいるスクールで基礎を固めるのも近道ですし、すでに実務経験があるなら、こうした低レイヤーの理解は転職市場で確実に評価されます。

エージェントとの面談で「バンドラの仕組みを説明できる」と伝えられるだけでも強い武器になります。

よくある質問(FAQ)

Q. これから学ぶならWebpackとViteどっちを優先すべき?

実務で使う頻度ではViteが優先です。ただし概念(entry / loader / plugin)はWebpackで学ぶ方が輪郭がはっきりします。この記事の最小構成を一度組んでからViteに移ると理解が速いです。比較の詳細はViteを推す5つの理由をどうぞ。

Q. create-react-app(CRA)はもう使えないの?

すでに非推奨で、新規プロジェクトでの採用は避けるべきです。React公式のドキュメントもフレームワーク(Next.js等)やViteの利用を案内しています。既存のCRA案件を保守する場合にこそ、この記事のWebpack知識が役立ちます。

Q. この構成をTypeScript対応にするには?

@babel/preset-typescriptを追加し、testを/\.(js|jsx|ts|tsx)$/に広げるのが最小の変更です。ただしBabelは型チェックをしないので、tsc --noEmitを併用します。新規でTS環境を作るなら素直にVite + TypeScriptの構成を使う方が早いです。

あわせて読みたい関連記事

CRAからVite移行5ステップ|React開発を爆速化【2026年版】create-react-appの起動が遅いのは構造的な問題で、解決策はVite移行一択です。既存Reactプロジェクトを30分でViteに乗せ替える5ステップを、Vite 8時代のNode.js要件やハマりがちな落とし穴とともに2026年基準で解説します。frontendlab.magicgifted.com ReactにESLint・Prettierを導入する完全ガイド【Vite・TypeScript・ESLint v9対応】Vite + React(TypeScript)にESLint v9とPrettierを導入する2026年版ガイド。flat config、VSCodeの保存時整形、husky・lint-stagedのコミット前チェック、動作確認まで解説します。frontendlab.magicgifted.com React入門2026|挫折しない学習ロードマップと教材の選び方Reactの独学は「教材選び」で9割決まります。CRAが廃止された2026年、環境構築はVite/Next.jsが標準、書き方は関数コンポーネント+Hooks一択です。HTML/CSS→JS→React→TypeScript→Next.jsの学習ロードマップと5つのステップを現役エンジニアが解説します。frontendlab.magicgifted.com