web-dev-qa-db-ja.com

縮小中にデバッグJavaScriptコードを除外する

通常の JSMin 、Packer、 [〜#〜] yui [〜#〜] ソリューションなど、JavaScriptコードを縮小するさまざまな方法を検討しています。非常に強力に見えるので、私は新しい Google ClosureCompiler に本当に興味があります。

Dean Edwards packer には、3つのセミコロンで始まるコード行を除外する機能があることに気付きました。これは、デバッグコードを除外するのに便利です。例えば:

;;;     console.log("Starting process");

コードベースのクリーンアップに時間を費やしており、デバッグコードを簡単に除外するために、このようなヒントを追加したいと思います。これに備えて、これが最善の解決策なのか、それとも他の手法があるのか​​を考えたいと思います。

ミニファイする方法をまだ選択していないので、最終的に使用するミニファイアと互換性のある方法でコードをクリーンアップしたいと思います。だから私の質問はこれらです:

  1. セミコロンを使用するのは標準的な手法ですか、それとも他の方法がありますか?

  2. Packerはこの機能を提供する唯一のソリューションですか?

  3. 他のソリューションもこのように機能するように適合させることができますか、それともこれを達成するための代替方法がありますか?

  4. やがてClosureCompilerを使い始めるでしょう。それに備えるために今やるべきことはありますか?

41
Tauren

これがクロージャーコンパイラーの(究極の)答えです:

/** @const */
var LOG = false;
...
LOG && log('hello world !'); // compiler will remove this line
...

これはSIMPLE_OPTIMIZATIONSでも機能し、--define=は必要ありません!

60
kares

これが私がClosureCompilerで使っているものです。まず、次のようにDEBUG変数を定義する必要があります。

/** @define {boolean} */
var DEBUG = true;

クロージャにJSアノテーションを使用しています。これについては、 ドキュメント内 を参照してください。

これで、デバッグ専用のコードが必要なときはいつでも、次のようにifステートメントでラップするだけです。

if (DEBUG) {
  console.log("Running in DEBUG mode");
}

リリース用にコードをコンパイルするときは、次のコンパイルコマンドを追加します。--define='DEBUG=false' --debugステートメント内のコードは、コンパイルされたファイルから完全に除外されます。

25
Fortes

この場合の適切な解決策は、「条件付きコンパイル」をサポートする js-build-tools です。

要するに、あなたは次のようなコメントを使うことができます

// #ifdef debug
var trace = debug.getTracer("easyXDM.Rpc");
trace("constructor");
// #endif

ここで、debugなどのプラグマを定義します。

それからそれを構築するとき(それはant-taskを持っています)

//this file will not have the debug code
<preprocess infile="work/easyXDM.combined.js" outfile="work/easyXDM.js"/>
//this file will        
<preprocess infile="work/easyXDM.combined.js" outfile="work/easyXDM.debug.js" defines="debug"/>
6
Sean Kinsey

コンソールにログインしているコード内のすべての場所にロジックを追加すると、デバッグと保守が難しくなります。

プロダクションコードのビルドステップをすでに追加する場合は、consoleメソッドをnoopに変換する別のファイルをいつでも上部に追加できます。

何かのようなもの:

console.log = console.debug = console.info = function(){};

理想的には、consoleメソッドを削除するだけですが、とにかくそれらを保持しているが使用していない場合は、これがおそらく最も簡単に操作できます。

2
Kevin Beal

glifyJS2 を使用している場合は、drop_console引数を使用してconsole。*関数を削除できます。

2
Druska

詳細モードでClosureCompilerを使用する場合、次のようなことができます。

if (DEBUG) console.log = function() {}

次に、コンパイラはすべてのconsole.log呼び出しを削除します。もちろん、コマンドラインで変数DEBUG--defineする必要があります。

ただし、これは詳細モードの場合のみです。シンプルモードを使用している場合は、ソースファイルでプリプロセッサを実行する必要があります。

Dojo Toolkitを検討してみませんか?ビルドに基づいてコードのセクションを含めたり除外したりするためのコメントベースのプラグマが組み込まれています。さらに、詳細モードのクロージャーコンパイラと互換性があります(以下のリンクを参照)。

http://dojo-toolkit.33424.n3.nabble.com/file/n2636749/Using_the_Dojo_Toolkit_with_the_Closure_Compiler.pdf?by-user=t

2
Stephen Chung

それは古い質問ですが。私は今日同じ問題に遭遇し、 CompilerOptions を使用してそれを達成できることを発見しました。

私は このスレッド をフォローしました。

コードをクライアントに送信する前に、サーバー上でJavaからコンパイラーを実行します。これは、シンプルモードで機能しました。

private String compressWithClosureCompiler(final String code) {
    final Compiler compiler = new Compiler();
    final CompilerOptions options = new CompilerOptions();
    Logger.getLogger("com.google.javascript.jscomp").setLevel(Level.OFF);
    if (compressRemovesLogging) {
        options.stripNamePrefixes = ImmutableSet.of("logger");
        options.stripNameSuffixes = ImmutableSet.of("debug", "dev", "info", "error",
                "warn", "startClock", "stopClock", "dir");
    }
    CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options);

    final JSSourceFile extern = JSSourceFile.fromCode("externs.js", "");
    final JSSourceFile input = JSSourceFile.fromCode("input.js", code);
    compiler.compile(extern, input, options);
    return compiler.toSource();
}

Logger.debug、logger.dev ... etc.etcへのすべての呼び出しが削除されます

2
Johan Leufvén

私は@ marcel-korpelと一緒です。完璧ではありませんが、機能します。縮小する前にデバッグ命令を置き換えてください。正規表現は多くの場所で機能します。囲まれていない行に注意してください。

/console\.[^;]*/gm

動作:

;;;     console.log("Starting process");
console.log("Starting process");
console.dir("Starting process");;;;;
console.log("Starting "+(1+2)+" processes"); iamok('good');
console.log('Message ' +
    'with new line'
);
console.group("a");
console.groupEnd();
swtich(input){
    case 1 : alert('ok'); break;
    default: console.warn("Fatal error"); break;
}

動作しない:

console.log("instruction without semicolon")
console.log("semicolon in ; string");
1
William

私はこれを私のReactアプリで使用します:

if (process.env.REACT_APP_STAGE === 'PROD')
  console.log = function no_console() {};

言い換えると、 console.log製品環境では何も返しません。

0
pmiranda

これまで縮小化については調べていませんが、この動作は単純な正規表現を使用して実現できます。

s/;;;.*//g

これにより、3つのセミコロンの後(およびそれを含む)の行のすべてが何も置き換えられないため、縮小する前に破棄されます。次のように、ミニファイツールを実行する前にsed(または同様のツール)を実行できます。

sed 's/;;;.*//g' < infile.js > outfile.js

ところで、パックバージョンと縮小バージョンのどちらが「より良い」か疑問に思っている場合は、 JavaScript圧縮方法のこの比較 を読んでください。

0
Marcel Korpel

私は次の自作のstufを使用しました:

_// Uncomment to enable debug messages
// var debug = true;

function ShowDebugMessage(message) {
    if (debug) {
        alert(message);
    }
}
_

したがって、debugに設定された変数trueを宣言すると、すべてのShowDebugMessage()呼び出しはalert()も呼び出します。したがって、コードで使用するだけで、ifdefやデバッグ出力行の手動コメントなどの条件を忘れてください。

0
sll