目次
前提
要素 | バージョン | 関連記事 |
---|---|---|
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を用いて、以下の手順でファイルを変換する
- gulp-concatで一つのES6ファイルに結合する
- gulp-babelでES5ファイルに変換する
- 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に変換してミニファイ