uglify-jsで顧客とのアプリ確認をもっと楽に!
こんにちは、斉藤です。
最近、マネジメントしながらプログラムを書くことが多いです。
今回WEBアプリ開発のプロジェクトを一つ通して、とある問題とその解決方法を模索しました。
その共有をしたいなーと思いましたので、ブログに書いてみます(ラズベリーパイの記事はまたもお休みです)。
問題
* 顧客に開発中のアプリを見てほしい
* 自分たちはもちろんのこと、顧客にも素早く確認してもらいたい
* アプリが完成に近づけば近づくほど、特定箇所の確認が難しくなる
* 特定の手順を踏まなければならない
* 特定の条件を満たさなければならない
* このためのデバッグ用コードを残しておくと、リリースに影響するため、取り除くことを覚えておかなければならない
* かといって、無ければ無いで開発に不便
こんな問題、思い当たりませんか?
ネイティブアプリなら、プリプロセッサを使っての条件付きコンパイルによるデバッグビルド/リリースビルドで解決出来ますが、JavaScriptを使うWEBアプリではどうでしょうか?
実は、前回紹介したuglify-jsというnpmモジュールには、結合/圧縮だけではなく、この条件付きコンパイルという強力な機能があります。
ということで、上記の問題をこのuglify-jsを使って解決したという内容を共有します。
uglify-js
uglify-jsのインストールは以下の通り。
$ sudo npm install -g uglify-js
さらに、こんなJSを作ります。
$ cat index.js
if (DEBUG) {
console.log("検証用");
} else {
console.log("本番用");
}
これに対して、以下のようにuglify-jsを実行。
– 検証用JS書き出し
$ uglifyjs index.js -c warnings=false --define DEBUG=true --beautify
console.log("検証用");
– 本番用JS書き出し
$ uglifyjs index.js -c warnings=false --define DEBUG=false --beautify
console.log("本番用");
if (DEBUG) {…}部分が条件付きコンパイルとして解釈され、それぞれ2種類のJS(検証用/本番用)を生成できます。
たったこれだけ(それどころか、結合/圧縮までついてくるというおまけ付き)!
基本: 検証用JSのみ、console.logを仕込みたい
まずは基本の使い方を。
開発に使っているconsole.logの結果は、アプリを実際に使うユーザーにはあまり見せたくないですね。これを隠すために、こんな要領で記述します。
$ cat count.js
count = 0;
function countUp() {
count++; // 何かのカウントアップ変数
if (DEBUG) console.log("countは今、こんな値です: " + count);
}
uglify-jsを掛けると、以下のように検証用JSのみconsole.logが働きます。
– 検証用JS書き出し
$ uglifyjs count.js -c warnings=false --define DEBUG=true --beautify
$ function countUp() {
count++, console.log("countは今、こんな値です: " + count);
}
count = 0;
– 本番用JS書き出し
$ uglifyjs count.js -c warnings=false --define DEBUG=false --beautify
function countUp() {
count++;
}
count = 0;
応用: 検証用JSのみ、URLパラメーターからのデバッグオプションを仕込みたい
これが、今回の問題を解決させるために使った方法です。
こんなURLパラメーターを解釈するJS(この例ではjquery.purl.jsを使っています)を仕込んでおき、
$ cat valid.js
function isValidYourStatus() {
if (DEBUG & & $.url().param("valid") !== undefined) {
return true;
}
var isValid = false;
// … 特殊な手順でisValidをtrueにする処理など …
return isValid;
}
同じくuglify-jsを掛けると、以下のように検証用JSのみURLパラメーターを解釈するようになります。
– 検証用JS書き出し
$ uglifyjs valid.js -c warnings=false --define DEBUG=true --beautify
function isValidYourStatus() {
if (void 0 !== $.url().param("valid")) return !0;
var isValid = !1;
return isValid;
}
– 本番用JS書き出し
$ uglifyjs valid.js -c warnings=false --define DEBUG=false --beautify
function isValidYourStatus() {
var isValid = !1;
return isValid;
}
あとはこのJSを読み込んでいるHTMLにアクセスするとき、URLの最後に?validと付けるだけ(http://localhost/?valid )で、関数の返り値を強制的に書き換えるコードも楽々仕込めます。付けなければ、そのまま本番用JSと同じ振る舞いをします。さらに、本番用JSではその機能を使えないように書き出してくれます。
特別な手順を踏まないと、欲しい返り値をくれないような関数には、この方法がとても有効です。
あとは、顧客に”その確認がするんだったら、このURLを踏むと便利だよ!”などと伝えておけば、確認作業がとてもスムーズになりますね。
gruntでもっと楽に
ただ、このコマンドを毎回叩くのも面倒ですよね?
ソースコードを書き換えたときに自動的に実行して欲しくありませんか?
流行りのgruntを使えばそんなことも可能です。以下のGruntfile.jsを参考にしてみてください。
$ cat Gruntfile.js
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
options: {
mangle: false,
beautify: false,
compress: {
global_defs: {DEBUG: false},
dead_code: true
}
},
index_all: {files: {'public_html/js/build/index_all.js': 'src/*.js'}},
index_all_dev: {
options: {
beautify: