node_modules から必要なファイルのみを抜き出す

2020年1月30日 14:47

これは実際のケースを見てもらったほうが早いだろう。たとえば、HTML ファイルの中で以下のような js ファイルの読み込みを行なっていたとしよう。

<script src="../node_modules/lodash/lodash.js"></script>
<script src="../node_modules/moment/min/moment-with-locales.js"></script>
<script src="../node_modules/angular/angular.js"></script>
<script src="../node_modules/angular-moment-picker/dist/angular-moment-picker.js"></script>
<script src="../node_modules/angular-loading-bar/build/loading-bar.js"></script>
<script src="../node_modules/angular-toastr/dist/angular-toastr.tpls.js"></script>
<script src="../node_modules/angularjs-dropdown-multiselect/dist/angularjs-dropdown-multiselect.min.js"></script>
<script src="../node_modules/ui-bootstrap4/dist/ui-bootstrap.js"></script>
<script src="../node_modules/ui-bootstrap4/dist/ui-bootstrap-tpls.js"></script>

これがあるせいで、サーバへは肥大した node_modules フォルダもアップロードしなくてはならない。Google App Engine(GAE)の場合も、デプロイ対象から外すわけにはいかなくなる。

今回はこの悩みを解決すべく、gulp のスクリプトを使ってこれらのファイルをひとまとめにし、ついでに minify も行なってしまおうというわけだ。

gulpfile.js に追加するのは以下のとおり。gulp 自体のセットアップや、必要なモジュールのインストールなどは済ませている前提ね。

gulp.task('js.bundle', function() {
  return gulp.src([
    '../node_modules/lodash/lodash.js',
    '../node_modules/moment/min/moment-with-locales.js',
    '../node_modules/angular/angular.js',
    '../node_modules/angular-moment-picker/dist/angular-moment-picker.js',
    '../node_modules/angular-loading-bar/build/loading-bar.js',
    '../node_modules/angular-toastr/dist/angular-toastr.tpls.js',
    '../node_modules/angularjs-dropdown-multiselect/dist/angularjs-dropdown-multiselect.min.js',
    '../node_modules/ui-bootstrap4/dist/ui-bootstrap.js',
    '../node_modules/ui-bootstrap4/dist/ui-bootstrap-tpls.js'
  ]).pipe(plumber({ errorHandler: notify.onError('<%= error.message %>') }))
    .pipe(concat('bundle.js'))
    .pipe(uglify())
    .pipe(rename('bundle.min.js'))
    .pipe(gulp.dest('scripts'));
});

これを実行すると、gulpfile.js と同じ場所にある scripts ディレクトリの中に bundle.min.js というファイルが作成されるので、冒頭の HTML をごっそり以下に置き換えてしまえばオーケー(/path/to/ の部分は適宜)。

<script src="/path/to/scripts/bundle.min.js"></script>

何か新しい js ライブラリが必要になった場合は、この gulpfile.js に追記し、当該タスクを実行するだけ。追加する頻度はそんなに高くないだろうから、自分的にはこれがベストな方法かと思う。

css ファイルの場合は、こんな感じ。

gulp.task('css.bundle', function() {
  return gulp.src([
    '../node_modules/ui-bootstrap4/dist/ui-bootstrap-csp.css',
    '../node_modules/angular-moment-picker/dist/angular-moment-picker.css',
    '../node_modules/angular-loading-bar/build/loading-bar.css',
    '../node_modules/angular-toastr/dist/angular-toastr.css',
    '../node_modules/@fortawesome/fontawesome-free/css/all.css'
  ]).pipe(plumber({ errorHandler: notify.onError('<%= error.message %>') }))
    .pipe(concat('bundle.css'))
    .pipe(cleanCss())
    .pipe(rename('bundle.min.css'))
    .pipe(gulp.dest('css'));
});