React + TypeScript + Webpackでバンドル環境を作るステップバイステップガイド

2025/01/05に公開

はじめに

ReactとTypeScriptを使用したモダンなWebアプリケーションの開発は、効率的で型安全なコードを書けるため非常に人気があります。しかし、その開発環境をセットアップするには少し手間がかかることもあります。特に、ReactとTypeScriptをWebpackでバンドルする設定は初めての方にとっては敷居が高く感じられるかもしれません。

この記事では、ReactとTypeScriptをWebpackでバンドルする方法をステップバイステップで解説します。実際に開発を始めるために必要な設定までを網羅しています。これからReactとTypeScriptを使ったプロジェクトを始める方、またはWebpackの設定に悩んでいる方にとって役立つ内容となっていますので、ぜひ最後までご覧ください。

なおWebpackの基本的な設定に関しては別の記事でご紹介していますので合わせてご参考ください。

https;//shinagawa-web.com/blogs/webpack-basics-guide

React(JSX)をバンドルする

JSXのような非標準のJavaScript構文をJSに変換する必要があるのですがそれを担うのがBabelになります。

前回の記事でBabelをご紹介しましたがその際は新しいJavaScriptの書き方を古い書き方に変換するために使いましたが、今回はJSX -> JSへの変換で使用します。

Babel公式

https://babeljs.io/

Babelプリセットの追加

npm i -D @babel/preset-react

.babelrcファイルをプロジェクト直下に作成してありましたので先ほど追加したプリセットを指定します。

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

プロジェクトにReactのインストール

ReactのインストールをしてJSX構文が使えるようにします。

npm i react react-dom

Reactアプリの作成

これまで作成してきたJSファイルを削除し新たにReactアプリを作成していきます。

rm dist/*.js* src/*.js

Appコンポーネントの作成

src/App.jsx
import React from "react";

export const App = ({name}) => {
  return (
    <h1>{`Hello ${name}`}</h1>
  );
};

nameをPropsに取り表示させています。

src/index.jsx
import { createRoot } from 'react-dom/client';
import React, { StrictMode } from 'react';
import { App } from './App';
import './styles.css'

const root = createRoot(document.getElementById('app'));
root.render(
  <StrictMode>
    <App name={'Test'} />
  </StrictMode>
);

id='app'の要素にReactアプリを表示させるよう定義しています。

dist/index.html
  <head>
    <meta charset="utf-8" />
    <title>webpack tutorial</title>
  </head>
  <body>
+     <div id="app"></div>
    <script src="./main.js"></script>
  </body>

表示させるHTMLに新たにid='app'の要素を追加しました。

動作確認

webpackでバンドルしてみます。

npx webpack --mode development

するとエラーが発生しました。

Image from Gyazo

これまではデフォルトでsrc/index.jsをエントリーファイルとして読み込まれるモジュールをバンドルしていましたが、src/index.jsxが今回エントリーポイントになったためエラーとなりました。

webpack.config.jsを修正します。

webpack.config.js
/** @type {import('webpack').Configuration} */
module.exports = {
  devtool: "source-map",
  module: {
    rules: [
      {
-         test: /\.js$/,
+         test: /\.jsx?$/,
        loader: "babel-loader",
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
+   resolve: {
+     extensions: ['.js', '.jsx']
+   }
};

再度バンドルすると今度は成功するかと思います。

Image from Gyazo

TypeScriptをバンドルする

Reactがバンドルできましたので次はTypeScriptで書いたコードのバンドルを行なっていきます。

TypeScriptのインストール

まず最初にTypeScriptのインストールを行います。

npm i -D typescript

react-dom に含まれる関数やオブジェクトの型情報もインストールします。

npm i -D @types/react-dom

tsconfigの作成

TypeScript プロジェクトのコンパイラ設定を管理するためのtsconfig.jsonファイルを作成します。

npx tsc --init

Reactを使用するため、"jsx": "react-jsx"を追記しておきます。

tsconfig.json
{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "jsx": "react-jsx"
  }
}

TypeScript用のローダーのインストール

TypeScriptで書かれたコードを読み取るためにローダーをインストールします。

npm i -D ts-loader

webpack.config.jsの設定変更

babel-loaderからts-loaderに変更します。

また新たに.ts.tsxをサポートするように設定変更します。

webpack.config.js
/** @type {import('webpack').Configuration} */
module.exports = {
  devtool: "source-map",
  module: {
    rules: [
      {
-         test: /\.jsx?$/,
+         test: /\.tsx?$/,
-         loader: "babel-loader",
+         loader: "ts-loader",
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  resolve: {
-     extensions: ['.js', '.jsx']
+     extensions: ['.js', '.jsx', '.ts', '.tsx']
  }
};

jsx -> tsxへの書き換え

ファイルの拡張子を変更しつつTypeScriptに書き換えていきます。

src/App.tsx
- import React from "react";

- export const App = ({name}) => {
+ export const App = ({name}: {name: string}) => {
  return (
    <h1>{`Hello ${name}`}</h1>
  );
};

nameの型を定義します。
また、tsconfig.json"jsx": "react-jsx"を設定したためimport React from "react";は不要になりました。

src/index.tsx
import { createRoot } from 'react-dom/client';
- import React, { StrictMode } from 'react';
+ import { StrictMode } from 'react';
import { App } from './App';
import './styles.css'

+ const container = document.getElementById('app');
+ if (!container) {
+   throw new Error("Failed to find the root element. Make sure there's an element with id='app' in your HTML.");
+ }

- const root = createRoot(document.getElementById('app'));
+ const root = createRoot(container);

root.render(
  <StrictMode>
-     <App name={'Test'} />
+     <App name={'TypeScript'} />
  </StrictMode>
);

id='app'の要素を取得できなかった場合の処理を追記しています。
動作確認のためTestからTypeScriptに変更しています。

動作確認

webpackでバンドルしてみます。

npx webpack --mode development

TypeScript + Reactの環境で動作確認ができました。

Image from Gyazo

webpack.configをTypeScriptで記述する

webpack.config.jsはwebpack.config.tsに変更することも可能です。

(そこまでする必要があるかはプロジェクトごとの判断になるかと思いますが)

webpack.configはwebpackでバンドルする前に読み込むためts-loaderではなくts-nodeを使ってTypeScript のまま Node.js スクリプトを実行できるようにします。

また実行時にはTypeScript 用 Node.js の型定義ファイルが必要となるためこちらもインストールします。

npm i -D ts-node @types/node

webpack.config.js -> webpack.config.tsに拡張子を変更しつつ書き方も若干変わります。

webpack.config.ts
import { Configuration } from "webpack";

const config: Configuration = {
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: "ts-loader",
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  resolve: {
    extensions: [".js", ".jsx", ".ts", ".tsx"],
  },
};

export default config;

Configurationというwebpackの型情報をセットすることで入力補完が効くようになります。

これまで通りwebpackでバンドルできるか確認します。

npx webpack --mode development

HTMLをバンドルする

これまではHTMLファイルをdistフォルダに置いて、getElementByIdでReactアプリを表示させていました。
webpackではHTMLもバンドルしてまとめてコードを出力することが可能です。

プラグインのインストール

html-webpack-plugin をプロジェクトに追加します。

npm i -D html-webpack-plugin

webpack.config.ts に設定を追加

webpack.config.ts
import { Configuration } from "webpack";
+ import HtmlWebpackPlugin from "html-webpack-plugin";

const config: Configuration = {
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: "ts-loader",
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  resolve: {
    extensions: [".js", ".jsx", ".ts", ".tsx"],
  },
+   plugins: [
+     new HtmlWebpackPlugin({
+       template: "./src/index.html",
+       inject: "body",
+     }),
+   ],
};

export default config;

先ほどのプラグインを追加し、HTMLファイルの配置先を定義します。
合わせてbodyタグでJavaScriptを読み込むよう設定します。

次にHTMLファイルをdist -> srcに移動しscriptタグは削除します。

dist/index.html
  <head>
    <meta charset="utf-8" />
    <title>webpack tutorial</title>
  </head>
  <body>
    <div id="app"></div>
-     <script src="./main.js"></script>
  </body>

動作確認

これまで通りwebpackでバンドルできるか確認します。

npx webpack --mode development

ブラウザで表示されていればOKです。

Image from Gyazo

これでdistフォルダは管理しなくて良くなったので.gitignoreに追加しておきます。

dist/

さいごに

今回の記事では、ReactとTypeScriptのアプリケーションをWebpackでバンドルする方法について解説しました。Webpackの設定ファイルの編集、BabelやTypeScriptの導入、さらにはHTMLのバンドルまで、必要な手順をひとつずつ追っていきました。

ReactとTypeScriptを使った開発は、最初は少し学習曲線があるかもしれませんが、適切なツールと設定を使うことで、開発効率が大きく向上します。このガイドを参考にして、あなたも自分の開発環境を整えて、効率的なReactアプリの開発を楽しんでください。

今後もWeb開発に役立つ情報を提供していきますので、引き続きチェックしていただけると嬉しいです

なおWebpackの基本的な設定に関しては別の記事でご紹介していますので合わせてご参考ください。

https;//shinagawa-web.com/blogs/webpack-basics-guide

記事に関するお問い合わせ📝

記事の内容に関するご質問、ご意見などは、下記よりお気軽にお問い合わせください。
ご質問フォームへ

技術支援などお仕事に関するお問い合わせ📄

技術支援やお仕事のご依頼に関するお問い合わせは、下記よりお気軽にお問い合わせください。
お問い合わせフォームへ