俺の webpack.config.js-20200503

基本思想

  • とにかく薄く。必要なものだけ。基本は ts-loader を transpileOnly: true で使うだけ。最悪これだけでいい。型チェックはIDEyarn tsc -p . --noEmit でやる。
  • CRA や parcel は使わない。暗黙な振る舞いが多すぎるので。一切勉強したくない人はいれていいと思うが、その場合 eject しない、dist ディレクトリをそのまま使うこと前提。
  • style-loader/css-loader は外部CSSを読むときに設定する
  • worker-plugin はなくてもいいけど、 worker もビルドしたいことが多いので、入れていることが多い
  • html-webpack-plugin と webpack-dev-server 組み合わせると、他と組み合わせずに完結して動く。このHTMLを本番で使わずとも、デバッグで使ってることが多いので常に入れてる
  • デフォルトの src/index をentry, dist/main.js を出力するのはそのままで、複数ファイルになったらいじる

期待している構造

src/index.ts(x)
src/index.html
package.json
tsconfig.json
--- ignore ---
dist/*
node_modules/*

install

yarn init -y # package.json がない場合
yarn add webpack webpack-cli webpack-dev-server ts-loader html-webpack-plugin worker-plugin style-loader css-loader typescript -D
# or npm install --save-dev ...

webpack.config.js (最小)

module.exports = {
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: {
          loader: "ts-loader",
          options: {
            transpileOnly: true,
          },
        },
      },
    ],
  },
  resolve: {
    extensions: [".js", ".ts", ".tsx", ".json", ".mjs", ".wasm"],
  },
};

webpack.config.js (通常)

const path = require("path");
const HTMLPlugin = require("html-webpack-plugin");
const WorkerPlugin = require("worker-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: {
          loader: "ts-loader",
          options: {
            transpileOnly: true,
          },
        },
      },
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"]
      },
    ],
  },
  resolve: {
    extensions: [".js", ".ts", ".tsx", ".json", ".mjs", ".wasm"],
  },
  plugins: [
    new HTMLPlugin({
      template: path.join(__dirname, "src/index.html"),
    }),
    new WorkerPlugin()
  ],
};

tsconfig.json

module: commonjs だと tree shaking (未 import のコードを削る機能)が効かない。tree shaking するために、 module: esnext を設定する。 あと個人的には "moduleResolution": "node"esModuleInterop: true も必須だと思っている。あとはお好きに。

{
  "compilerOptions": {
    "target": "es2019",
    "module": "esnext",
    "moduleResolution": "node",
    "jsx": "react",
    "strict": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true
  }
}

(大抵はnodeの細かいユーティリティ使うために yarn add @types/node もしている)

package.json scripts

  "scripts": {
    "build": "webpack --mode production",
    "dev": "webpack-dev-server",
    "typecheck": "tsc -p . --noEmit"
  },

CI で typecheck を走らせる。watch ビルド時に常に型チェックするのはCPUの無駄。

dev では、html-webpack-plugin が入っているので、index.html も生成され、localhost:8080 でプレビューできる

(このとき index.html に entry の script タグが自動挿入されるので、書かなくて良い)

netlify にデプロイ

yarn build (npm run build) して、生成された dist をどこかのホスティングサイトにアップロードしたら終わり。

yarn build # 生成

npm i -g netlify-cli
netlify deploy -d dist --prod