LoginSignup
38
29

More than 5 years have passed since last update.

今時のwebpackの構成

Posted at

webpack4がリリースされていて、ちょっと調べて行く中で、webpack.configの構成方法を工夫した方がいいんだと言うことを知りました。
公式でも解説されている事なのですが、webpack.configを以下のように構成するのが、今時なんだそうです。

  • 共通のwebpack.config = webpack.common.js
  • 開発用のwebpack.config = webpack.dev.js
  • リリース用のwebpack.config = webpack.prod.js

この方が、シンプルに考えられるよねってことです。

webpack-mergeのインストール

この構成で、webpack.configを構成するには、webpack-mergeが必要になります。
開発用とリリース用のwebpack.configに、共通のwebpack.configを取り込むために、webpack-mergeを使います。

npm install webpack-merge --save-dev

共通のwebpack.configを作成

開発用とリリース用で共通となる部分のwebpack.configを、webpack.common.jsとして作成します。

webpack.common.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const glob = require('glob');

module.exports = {
    entry: {
        server: './src/server/main.ts',
        assets: glob.sync('./src/server/assets/**/*')
    },
    target: 'node',
    node: {
        __dirname: false,
        __filename: false
    },
    externals: [
        nodeExternals()
    ], 
    module: {
        rules: [
            {
                test: /\.ts$/,
                use: [
                    // 下から順に処理される
                    {
                        loader: 'ts-loader',
                        options: {
                            configFile: 'src/server/tsconfig.server.json'
                        }
                    },
                    {
                        loader: 'tslint-loader',
                        options: {
                            typeCheck: true,
                            // tslint時に自動的に修正しない
                            fix: false,
                            // warningをエラーにすることでその後のビルドを止める
                            emitErrors: true
                        },
                    },
                ],
                exclude: /(node_modules|client)/
            },
            {
                test: /\.txt$/,
                use: {
                    loader: 'file-loader'
                },
                exclude: /(node_modules|client)/
            }
        ]
    },
    resolve: {
        extensions: [ '.ts', '.txt' ]
    },
    plugins: [
        new BundleAnalyzerPlugin({
                openAnalyzer: false,
                generateStatsFile: true,
                analyzerMode: 'static',
                reportFilename: '../../report.html',
                statsFilename: '../../stats.json'
            })
    ],
    output: {
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist/server'),
        publicPath: path.resolve(__dirname, 'dist/server')
    }
};

開発用のwebpack.configを作成

開発用として必要になる構成、例えばmodeをdevelopmentにするとか、devtoolでソースマップを作成するとかを指定します。
共通として作成したwebpack.common.jsを取り込む必要があるので、webpack-mergeを使います。

webpack.dev.js
const merge = require('webpack-merge');
const common = require('./webpack.common');

module.exports = merge(common, {
    mode: 'development',
    devtool: 'source-map'
})

リリース用のwebpack.configを作成

今度はリリース用として必要になる構成、例えばmodeをproductionにするとかを指定します。
こっちでも、共通として作成したwebpack.common.jsを取り込む必要があるので、webpack-mergeを使います。

webpack.prod.js
const merge = require('webpack-merge');
const common = require('./webpack.common');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = merge(common, {
    mode: 'production',
    optimization: {
        minimizer: [
            new TerserPlugin({
                terserOptions: {
                    keep_classnames: true,
                    drop_console: true
                }
            })
        ]
    }
})

使い分け

以下のビルドするときのパラメータを変えると使い分けるとできます。

  • 開発するとき・・・webpack --config webpack.dev.js
  • リリースするとき・・・webpack --config webpack.prod.js

ただ、これだとPCで開発しているとき、Herokuにリリースするときを考えると、めんどくさいので、gulpを使う事にしました。
gulpfile.jsを以下のようにすると、NODE_ENVを見て、構成を変えることができます。

gulpfile.js
const gulp = require('gulp');
const webpack = require('webpack');
const webpackStream = require('webpack-stream');

const webpackConfigDev = require('./webpack.dev');
const webpackConfigProd = require('./webpack.prod');

// Node.jsのビルド(webpack)
gulp.task('build-server', () => {
    const webpackConfig = (process.env.NODE_ENV || 'development') === 'development' ? webpackConfigDev : webpackConfigProd;

    return webpackStream(webpackConfig, webpack)
            .pipe(gulp.dest('dist/server'));
});

すっきり!

38
29
0

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
38
29