🐕

Webpackとは【Webpack + TypeScript + React で環境構築】

5 min read

Webpackとは

複数のモジュールを1つにまとめて出力できる。モジュールバンドラ。
loderを用いることでjsファイル以外をまとめることができる。

利点

  • JavaScriptモジュール間の依存関係を解決
    従来はhtml側からのJSファイルの読み込み順を自身で考えなければならなかった。WebpackではJSファイル間の依存関係を移動で解析して、まとめてくれる。
    Dependency Graph
  • 読み込み回数を減らせる
    1つのファイルにビルドしてから読み込むため
  • コード変換
    Node.jsのみで使える記法などをブラウザでも使えるように変換できる

WebpackでReactの環境構築

リポジトリ: https://github.com/Ichigo-dev/webpack-test-react

package.jsonの作成

$ npm init -y

webpackインストール

$ npm install -D webpack webpack-cli webpack-dev-server html-webpack-plugin

wepack本体、CLI、開発用サーバとwebpackで生成したファイルを読み込んだHTMLを出力するためのプラグインhtml-webpack-pluginをインストール。

Babelインストール

$ npm install -D @babel/core @babel/runtime @babel/plugin-transform-runtime @babel/preset-env babel-loader

Babel本体とプラグイン、プリセットの設定、webpackのローダーをインストール。

Reactインストール

$ npm install react react-dom
$ npm install -D @babel/preset-react

React, React-Dom, Babelのプリセットをインストール。

Reactアプリ作成

/src配下に適当なアプリを作成する。
index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>React App</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>

app.js

import React from 'react';
import ReactDom from 'react-dom';
import HelloWorld from './HelloWorld';

ReactDom.render(
  <React.StrictMode>
    <HelloWorld />
  </React.StrictMode>,
  document.getElementById('app')
);

HelloWorld.jsx

import React from 'react';

const HelloWorld = () => <h1>Hello World!!</h1>;
export default HelloWorld;

Webpack設定

webpack.config.jsを作成。

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

module.exports = {
  mode: "development",
  entry: path.resolve(__dirname, "src/app.js"),
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "app.js",
  },
  resolve: {
    modules: [path.resolve(__dirname, "node_modules")],
    extensions: [".js", ".jsx"],
  },
    module: {
    rules: [
      {
        test: [/\.js$/, /\.jsx$/],
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: ["@babel/preset-env", "@babel/preset-react"],
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "src/index.html"),
    }),
  ],
  devServer: {
      contentBase: path.join(__dirname, "dist"),
    },
};

設定としてはwebpackの設定、Babelの設定、プラグインの読み込み、開発サーバの設定。
webpackの出力先ディレクトリとしてdistを作成。

ビルド&実行

$ npx webpack serve --config webpack.config.js

localhost:8080 で 「Hello World!!」が確認できる。

TypeScriptを使用する

$ npm install -D typescript ts-loader @babel/preset-typescript @types/react @types/react-dom

TypeScriptとWebpackのローダー,Babelのプリセット,Reactの型定義ファイルをインストール。
次にTypeSriptの設定ファイルtsconfig.jsonを作成。

{
  "compilerOptions": {
    "target": "esnext",
    "jsx": "react",

    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "moduleResolution": "node",
    "esModuleInterop": true,
    "isolatedModules": true,
    "allowSyntheticDefaultImports": true,
  },
  "include": ["src/**/*.ts", "src/**/*.tsx"],
  "exclude": ["node_modules"]
}

次にwebpack.config.jsを修正する。

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

module.exports = {
  mode: "development",
  entry: path.resolve(__dirname, "src/app.tsx"), // エントリーポイント修正
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "app.js",
  },
  resolve: {
    modules: [path.resolve(__dirname, "node_modules")],
    extensions: [".js", ".ts", ".tsx"], // ts, tsx 追加
  },
    module: {
    rules: [
      {
        test: [/\.ts$/, /\.tsx$/],
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"], // typescript追加
            },
          },
          'ts-loader' // ts-loader追加
        ],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "src/index.html"),
    }),
  ],
};

src/*.js=>src/*.tsxに更新。
app.tsx

import * as React from "react";
import ReactDOM from "react-dom";
import HelloWorld from "./HelloWorld";

ReactDOM.render(
  <React.StrictMode>
    <HelloWorld />
  </React.StrictMode>,
  document.getElementById("app")
);

HelloWorld.tsx

import * as React from "react";

const HelloWorld: React.FC = () => <h1>Hello World!!</h1>;

export default HelloWorld;

ビルドが通ることを確認する。

参考

https://webpack.js.org/configuration/
https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
https://enjoyworks.jp/tech-blog/6889
https://enjoyworks.jp/tech-blog/7337

Discussion

ログインするとコメントできます