webpackとbabelでReactを使える環境を作成する

webpack

JavaScriptのモジュールバンドラー。
Webpackでビルドすることでnode_modulesの依存関係を解消し、1つのJSファイルにまとめることができる。

Babel

JavaScriptのトランスコンパイラー。
元々はES6のコードをES5に変換するため「6to5」という名前で作成された。
新記法で書かれたコードを、それらの機能をサポートしていないブラウザでも動く古記法のコードに変換することができる。

環境構築

以下の記事を参考に作成した。

必要なモジュールのインストール

mkdir react_test
cd react_test

# プロジェクトの初期化
npm init -y

# Babelを使用するのに必要なモジュール
npm i -D @babel/core # Babel本体
npm i -D @babel/preset-env # 必要なプラグインを自動で選択して変換処理しれくれるpresets
npm i -D @babel/preset-react @babel/preset-typescript # React, Typescript用

# Webpackを使用するのに必要なモジュールなど
npm i -D webpack webpack-cli babel-loader ts-loader
npm i -D webpack-dev-server html-webpack-plugin

# Reactを使用するのに必要なモジュールを追加
npm i -S react react-dom # jsxコードを使用してReactを記述する
npm i -D typescript @types/react @types/react-dom

# tsconfig.json 生成
npx tsc init

ファイルを作成・編集

tree .
.
├── dist
│   ├── index.html
│   ├── main.js
│   └── main.js.LICENSE.txt
├── node_modules
│   └── 依存関係のファイル
├── package-lock.json
├── package.json
├── src
│   ├── index.html
│   └── index.tsx
├── tsconfig.json
└── webpack.config.js

src/index.html

<!DOCTYPE html>
<html lang="ja">
  <body>
    <div id="app"></div>
  </body>
</html>

src/index.tsx

import React from "react";
import { render } from "react-dom";

const App = () => {
  return <h1>Hello World!</h1>;
};
render(<App />, document.getElementById("app"));

.babelrc

Babelの変換方法設定ファイル

Plugins:Babelでどのようにコードを変換するかを定義したJSのプログラム
Presets:複数のプラグインを目的に応じてパッケージとして集約する仕組み

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

package.json

{
  "name": "react_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack serve",
    "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のビルド設定ファイル

{
    "compilerOptions": {
      "target": "es5", // トランスコンパイル後のバージョンを指定
      "module": "commonjs",
      "outDir": "dist",
      "strict": true,
      "moduleResolution": "node",
      "allowSyntheticDefaultImports": true,
      "esModuleInterop": true,
      "skipLibCheck": true,
      "forceConsistentCasingInFileNames": true,
      "jsx": "react"
    },
    "include": ["src"]
  }

webpack.config.js

Webpackのバンドル設定ファイル

// 絶対パスを参照するためのモジュール
const path = require("path");

// HTMLファイルを生成するためのモジュール
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  mode: "development",
  // エントリポイントを指定
  entry: "./src/index.tsx",
  // 作成したバンドルを出力する場所を指定
  output: {
    path: path.resolve(__dirname, "dist/"), 
  },
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/, // 変換するファイルを指定
        use: ["ts-loader"], // 変換するためのローダーの指定
                            // WebpackはJSとJSONのみを理解するがローダーを用いることでほかのファイルを理解できるようになる。
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
  ],
  devServer: {
    static: {
        directory: path.join(__dirname, "dist/"),
      },
  },
};
Tags: