Search code examples
javascriptminifyconditional-compilation

Is there a JavaScript minifier with conditional directives?


I'm looking for a JavaScript minifier which will have some kind of support for something similar to conditional compilation directives.

So for example, the original JavaScript code could look like something similar to this:

//#if Dev
    showLoginScreen();
//#else
    login("DevUser", "qwerty1");
//#endif

So the original code could contain a directive #define Dev but once it goes into production that #define Dev would be removed, and the minifier would exclude the line login("DevUser", "qwerty1"); from its output.

Do any minifiers support this kind of behavior?


Solution

  • Just run the code through the C preprocessor, then run that output through the minifier. The C preprocessor isn't really C-specific beyond its handling of string literals.

    Example:

    cpp -DDev file.js /dev/stdout | jsmin > file-min.js
    

    where file.js is:

    #if Dev
        showLoginScreen();
    #else
        login("DevUser", "qwerty1");
    #endif
    

    will include the Dev code and then minify it.

    In order to make the original source code executable as-is, you can add one more step to the processing pipeline. Write your code like this:

    //#if Dev
        showLoginScreen();
    //#else
        login("DevUser", "qwerty1");
    //#endif
    

    and then process it like this:

    sed 's!^//#!#!' file.js | cpp -DDev /dev/stdin /dev/stdout | jsmin > file-min.js
    

    The sed portion serves to strip the leading // from lines beginning with //#. cpp then preprocesses the source as normal, and the output from cpp is fed through jsmin for minification.

    A better solution is probably just to do as C programmers do and always preprocess your source file appropriately before running. You might edit a .jspp ("pre-process JavaScript") file, and have your system set up to preprocess it appropriately for development or deployment whenever you change things. If you're using frequent testing, you can make the preprocessing part of your test tool's invocation.

    (NOTE: The command line might be off; I worked out the cpp part from the manpage and the jsmin part from the jsmin.c source code file, so I haven't actually tested this command line.)