Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

webpack.config.jsのプラクティスを考えてみた

何度もwebpack.config.jsを手書きしていて面倒くさくなってきたので、ここに書き方を残しておきます。

webpack.config.jsを書く際によく使うTipsとして、これらが挙げられます。

  • mode: env.mode || 'development'
  • path.resolve(__dirname, path_to_file)を使う
  • options.resolve.extensionsに読み込みたいファイルの拡張子を記述
  • entryを複数書くとoptions.output.filename'[name].min.js'のように指定できる
  • loaderはoptiopns.module.rulesに書き込む

ひとまずテンプレ

最初にwebpack.config.jsのテンプレを載せておきます。どうせ未来の僕がこの記事を読むときは、このテンプレを見たいときだけなので。

const path = require('path');

module.exports = (argv, env) => ({
    mode: env.mode || 'development',
    entry: path.resolve(__dirname, './src/main.js'),
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, './dist'),
    },
    module: {
        rules: [],
    },
});

記事の後半の内容が必要そうなら使うバージョン。

const path = require('path');

module.exports = (argv, env) => ({
    mode: env.mode || 'development',
    entry: path.resolve(__dirname, './src/main.js'),
    // entry: {
    //     main: path.resolve(__dirname, './src/js/main.js'),
    //     index: path.resolve(__dirname, './src/js/index.js'),
    //     gallery: path.resolve(__dirname, './src/js/gallery.js'),
    // },
    // resolve: {
    //     extensions: ['.js'],
    // },
    output: {
        // filename: '[name].min.js',
        filename: 'bundle.js',
        path: path.resolve(__dirname, './dist'),
    },
    module: {
        rules: [
            // {
            //     test: /\.css$/,
            //     use: ['to-string-loader', 'css-loader'],
            // },
        ],
    },
});

mode: env.mode || 'development'

この設定をしておくと、package.json内で開発ビルドとプロダクションビルドをカンタンに切り替えることができます。

  "scripts": {
    "build": "webpack --mode production",
    "build:dev": "webpack",
    ...
  },

応用として、options.output.filenameを書き換えることもできます。

{
    output: {
        filename: env.mode == 'production' ? 'bundle.min.js' : 'bundle.js'
    }
}

path.resolveを使う

pathモジュールのpath.resolveメソッドを使ってファイルパスを指定するようにします。例えばoptions.entryoptions.output.pathなどで使うといいです。

なぜわざわざpath.resolveを使うかという理由は webpack.config.jsで思ったpath.resolveって何のためにあるの?に書いてあります。

Windowsとかだとパス区切りが/じゃないこともあるみたい。バックスラッシュっていうやつ(\)。だから__dirname + '/src'だとパスがおかしくなってしまうことがあるからpath.resolveを使って安心安全で行こうぜ!ってことらしい。 (引用: webpack.config.jsで思ったpath.resolveって何のためにあるの?)

環境間の差異を吸収する目的のようです。

読み込みたいファイルの拡張子はoptions.resolve.extensions に

よく忘れるので書いただけです。特に解説することはないです。

entryが複数あるときのoutput.filenameの書き方

これはそこまで頻度高くないです。

{
    entry: {
        main: path.resolve(__dirname, './src/main.js'),
        sub1: path.resolve(__dirname, './src/sub1.js'),
        sub2: path.resolve(__dirname, './src/sub2.js'),
    },
    output: {
        filename: '[name].bundle.js'
    }
}

loaderは optiopns.module.rules に書き込む

めちゃくちゃ当たり前なんですが、手書きすると「あれ?どこに書くんだっけ?」となるので書いておきます。

参考

webpack.config.jsで思ったpath.resolveって何のためにあるの?