ES6のファイルを自動で結合してミニファイする

前提

要素 バージョン 関連記事
node/npm 7.4.0/4.1.2 Debian8.7にMEAN開発環境を構築する
gulp 3.9.1 Babel+Gulpで始めるES6

概要

JavaScriptの次世代仕様ES6で記述された複数のJavaScirptファイルを、一つのファイルに結合し、ミニファイルする作業を自動化する。

ES6及びタスクを自動化させるgulpについては関連記事で触れているので割愛する。

JavaScriptファイルの結合について

HTTPでは基本的に1リクエスト1ファイルとなるため、クライント側で利用するJavaScriptファイルがN個あればN回余分にリクエストを発行することになってしまう。これは些細な違いとは言え、オーバーヘッドが積もりパフォーマンスの低下に繋がることもある。

そこで、複数のJavaScriptファイルを1ファイルに結合することで、JavaScriptファイルのリクエスト回数を1回に抑えることができる。

しかし、ファイルを一つにすることで、全てのファイルのスクリプトが集約するため、そのファイルの容量が増大してしまうデメリットがある。これについては、後述するミニファイの技術を用いることで緩和することができる。

JavaScriptファイルのミニファイについて

通常、プログラマがスクリプトを記述する際は、可読性などから、以下のように冗長的なコーディングを行う
– 適切な空白や改行
– 理解しやすい識別子
– コメント

しかし、これらは処理系にとっては無意味な要素であり、処理系の負担やファイルの容量を無駄に増やしてしまう。

そこで、以下の例のように、処理系にとって不要の情報を極限まで削る(ミニファイ)ことで、ファイルの容量を削減し、パフォーマンスを向上させることができる。

ミニファイ前

/* 2数の和を戻す関数 */
var getSum = function(number1 , number2) {
  return number1 + number2; // 計算結果を戻す
};

ミニファイ後

var getSum=function(b,a){return b+a};

ファイル結合とミニファイの自動化

ここでは、複数ファイルに分割して記述されたES6のコードを、タスクランナーツールgulpを用いて、以下の手順でファイルを変換する

  1. gulp-concatで一つのES6ファイルに結合する
  2. gulp-babelでES5ファイルに変換する
  3. gulp-uglifyでミニファイする

必要なnpmモジュールをインストール

node/npm/gulpインストール後、追加で下記のモジュールをインストールする

$ npm install --save-dev gulp-concat
$ npm install --save-dev gulp-uglify
$ npm install --save-dev gulp-rename

gulp-renameについては後述

gulpによる自動変換

gulpfile.js

var gulp = require('gulp'),
    concat = require("gulp-concat"),
    uglify = require("gulp-uglify"),
    babel = require('gulp-babel'),
    rename = require('gulp-rename');

gulp.task('js' , function() {
  gulp.src('scripts/*.js')
    .pipe(concat('main.js'))
    .pipe(babel({presets: ['es2015']}))
    .pipe(uglify())
    .pipe(rename('main.min.js'))
    .pipe(gulp.dest('build/'));
});

gulp.task('watch' , function() {
  gulp.watch('scripts/*.js' , ['js']);
});

gulp.task('default' , ['js' , 'watch']);

上記gulpfileは、gulp実行時及びscriptsディレクトリ内のjsファイルに変更があった場合に、jsタスクを実行する。

jsタスクは、scriptsディレクトリ内のjsファイルをconcatモジュールで結合し、babelモジュールでES5に変換後、uglifyモジュールでミニファイしている。

uglifyモジュールは、JavaScriptファイルをミニファイする機能を持っているが、それを別名で保存する機能を持っていない。そこで。renameモジュールを前項で別途インストールしておいたので、それを用いてファイル名を変換する。

実行例を以下に示す

実行前

hoge.js

/* カウンタを備えたモジュール */
let myModule = (function() {
  let n = 0;
  return {
    add: () => n++,
    get: () => n,
  };
})();

fuga.js

/* 2数の和を求める関数 */
let myFunction = (numberA , numberB) => numberA + numberB;

実行後

main.min.js

"use strict";var myModule=function(){var c=0;return{add:function b(){return c++},get:function a(){return c}}}();var myFunction=function myFunction(b,a){return b+a};

処理系にとっては等価であるが、グット軽量化できたことがわかる

所感

  • AngularJSなどのJavaScriptフレームワークを用いていると、MVC分離のためにファイル数がどんどん増えていってしまうので、やはりこういった結合・ミニファイの技術は必須だ
  • ミニファイされたコードを用いて動作確認を行うと、バグが発生した際にブラウザでコードを確認しづらい問題がある
    — これについては、ミニファイ前のファイルも生成することで、開発中はミニファイ前を使用する運用にすれば解決する
  • ファイルが増えてもスクリプトをロードするタグを追加する必要がないので楽になる
  • JavaScriptファイル間で複雑な依存関係がある場合は、別途依存対策を取る必要がありそう
  • 当たり前だが、この技術はJavaScriptだけじゃなくCSSでも適用できるはず
    — 複数のLESSファイルを一つに結合し、CSSに変換してミニファイ

参考

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です