345
262

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

webpack.config.js 最小設定

Last updated at Posted at 2018-07-19

巷で webpack 難しいという声が大きいですが、個人的に初期設定でハマるものではないと思っていて(複雑なローダーを複雑に使うとハマる)、勘所掴めるような小さい例を紹介します。

bundle only

src/index.js => public/bundle.js にコンパイルするだけ。babel を使わない。

npm install webpack webpack-cli --save-dev
webpack.config.js
module.exports = {
  mode: process.env.NODE_ENV || "development",
  entry: ["./src/index.js"],
  output: {
    filename: "bundle.js",
    path: __dirname + "/public"
  }
};
## build for dev
npm run webpack

## watch for dev
npm run webpack -w

## build for prod
NODE_ENV=production npm run webpack

-w はなかなか便利で、ファイルに変更があるたびに自動ビルドします。依存ファイルの依存グラフを構成しつつオンメモリに持ってるので、再ビルドが高速です。どれぐらい高速化というと 8秒が0.2秒になったりします。

bundle with babel

npm install webpack webpack-cli webpack-serve --save-dev
npm install babel-loader@^8.0.0-beta @babel/core @babel/preset-env --save-dev
echo '{ "presets": ["@babel/preset-env"] }' > .babelrc
webpack.config.js
module.exports = {
  mode: process.env.NODE_ENV || "development",
  entry: ["./src/index.js"],
  output: {
    filename: "bundle.js",
    path: __dirname + "/public"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: "babel-loader",
        exclude: /node_modules/
      }
    ]
  }
};

コマンドは同じなので略

with html serve

webpack-serve と html-webpack-plugin を使って、 bundle した js を読み込む index.html を生成しつつ localhost にサーバーを立てます。

注意点として webpack-serve は --watch と同様にサーバー内のインメモリにビルドしたファイルを構成し、それを返却するのでファイルIOがなく速いのですが、public 以下にファイルを出力しません。

yarn add webpack webpack-cli webpack-serve html-webpack-plugin -D
yarn add babel-loader@^8.0.0-beta @babel/core @babel/preset-env -D
echo '{ "presets": ["@babel/preset-env"] }' > .babelrc
webpack.config.js
const HtmlPlugin = require("html-webpack-plugin");
module.exports = {
  mode: process.env.NODE_ENV || "development",
  entry: ["./src/index.js"],
  output: {
    filename: "bundle.js",
    path: __dirname + "/public"
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: "babel-loader",
        exclude: /node_modules/
      }
    ]
  },
  plugins: [new HtmlPlugin()]
};
npm run webpack-serve --port 4000

デプロイする際は同様に npm run webpack して生成物を配布します。

任意な html を初期状態にしたい場合は new HtmlPlugin({ template: 'src/index.html'}) のように自分で指定した HTML を指定します。

これがいわゆるSPAのスタートラインです。

未来へ向けて

最近のフロントエンドでwebpackの乱用がすぎるのはそうだと思っていて、とはいえ利用者がアレもコレもやろうとして、勝手にハマってるだけなところが大きいと思います。

例えば代表的なのが css-modules をやろうとすると複数の loader を複雑に使って実現していて、webpack 2系から 3系に上げられなくて爆死、という例が多いですね。単体で難しいわけじゃないですが、loader 組み合わせで爆発するのもwebpackの特徴です。

webpack はES Modules が最適化される前の必要悪であって、IEが死んだ未来の時点でサッと webpack を抜いてもそのまま動くようなコードが理想です。なので require 使わず ESM の import/export だけ使うみたいな感じにがたぶん痛くない設計です。

とはいえ ES Modules の静的解析を行って読み込みを最適化するのが実装されるのはだいぶ先の未来だと思われます。たとえば nginx が JS の依存の静的解析が行ってhttp/2のストリームに最適にパケットを詰める、みたいな未来がこなくてはなりません。アセットサーバーが依存解析して先読みのグラフを作る仕様が必要です。

少なくても現時点から5年先ぐらいは 一つのファイルに bundle するのが最適解だと思われます。もしかしたら10年さきもやってるかもしれません。ないといいですね。

345
262
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
345
262

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?