概要
本番環境にアップしたさいに console.log をうっかり消し忘れて、ログ出っぱなしでIEとかでうわああああを防ぐ方法です。
Grunt プラグインの grunt-contrib-uglify はJSファイルの結合や圧縮だけでなく、使われていないコード、デッドコードを削除する機能があります。これを利用して本番環境では必要のない console を取り除きます。
Grunt実行時にデバッグ用フラグをスイッチして、console.log をデッドコードにしてしまおうという仕組みです。
デバッグ用コードを準備する
Grunt と grunt-contrib-uglify はインストール済みという前提です。
次のようなjsがあったとします。
console.log('hello!');
if (DEBUG) {
console.info('console.info');
}
DEBUG && console.debug('console.debug');
肝は DEBUG というグローバル変数です。
このグローバル変数を uglify で値を入れ替えてデッドコードを意図的に作り出すのです。
Gruntの設定
Gruntfile.js に uglify のタスクを2つ作成します。
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.initConfig({
uglify: {
//デッドコードの削除を有効にする
options: {
compress: {
dead_code: true
}
},
//【開発版】変数 DEBUG を true に定義
dev: {
options: {
compress: {
global_defs: {
"DEBUG": true
}
}
},
files: {
'./index.min.js': ['./index.js']
}
},
//【公開版】変数 DEBUG を false に定義
app: {
options: {
compress: {
global_defs: {
"DEBUG": false
}
}
},
files: {
'./index.min.js': ['./index.js']
}
}
}
});
};
DEVタスク実行時に true を DEBUG に代入するので、当然 console の箇所は実行されます。
もう一方の APPタスクは DEBUG を false にします。これもコードを見たとおり console は実行されません。つまりデッドコードになるので圧縮時にはコード上から削除されるのです。
この方法のよいところは、ifブロックもまるごと削除されるので、ログだけでなく開発時にだけ必要なコードを分離しておくのにも便利です。
Gruntタスクで出し分けする
$ grunt uglify:dev
DEVタスクを実行させます。
出力後のコードはたぶんこんな感じになります。
console.log("hello!"),console.info("console.info"),!0&&console.debug("console.debug");
細かいとこは uglify のバージョンで変わりそうですが、3つの console があることには変わりないと思います。
$ grunt uglify:app
APPタスクを実行させてみましょう。
console.log("hello!");
デバッグ用のコードがきれいに取り除かれて、ただの console.log のみになっているはずです。
変数による出し分けよりもはるかに安全で、無駄なコードもなくなるのでおすすめです。