• カミナリツイッターカミナリtwitter
  • カミナリフェイスブックカミナリfacebook
  • カミナリインスタグラムカミナリinstagram

山陰の情報を発信するカミナリ

ナビ

22

AUGUST

ウェブTUESDAY 2017 / 8 / 22

javascript の console.log 等の結果を本番環境で表示させないようにするには? → メソッドをオーバーライドしちゃえばいいよ

ブラウザ内で動作するJavascriptですが、内部の値を参照するために console.log という関数が用意されています。ブラウザには開発者用に「デベロッパーツール」とか「開発者モード」とかいうのが用意されているのですが、その中のコンソールタブに任意の値を出力させることができるようになっています。

 

デバッグ(不具合がないか確認すること)の際にはとても便利なのですが、本番環境でもついこの出力を消し忘れてしまい、

「わぁ、同業者から見られたらちょっとカッコ悪いなー」

ということがあります。

 

自前で関数を自作して対応することもできますが全箇所の修正は面倒なので、そもそもの console.log の処理を書き換えてしまうとスマートですね。

ちなみに、consoleには他にもいろいろなメソッドがあります。

console.warn, console.debug, console.info → ほぼ console.log と同様の機能
console.error → 結果をエラーとして表示
console.table → 配列やオブジェクトを表形式で表示(IEでは使えません)

※ 他にもありますが、詳しくは console – Web API インターフェイス | MDN を見てください。

 

これらもまとめて出力のON/OFFが制御できると助かるかなぁー、ということで作りました。

自前のJavaScriptを読み込む前に下記を実行させることで対応は完了です。

 

(function(){
  var loca = location,  // minify時に縮小するための変数
      host = loca.host, // minify時に縮小するための変数
      consoleDomains = ['localhost', '127.0.0.1', 'codepen.io', 'test-domain.com']; // console結果を出力するドメイン名を指定(後方一致)
  /**
    * isConsole
    * ここにConsole結果を出力する条件を記述する
    */
  function isConsole(){
    if(loca.protocol==='file:')  // ローカルファイルを呼び出している場合は
      return true;                //  結果を表示する
    var is = false;
    consoleDomains.some(function(domain){
      if(host.slice(-domain.length)===domain){
        is = true;
        return true;
      }
    });
    return is;
  }
  for(var key in console){
    if(typeof console[key] === 'function'){
      override(key);
    }
  }
  function override(key){
    var proto = console[key];
    console[key] = function(){
      if(isConsole()){
        proto.apply(this, arguments);
      }
    };
  }
})();

表示するか否かを決めているのは isConsole関数内で、そちらは少し修正する必要があります。変数 consoleDomains にテスト環境のドメイン名を配列として入れるだけです。
あとローカル環境では表示してもよかろう、ということで、file:プロトコルを使っている場合も表示するようにしてあります。

 

この処理は通常は書き換えることがないはずなので、minifyして縮小しておくとあとあと使い勝手が良いです。JSCompress 等のサービスを使って縮小することで、1/3くらいのサイズになります。

!function(){function o(){if("file:"===n.protocol)return!0;var o=!1;return c.some(function(n){if(t.slice(-n.length)===n)return o=!0,!0}),o}var n=location,t=n.host,c=["localhost","127.0.0.1","codepen.io","test-domain.com"];for(var e in console)"function"==typeof console[e]&&function(n){var t=console[n];console[n]=function(){o()&&t.apply(this,arguments)}}(e)}();

 

なお JavaScriptでは既存処理を書き換える際、通常は prototype と呼ばれる原型を書き換えるのですが、この console についてはうまく書き換えができなかったため、applyメソッドを使うことで対応しています。

参考 Can I extend the console object (for rerouting the logging) in javascript? – Stack Overflow

 

それと、console内のメソッドをすべてオーバーライドしていますので、本番環境では console.time や console.timeEnd も使用できなくなってしまいます。本番環境でベンチマークを取りたいという場合は処理を書き換える等対応してやってください。

松本博之隠しプロフィール画像

TEXT by

松本 博之まつもとひろゆき)

1978年、鳥取県米子市生まれ。
株式会社カミナリ WEBシステムの開発・運用を担当。

この人が書いた他の記事を読む