Webpack使用時のpackage.jsonデータの取り扱いに注意

どのような状況だったか?

Webpack 3.8.1を使用しており、webpack buildを実行した後、main.[chunkhash:8].jsが生成されました。

その際、私のpackage.jsonのデータがmain.xxxx.jsファイルに含まれてしまっていました。

これをサービスにデプロイした際、セキュリティ上の問題となりました。

実際、私は独自のプライベートnpmリポジトリにあるプライベートnpmモジュールを使用していました。

この時点で、誰かが私のmain.jsファイルを読み、package.jsonのデータを取得してしまったのです。

その後、その人物は私がpackage.jsonで個人的に作成したモジュールと同じ名前のモジュールを作成し、パブリックnpmリポジトリにアップロードしました。

0.0.1から9.9.9までのすべてのバージョンがアップロードされてしまったのです。

このため、Jenkinsビルド中にパブリックnpmデータを先に読みに行く私のビルドサーバーは、毎回ビルドに失敗するようになってしまいました。

解決策は?

ロギング用のHOC JSXファイル内に、以下のようなimport {version} from package.jsonという記述を見つけました。

import {version} from '../package.json'

Webpackでプロダクションモードでビルドすると、package.jsonのすべてのデータがmain.xxxx.jsに実装されてしまっていました。

そこで、そのコードを削除しました。

代わりにwebpack.DefinePluginを使用しました。これは、Webpackのビルド時に保存されたデータをグローバル変数として利用できるようにするものです。

現在のサービスのバージョンを独立したグローバル変数に保存し、実際に使用される際にその変数からpackage.jsonのバージョン情報を読み込むようにしました。

webpack.config.js
const defined = {'process.package': { VERSION:JSON.stringify(packageConfig.version)}}
module.exports = {
   ...
   plugins : [
      new webpack.DefinePlugin(defined),
      ...
   ],
   ...
log.hoc.jsx
const logInfo = { version: process.package.VERSION, ... }

結論

Babelと一緒にWebpackを使用する際、プリセットでmodules:falseを設定していました。

そのため、import {version} from 'package.json'のようなコードを使えばTree Shakingが行われ、バージョン情報だけがmain.xxxx.jsバンドルファイルに含まれると考えていました。しかし、そうではありませんでした。

今では、ファイルのimportrequireと同じように動作するため、Tree Shakingが機能していなかったことがわかりました。

振り返ってみると、恥ずかしい経験でした。

Stay Hungry, Stay Foolish