webpack4でバンドルのファイル名にバージョン番号を付与する方法、productionとdevelopmentモードで出し分ける方法メモ

#概要
webpack4を使って以下のようなことをしたいときのやりかたメモです。

- 出力するバンドルのファイル名にバージョン番号を付与する方法
- productionモードとdevelopmentモードでバンドルのファイル名を変える方法
- developmentモードのときだけ source-map を出力する方法
- productionモードの場合には console.log を消す方法


# 出力するバンドルのファイル名にバージョン番号を付与したい

ライブラリを作るときなど、package.jsonで指定したバージョン番号を持ってきて、 **lib-1.3.0.js** のようにバージョン番号をつけて出力する

```webpack.config.js
const packageJson = require('./package.json');
const version = packageJson.version;
const path = require("path");
module.exports = {
    mode:'development',
    entry: {
        lib: './src/lib.js',
    },
    output: {
        path: path.join(__dirname, "dist"),
        filename: `[name]-${version}.js`,
        libraryTarget: 'umd'
    }
};

```

package.jsonは以下のような感じ

```package.json
{
  "name": "lib",
  "version": "1.3.0",
  "main": "index.js",
  "scripts": {
    "build": "webpack --config webpack.config.js",
   },
  ...（以下略)
}
```

ポイントはここ。package.jsonをひっぱってきて、バージョン番号をversionという変数にいれる。

```js:webpack.config.js抜粋
const packageJson = require('./package.json');
const version = packageJson.version;
```

実行すると、

```shell
npm run build

Hash: c45a905967f1a00277db
Version: webpack 4.28.2
Time: 225ms
Built at: 2018-12-24 01:05:19
       Asset      Size  Chunks             Chunk Names
lib-1.3.0.js  39.6 KiB       0  [emitted]  lib
```

バージョンつきのファイル名をもつ **lib-1.3.0.js** が無事生成された。


# modeの値(productionかdevelopment)によって出し分けたい

## modeを指定してwebpackを呼び出す

以下のように、**--mode production** のようにすると、モードを指定してwebpackを呼び出すことができる。

```package.json
{
  "name": "lib",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "build": "webpack --config webpack.config.js --mode production",
   },
  ...（以下略)
}
```


```shell
npm run build
```


## productionとdevelopmentで出力ファイル名を変えたい

**webpack --config webpack.config.js --mode production**のような呼び出し方法のときに、**mode** が何であるかを判定するために、webpack.config.jsを以下のような形式に書き換える。

```webpack.config.js
const packageJson = require('./package.json');
const version = packageJson.version;
const path = require("path");
module.exports = (env, argv) => {
    const conf = {};
    return conf;
};
```

これによって、argvの中にコマンドラインで指定した引数等が入ってくるようになる。
さっそく **mode** の値をみてファイル名を変更するスクリプトか書く

```js:webpack.config.js(modeの値をみてファイル名を変更する)
const packageJson = require('./package.json');
const version = packageJson.version;
const path = require("path");
module.exports = (env, argv) => {
    const conf = {
        entry: {
            lib: './src/lib.js',
        },
        output: {
            path: path.join(__dirname, "dist"),
            filename: argv.mode === 'production' ? `[name]-${version}.min.js` : `[name]-${version}.js`,
            libraryTarget: 'umd'
        }
    };
    return conf;
};

```

**argv.mode**に**-mode production**で指定した**production**が入ってくる。
ここでは

```js
filename: argv.mode === 'production' ? `[name]-${version}.min.js` : `[name]-${version}.js`,
```

productionのときにはファイルのminifyが行われるので、productionのときは**.min.js**という名前をつけるようにした。

さっそく実行してみる

```shell
webpack --config webpack.config.js --mode production

Hash: c45a905967f1a00277db
Version: webpack 4.28.2
Time: 222ms
Built at: 2018-12-24 01:13:53
           Asset      Size  Chunks             Chunk Names
lib-1.3.0.min.js  39.6 KiB       0  [emitted]  lib
```

**.min.js**つきのファイル名をもつ **lib-1.3.0.min.js** が無事生成された。


```shell
webpack --config webpack.config.js --mode development

Hash: 4f89417aa5c54bc94248
Version: webpack 4.28.2
Time: 191ms
Built at: 2018-12-24 01:15:12
       Asset     Size  Chunks             Chunk Names
lib-1.3.0.js  102 KiB     lib  [emitted]  lib
Entrypoint lib = lib-1.3.0.js
```

**--mode development**の場合は、ちゃんと**lib-1.3.0.js** が生成された、ということで、想定どおりうごいた。

# developmentの場合だけ source-map を出力したい

こんな感じ。

```webpack.config.js
const packageJson = require('./package.json');
const version = packageJson.version;
const path = require("path");
module.exports = (env, argv) => {
    const conf = {
        entry: {
            lib: './src/lib.js',
        },
        output: {
            path: path.join(__dirname, "dist"),
            filename: argv.mode === 'production' ? `[name]-${version}.min.js` : `[name]-${version}.js`,
            libraryTarget: 'umd'
        }
    };

    if (argv.mode === 'development') {
        conf.devtool = 'inline-source-map';
    }
    return conf;
};

```

ポイントはここ。developmentが指定されていることを判定して、その場合だけsource-mapを出力するようにする

```js
 if (argv.mode === 'development') {
        conf.devtool = 'inline-source-map';
    }
```

# productionの場合には、 console.log を消したい(おまけ)

productionの時は console.log を消したいので、minimizerをカスタマイズする。


```js:webpack.config.js

const packageJson = require('./package.json');
const version = packageJson.version;
const path = require("path");
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

module.exports = (env, argv) => {
    const conf = {
        entry: {
            lib: './src/lib.js',
        },
        output: {
            path: path.join(__dirname, "dist"),
            filename: argv.mode === 'production' ? `[name]-${version}.min.js` : `[name]-${version}.js`,
            libraryTarget: 'umd'
        },
        optimization: {
            minimizer: [
                new UglifyJSPlugin({
                    uglifyOptions: {compress: {drop_console: true}},
                }),
            ],
        }
    };

    if (argv.mode === 'development') {
        conf.devtool = 'inline-source-map';
    }
    return conf;
};

```

ポイントはここUflifyJSPluginを追加して、設定にて **drop_console: true** にする。

```js
 optimization: {
            minimizer: [
                new UglifyJSPlugin({
                    uglifyOptions: {compress: {drop_console: true}},
                }),
            ],
        }
```