やしログ

ビルドツール素振り(webpack編)

created: 2021/04/15
改めて、webpack を素振りしてみました。

以前の LT で、frontend のビルドツールについて話しました。(詳細は こちら )

そのとき調べたそれぞれのツールを使い、 create-react-app で作ったアプリケーションのビルドを試しました。

ここではその具体的な方法と、webpack(v5) を使ったビルドについて書きます。

アプリケーションの抜け殻を作成する

create-react-app (以下 CRA)を使ったアプリケーションは、webpack が同梱されており、既にビルド設定も済んでいる状態のものです。 しかし今回は、アプリケーションの内部実装は変えないまま、ビルドツール及び設定のみを変える、ということをしたいです。そのため、一度 CRA で作成したアプリケーションからビルドツールを取り除いたアプリケーション(ビルドできないので動かないのですが...w)を作成しました。

まずは CRA します。

$ npx create-react-app --template=typescript .

次にビルドツールを取り除きます。本来 yarn eject してから webpack (及び各種 loader)や webpack.config.js を取り除いていくほうがキレイですが、今回やりたかったことの本筋ではなかったため横着し、雑に以下を実行しました。

$ yarn remove react-scripts

次に package.json を一部編集します。

   "scripts": {
-    "start": "react-scripts start",
-    "build": "react-scripts build",
-    "test": "react-scripts test",
-    "eject": "react-scripts eject"
+    "start": "echo start",
+    "build": "echo build",
+    "test": "echo test"
   },

eject はこの際不要なので消します。それ以外については一旦ダミーで echo しておき、各ツールに応じたコマンドに変えていくことにしました。(結局テスト用の設定は行わなかったため、全てのツールで test は echo のままとなりました 😇)

さらに、 public/index.html%PUBLIC_URL% の記述を消します。

   <head>
     <meta charset="utf-8" />
-    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
+    <link rel="icon" href="favicon.ico" />
     <meta name="viewport" content="width=device-width, initial-scale=1" />
     <meta name="theme-color" content="#000000" />
     <meta
       name="description"
       content="Web site created using create-react-app"
     />
-    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
+    <link rel="apple-touch-icon" href="logo192.png" />
     <!--
       manifest.json provides metadata used when your web app is installed on a
       user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manif
     -->
-    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
+    <link rel="manifest" href="manifest.json" />
     <!--

この PUBLIC_URL は CRA 独自で定義している環境変数です。詳細は下記を参照下さい。

react-script を削除した今となっては HTML に書かれている必要がない(というより書かれていると動かない...orz)ため、消します。

これで、 CRA で作ったアプリケーションを元にしたビルドできない何か、ができあがりました。名前を付けたかったため、「アプリケーションからビルド部分を除いた抜け殻」というところから ヌケニン と呼ぶことにしました。

webpack v5 を使ったビルド設定をやってみる

さてこのヌケニンフォルダを元に、webpack のインストールからビルド設定までを改めて行ってみました。

まず、諸々必要なものをインストールします。

# webpack 本体を install
$ yarn add -D webpack webpack-cli

# ts, cssをbuildするために必要なloaderをinstall
$ yarn add -D ts-loader style-loader css-loader

# htmlも出力するためのplugin をinstall
$ yarn add -D html-webpack-plugin

# 開発環境用のdevServerをinstall
$ yarn add -D webpack-dev-server

webpack.config.js を作り、ビルド設定を書きます。

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

module.exports = {
  entry: './src/index.tsx',
  output: {
    filename: 'index.js',
    path: path.resolve(__dirname, 'public'),
  },
  target: 'web',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.svg/,
        type: 'asset',
      },
    ],
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.svg', '.js', '.json'],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, 'public/index.html'),
    }),
  ],
  devServer: {
    contentBase: path.resolve(__dirname, 'public'),
    watchContentBase: true,
  },
};

.svg のバンドルに関して、以前は url-loader 等が必要でしたが、webpack v5 から asset management の機能が追加され、標準でバンドルできるようになりました。

あとは package.json 内の script を書き換えます。

"scripts": {
-    "start": "echo start",
-    "build": "echo build",
+    "start": "webpack serve --open --mode=development",
+    "build": "webpack --mode=production",
     "test": "echo test"
   },

これで完了です 🎉

yarn start で CRA と同じ結果をローカルで表示でき、コードを変更すると直ちに反映されます。さらに、 yarn build で production 向けのビルドができます。

改めて webpack を使ったビルド設定を行ってみました。特に、v5 から追加された asset management は使いやすいなーという印象です。標準でできることが増えすぎてほしくないなという気持ちもありつつ、これからも程よく便利になってくれると良いなーと思いました。

ここまでの内容は下記に置いています。

引き続き、他のビルドツールの記事も書いていこうと思います 💪