⚒️

webpackでJS,React×JS,React×TSの開発環境を1から構築してみた

2023/01/08に公開

こんにちは!
スペースマーケットでフロントエンドエンジニアをしているmizukiです!

今回はwebpackで1からReact×TypeScriptの開発環境を構築する過程についてまとめていきたいと思います。
webpackの公式ドキュメントにはいきなりReact×TypeScriptの開発環境を構築する手順が書かれていますが、この記事では学習も兼ねてJavaScript → React×JavaScript → React×TypeScriptと段階を踏んで進めていきます。

学習しながらのアウトプットした記事なので、至らない点があればご指摘ください🙇‍♂️

webpackとは

まずはそもそもwebpackとは何かについて軽く触れておきます。
webpackとは「モジュールバンドラ」と呼ばれ、複数のファイルを1つに束ねる役割があります。
アプリを開発する際に必ずと言っていいほど、複数のファイルに分けて実装していくかと思います。
その複数のファイルのコードを1つのファイルにまとめてくれるツールで、1つのファイルにまとめて出力することを「バンドル」と呼びます。

ざっくり言うと、「人間が扱いやすいコードやファイル構成」を「プログラムが解釈しやすいコードやファイル構成」へよしなに変換してくれるやつ、といった立ち位置です。

webpackで開発環境を構築していく

ではwebpackで開発環境を構築していきたいと思います。
実装したコードは以下のリポジトリに上げていますので、よければ参考にしてください。
コミットと見出しを揃えたつもりなので、コミット単位で見ていただけるとわかりやすいかと思います。
https://github.com/mizuki0201/webpack_practice

0. 下準備

まずは専用のディレクトリを作り、そこでwebpackをインストールします。

% mkdir webpack_practice
% cd webpack_practice
% npm init -y 
// webpack本体と一緒に、cli上で動作するwebpack-cliと開発サーバーを立ち上げるためのwebpack-dev-serverもインストール
% npm install --save-dev webpack webpack-cli webpack-dev-server

あとはscriptをpackage.jsonに記載しておきましょう。
※buildはwebpack-dev-serverの機能に搭載されているのでstartコマンドのみ記述しています。

package.json
{
  // ...中略...
  "scripts": {
+   "start": "webpack-dev-server --open"
  },
}

1. jsファイルを読み込めるようにする

第一歩目としてjsファイルを読み込んで開発サーバーを立ち上げるところまで進めます。

まずはbabelをインストールします。

% npm install --save-dev babel-loader @babel/core @babel/preset-env

babelの設定をするために.babel.config.jsというファイルをプロジェクト直下に作成し、以下の設定を書き込みます。

.babel.config.js
module.exports = {
  presets: [ "@babel/preset-env" ],
};

presetという単語が出てきますが、これは直訳すると「前もって準備すること、初期設定」といった意味で、ざっくり言うとこれさえインストールして設定しておけば最低限のデフォルト設定を使えるようになります。
細かく設定したい場合は一つずつ記述していきますが、今回は開発環境を構築するところまでが目的なのでpresetを使用します。

次にwebpackの設定をしていきます。
webpack.config.jsをプロジェクト直下に作成し、以下のように記述します。

webpack.config.js
module.exports = {
  entry: "./src/index.js",
  output: {
    path: `${__dirname}/dist`,
    filename: "main.js",
  },
  devServer: {
    static: {
      directory: "./dist",
    },
  },
  mode: "development",
  module: {
    rules: [{ test: /\.js$/, loader: "babel-loader", exclude: /node_modules/ }],
  },
};

意味は以下の通りです。
entry:バンドル時に読み込むファイル
output:webpackでバンドルしたコードを出力する先のディレクトリとファイル名
devServer:開発サーバーを立ち上げた時に読み込むディレクトリ
mode:環境が開発か本番か
module:何か使用するモジュールがあれば記載(今回は先ほどインストールしたbabel-loaderを使用していきます)

ファイル構成は以下のようにします。

webpack_practice/
├── dist/  // バンドル後のファイルを出力するディレクトリ
│   ├── index.html  // 開発サーバーを立ち上げたときに読み込むhtml
│   └── main.js  // バンドル結果のファイル
├── src/  // 開発用ファイルを作成するディレクトリ
│   └── index.js // コードを書いていくファイル
└── 〜その他package.jsonや設定ファイルが諸々〜

webpack.config.jsで、バンドル後の出力はdist/main.jsと指定しているので、dist/index.htmlではmain.jsを読み込むようにしておきます。

dist/index.html
<!DOCTYPE html>

<html lang="ja">
  <head>
    <meta charset="UTF8"/>
    <title>webpack practice</title>
  </head>

  <body>
    <div id="app"></div>
    <script src="./main.js"></script>
  </body>
</html>

index.jsにJavaScriptの処理を書いていきます。
お好きなように書いて問題ないですが、例示として一応置いておきます。

src/index.js
console.log("webpack practice!!");

const text = document.createElement("p");
text.innerText = "Hello World!";

const app = document.getElementById("app");
app.appendChild(text);

ここまでできたら開発サーバーを立ち上げてみます。

% npm run start 

画面を見るとjsの処理が反映されているかと思います。
これでjsファイルを読み込んで開発サーバーを立ち上げるところまで完了です!

2. Reactを導入する

次はReactを導入していきます。
まずはライブラリをインストールします。

% npm install --save react react-dom
% npm install --save-dev @babel/preset-react

今回もpresetを使用するので、.babel.config.jsにReactのpresetを追加します。

.babel.config.js
{
module.exports = {
  presets: [
    "@babel/preset-env",
+   "@babel/preset-react"
  ],
};
}

次にjsxファイルを作成します。
今回はsrc/index.jsxとsrc/app.jsxを作成します。

src/index.jsx
import React from "react";
import ReactDom from "react-dom";
import App from "./app";

ReactDom.render(<App />, document.getElementById("app"));
src/app.jsx
import React from "react";

const App = () => (
  <div>
    <h1>welcome!</h1>
    <p>this is react development environment built by webpack!</p>
  </div>
);

export default App;

最後に、webpack.config.jsで今までは.jsを読み込んでいたので、.jsxに修正します。

webpack.config.js
module.exports = {
+ entry: "./src/index.jsx",
  output: {
    path: `${__dirname}/dist`,
    filename: "main.js",
	@@ -9,8 +9,13 @@ module.exports = {
      directory: "./dist",
    },
  },
+ resolve: {
+   extensions: [".js", ".jsx"],
+ },
  mode: "development",
  module: {
    rules: [
+     { test: /\.jsx$/, loader: "babel-loader", exclude: /node_modules/ },
    ],
  },
};

この状態で再度開発サーバーを立ち上げると、jsxファイルを正しく解釈して画面に表示できていることが確認できるかと思います。

3. TypeScriptを導入する

ようやく最終ステップです。
最後にTypeScriptを導入していきます。

まずはライブラリをインストールします。

% npm install --save-dev @babel/preset-typescript @types/react @types/react-dom

次にTypeScriptを解釈できるように.babel.config.jsにpresetの設定を追加します。

.babel.config.js
module.exports = {
  presets: [
    "@babel/preset-env",
    "@babel/preset-react",
+   "@babel/preset-typescript",
  ],
};

webpack.config.jsで.tsxファイルを読み込むように設定をします。

webpack.config.js
module.exports = {
+ entry: "./src/index.tsx",
  output: {
    path: `${__dirname}/dist`,
    filename: "main.js",
	@@ -10,12 +10,12 @@ module.exports = {
    },
  },
  resolve: {
+   extensions: [".js", ".jsx", ".ts", ".tsx"],
  },
  mode: "development",
  module: {
    rules: [
+     { test: /\.tsx$/, loader: "babel-loader", exclude: /node_modules/ },
    ],
  },
};

最後に以下コマンドでTypeScriptの設定ファイルであるtsconfig.jsonを追加します。

% npx tsc --init

このコマンドでファイルが自動で作成され、デフォルトの記述はされています。
細かい設定をする場合はファイルを編集しますが、今回は特に設定はいじりません。
warningが出ていたのでincludeとexcludeだけは追加しています。

tsconfig.json
{
  "compilerOptions": {
    // ...中略...
  },
+ "include": ["src/**/*.ts", "src/**/*.tsx"],
+ "exclude": ["node_modules"]
}

あとはindex.jsxとapp.jsxをtsxファイルに変えて、よしなに型定義を追加してみます。

src/app.tsx
import React, { FC } from "react";

type DisplayData = {
  description: string;
};

const App: FC = () => {
  const headText: string = "welcome!";
  const displayData: DisplayData = {
    description:
      "this is react and typescript development environment built by webpack!",
  };

  return (
    <div>
      <h1>{headText}</h1>
      <p>{displayData.description}</p>
    </div>
  );
};

export default App;

この状態でも正しくコードが読み込まれ、画面が表示されていることが確認できます。

これにてwebpackをインストールするところからReact×TypeScriptの開発環境を最低限構築することができました!
今回は開発環境を構築することを目的としていたので細かい設定などは何も触れていませんが、ここから細かく設定ができると考えるとまだまだ奥深いなと思います。

おわりに

最後に宣伝させてください!笑
弊社では一緒に働く仲間を募集しています。

エンジニアを育成しようという風潮があったり、技術スタックも日々新しいものを取り入れようとしていたり、エンジニアにとってはとても良い環境が揃っているのではないかと思います。
まずは話だけ聞いてみたいという方も大歓迎ですので、ぜひ興味ある方は以下からご応募ください!

https://www.wantedly.com/projects/1113570

https://www.wantedly.com/projects/1113544

https://www.wantedly.com/projects/1061116

https://spacemarket.co.jp/recruit/engineer/

スペースマーケット Engineer Blog

Discussion