本記事では、webpack
と Babel
を用いて、ReactとTypeScriptを使ったモダンなWebアプリケーション開発環境をゼロから構築する手順を解説します。
Webpackとは
Webpack は、JavaScriptアプリケーションのためのモジュールバンドラーです。複数のJavaScriptファイルやその他のアセット(CSS、画像など)を依存関係に基づいて解析し、ブラウザで実行可能な単一または複数のファイルにまとめます。
- 主な機能:
- モジュール解決:
import
やrequire
などの構文を解釈し、依存関係を解決します。 - バンドル: 複数のファイルを一つにまとめます。
- トランスパイル: Babelなどのローダーと連携し、新しいJavaScript構文を古いブラウザでも動作するように変換します。
- 最適化: コードの圧縮、不要なコードの削除など、パフォーマンス向上のための最適化を行います。
- モジュール解決:
Babelとは
Babel は、JavaScriptのトランスコンパイラーです。主に、最新のJavaScript(ES2015+)で書かれたコードを、古いブラウザや実行環境でも動作する互換性のあるJavaScript(ES5など)に変換するために使用されます。
- 主な機能:
- 新しい構文の変換:
async/await
, アロー関数、クラス構文などを変換します。 - JSXの変換: ReactのJSX構文を通常のJavaScriptに変換します。
- TypeScriptの変換: TypeScriptコードをJavaScriptに変換します(型チェックは行いません)。
- 新しい構文の変換:
環境構築
以下の記事を参考に、React/TypeScript開発環境を構築します。
- React 環境構築 Webpack + Babelなぜ必要?
- WebpackとBabelでReact.js 構築 設定
- webpack + babel + TypeScript + React メモ
必要なモジュールのインストール
プロジェクトディレクトリを作成し、npmで初期化します。
mkdir react_test
cd react_test
# プロジェクトの初期化
npm init -y
# Babel関連モジュール
npm install -D @babel/core # Babel本体
npm install -D @babel/preset-env # 最新のJS構文をターゲット環境に合わせて変換
npm install -D @babel/preset-react # ReactのJSXを変換
npm install -D @babel/preset-typescript # TypeScriptを変換
# Webpack関連モジュール
npm install -D webpack webpack-cli babel-loader ts-loader # webpack本体とCLI、Babel/TSをwebpackで扱うためのローダー
npm install -D webpack-dev-server html-webpack-plugin # 開発サーバーとHTML生成プラグイン
# ReactとTypeScript関連モジュール
npm install react react-dom # React本体とDOM操作ライブラリ
npm install -D typescript @types/react @types/react-dom # TypeScript本体とReact/ReactDOMの型定義
# tsconfig.json の生成
npx tsc --init
ファイル構成
最終的なファイル構成は以下のようになります。
.
├── dist/
│ ├── index.html
│ └── main.js
├── node_modules/
├── package-lock.json
├── package.json
├── src/
│ ├── index.html
│ └── index.tsx
├── tsconfig.json
└── webpack.config.js
各種設定ファイル
src/index.html
ReactアプリケーションのエントリポイントとなるHTMLファイルです。div
要素にReactコンポーネントがマウントされます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React App</title>
</head>
<body>
<div id="app"></div>
<!-- WebpackによってバンドルされたJavaScriptがここに自動的に挿入される -->
</body>
</html>
src/index.tsx
Reactアプリケーションのメインエントリファイルです。TypeScriptとJSXで記述されます。
import React from "react";
import { createRoot } from "react-dom/client"; // React 18からcreateRootを使用
const App = () => {
return <h1>Hello React with TypeScript!</h1>;
};
// React 18の新しいAPIを使用
const container = document.getElementById("app");
if (container) {
const root = createRoot(container);
root.render(<App />);
}
.babelrc
Babelの設定ファイルです。どのプリセット(プラグインのセット)を使用してコードを変換するかを定義します。
{
"presets": [
"@babel/preset-env", // 最新のJSをターゲット環境に合わせて変換
"@babel/preset-react", // ReactのJSXを変換
"@babel/preset-typescript" // TypeScriptを変換 (型チェックは行わない)
]
}
package.json
プロジェクトのメタデータとスクリプト、依存関係を定義します。scripts
セクションに開発サーバーの起動コマンドとビルドコマンドを追加します。
{
"name": "react_test",
"version": "1.0.0",
"description": "React with TypeScript development environment",
"main": "index.js",
"scripts": {
"start": "webpack serve --open", // 開発サーバーを起動し、ブラウザを自動で開く
"build": "webpack --mode production" // 本番用にビルド
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.20.2",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.8",
"babel-loader": "^9.1.0",
"html-webpack-plugin": "^5.5.0",
"ts-loader": "^9.4.1",
"typescript": "^4.8.4",
"webpack": "^5.75.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}
tsconfig.json
TypeScriptのコンパイラ設定ファイルです。TypeScriptコードをJavaScriptに変換する際のルールを定義します。
{
"compilerOptions": {
"target": "es2015", // 出力するJavaScriptのバージョン (ES5でも可)
"module": "esnext", // モジュールシステム (Webpackが処理するためesnextが柔軟)
"jsx": "react-jsx", // JSXの変換方法 (React 17+ の新しいJSXトランスフォーム)
"strict": true, // 厳格な型チェックを有効にする
"esModuleInterop": true, // CommonJSモジュールとESモジュールの互換性を高める
"skipLibCheck": true, // 型定義ファイルの型チェックをスキップ (ビルド高速化)
"forceConsistentCasingInFileNames": true, // ファイル名の大文字小文字を区別する
"moduleResolution": "node", // モジュール解決戦略
"resolveJsonModule": true, // JSONファイルのインポートを許可
"isolatedModules": true, // 各ファイルを独立したモジュールとしてコンパイル
"noEmit": true, // TypeScriptからJSへの出力を行わない (Babel/Webpackが担当)
"allowJs": true, // JavaScriptファイルのコンパイルを許可
"lib": ["dom", "dom.iterable", "esnext"] // 利用可能なライブラリ
},
"include": ["src"] // コンパイル対象のファイル
}
webpack.config.js
Webpackのバンドル設定ファイルです。エントリポイント、出力先、ローダー、プラグインなどを定義します。
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
// 開発モードに設定 (最適化やデバッグ情報が有効になる)
mode: "development",
// エントリポイント (アプリケーションの開始点)
entry: "./src/index.tsx",
// 出力設定
output: {
path: path.resolve(__dirname, "dist"), // 出力ディレクトリ
filename: "bundle.js", // 出力ファイル名
clean: true, // ビルド前にdistディレクトリをクリーンアップ
},
// モジュール解決の設定
resolve: {
extensions: [".ts", ".tsx", ".js", ".jsx"], // インポート時に解決する拡張子
},
// モジュールルール (ローダーの設定)
module: {
rules: [
{
test: /\\.(ts|tsx)$/, // .tsまたは.tsxファイルに適用
exclude: /node_modules/, // node_modulesは除外
use: {
loader: "babel-loader", // Babelを使って変換
options: {
presets: [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript",
],
},
},
},
// CSSや画像などのローダーもここに追加できる
],
},
// プラグインの設定
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html", // テンプレートとして使用するHTMLファイル
filename: "index.html", // 出力されるHTMLファイル名
}),
],
// 開発サーバーの設定
devServer: {
static: {
directory: path.join(__dirname, "dist"), // 静的ファイルの提供元ディレクトリ
},
compress: true, // gzip圧縮を有効にする
port: 3000, // 開発サーバーのポート番号
open: true, // サーバー起動時にブラウザを自動で開く
hot: true, // ホットモジュールリプレイスメントを有効にする
},
// ソースマップの設定 (デバッグ用)
devtool: "eval-source-map",
};
これらの設定ファイルが揃ったら、npm start
で開発サーバーを起動し、npm run build
で本番用のビルドを行うことができます。