Javascript bundle obfuscation

Apr 7, 2014 at 7:14 AM
I am trying to obfuscate the output of our JavaScript bundles on the fly using bundletransformer but had no success implementing it! So far by reading the provided documentation I've written the following code in the RegisterBundles method:
        var nullBuilder = new NullBuilder();           
        var cssTransformer = new CssTransformer();

        var yuiSettings = new BundleTransformer.Yui.Configuration.YuiSettings();
        yuiSettings.JsMinifier.ObfuscateJavascript = true;

        var jsTransformer = new JsTransformer();

        var nullOrderer = new NullOrderer();

        var scriptBundle = new CustomScriptBundle("~/jscbundle/").Include(
                      "~/Assets/Scripts/jquery.js",
                      "~/Assets/Scripts/jquery-ui.js");

        scriptBundle.Builder = nullBuilder;
        scriptBundle.Orderer = nullOrderer;


        scriptBundle.Transforms.Add(jsTransformer);

        bundles.Add(scriptBundle);
and the following code in the web.config :

<bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
<core>
  <css>
    <minifiers>
      <add name="NullMinifier" type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core" />
      <add name="YuiCssMinifier" type="BundleTransformer.Yui.Minifiers.YuiCssMinifier, BundleTransformer.Yui"  />
    </minifiers>
    <translators>
      <add name="NullTranslator" type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core" enabled="false" />
    </translators>
  </css>
  <js defaultMinifier="YuiJsMinifier" usePreMinifiedFiles="true">
    <minifiers>
      <add name="NullMinifier" type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core" />
      <add name="YuiJsMinifier" type="BundleTransformer.Yui.Minifiers.YuiJsMinifier, BundleTransformer.Yui" />
    </minifiers>
    <translators>
      <add name="NullTranslator" type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core" enabled="false" />
    </translators>
  </js>
</core>
<yui>
  <css compressionType="Standard" removeComments="true" lineBreakPosition="-1" />
  <js compressionType="Standard" obfuscateJavascript="true" preserveAllSemicolons="false" disableOptimizations="false" ignoreEval="false" severity="0" lineBreakPosition="-1" encoding="UTF8" threadCulture="en-us" />
</yui>
Judging from the bundle output I can infer that not only it's not obfuscated but the compression is not taking effect at all! I could not find any samples online and tried changing a few settings here and there with no luck! So I'm pretty clueless and any solutions or suggestions would be much appreciated. Thanks in advance!
Coordinator
Apr 7, 2014 at 8:54 AM
Hello, Bahador!

Honestly, I haven't seen more terrible code of bundle registration.

Actually, we need a very simple code:
namespace TestYui
{
    using System.Web.Optimization;

    using BundleTransformer.Core.Bundles;
    using BundleTransformer.Core.Orderers;

    public class BundleConfig
    {
        public static void RegisterBundles(BundleCollection bundles)
        {
            var nullOrderer = new NullOrderer();

            var scriptBundle = new CustomScriptBundle("~/jscbundle/");
            scriptBundle.Include(
                "~/Assets/Scripts/jquery.js",
                "~/Assets/Scripts/jquery-ui.js");
            scriptBundle.Orderer = nullOrderer;

            bundles.Add(scriptBundle);
        }
    }
}
And settings in the Web.config file:
<configuration>
    …
    <bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
        <core>
            <css>
                <minifiers>
                    <add name="NullMinifier" type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core" />
                    <add name="YuiCssMinifier" type="BundleTransformer.Yui.Minifiers.YuiCssMinifier, BundleTransformer.Yui" />
                </minifiers>
                <translators>
                    <add name="NullTranslator" type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core" enabled="false" />
                </translators>
            </css>
            <js defaultMinifier="YuiJsMinifier">
                <minifiers>
                    <add name="NullMinifier" type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core" />
                    <add name="YuiJsMinifier" type="BundleTransformer.Yui.Minifiers.YuiJsMinifier, BundleTransformer.Yui" />
                </minifiers>
                <translators>
                    <add name="NullTranslator" type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core" enabled="false" />
                </translators>
            </js>
        </core>
    </bundleTransformer>
    …
</configuration>
Rather, problem is caused by fact, that the web application run in debug mode.

Switch a web application to release mode by using the following settings in the Web.config file:
<configuration>
  …
  <system.web>
    <compilation debug="false"  … />
    …
  </system.web>
  …
</configuration>
Or add to the App_Start\BundleConfig.cs file the following code:
BundleTable.EnableOptimizations = true;
Before you read the documentation for Bundle Transformer, i recommend to read chapter “Bundling and Minification” of the ASP.NET MVC 4 tutorial.
Coordinator
Apr 7, 2014 at 2:05 PM
I've alse added the <yui> tag after the <core> tag like the one mentioned in my original question, but either way the result still seems minified but not obfuscated and the comments are not removed either.
Dear Bahador, these settings do not need to set, because BundleTransformer.Yui has the following default settings:
<configuration>
  …
  <bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
    …
    <yui>
      <css compressionType="Standard" removeComments="true"
        lineBreakPosition="-1" />
      <js compressionType="Standard" obfuscateJavascript="true"
        preserveAllSemicolons="false" disableOptimizations="false"
        ignoreEval="false" severity="0" lineBreakPosition="-1"
        encoding="UTF8" threadCulture="en-us" />
    </yui>
    …
  </bundleTransformer>
  …
</configuration>
I just noticed that the bundler code you provided does not contain the code for adding new JsTransformer, isn't that needed?
If we use the CustomScriptBundle class, then we not need to add an instance of the JsTransformer class to the list of transformations. Carefully read the documentation.
... the result still seems minified but not obfuscated and the comments are not removed either.
On my computer all works correctly (and obfuscation, and removing of comments). You must understand 2 things:
  1. Obfuscation is not exposed to the names of variables and functions, that are declared in global scope.
  2. YUI JS Compressor does not remove important comments (/*!…*/). More detailed information you can read in the «How to remove comments with BundleTransformer YuiJsMinifier» discussion.