Taritsyn / BundleTransformer

Bundle Transformer - a modular extension for System.Web.Optimization (also known as the Microsoft ASP.NET Web Optimization Framework).
Apache License 2.0
130 stars 19 forks source link

SingeLine Output mode not working for any minifier #68

Closed shivp closed 1 year ago

shivp commented 2 years ago

I had a requirement to preserve the copyright notices of minified third-party JS libraries which led me to the BundleTransformer. While it does fulfill my requirement, the minification does not seem to remove line breaks between code from different source files. To illustrate the scenario, I created two JS files

TestA.js

var myVar = 0; for (; myVar < 10; myVar++) { console.log(myVar) }

TestB.js

var myVar = 10; for (; myVar < 20; myVar++) { console.log(myVar) }

Output

for(var myVar=0;myVar<10;myVar++)console.log(myVar); for(var myVar=10;myVar<20;myVar++)console.log(myVar);

As you can see, there is a line break in the minified file, while it is expected to be a single line as per the configuration I have.

Here is my Web.config

    <bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
        <core>
            <css>
                <translators>
                    <add name="NullTranslator" type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core" enabled="false" />
                </translators>
                <postProcessors>
                    <add name="UrlRewritingCssPostProcessor" type="BundleTransformer.Core.PostProcessors.UrlRewritingCssPostProcessor, BundleTransformer.Core" useInDebugMode="false" />
                </postProcessors>
                <minifiers>
                    <add name="NullMinifier" type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core" />
                    <add name="MicrosoftAjaxCssMinifier" type="BundleTransformer.MicrosoftAjax.Minifiers.MicrosoftAjaxCssMinifier, BundleTransformer.MicrosoftAjax" />
                </minifiers>
                <fileExtensions>
                    <add fileExtension=".css" assetTypeCode="Css" />
                </fileExtensions>
            </css>
            <js defaultMinifier="MicrosoftAjaxJsMinifier">
                <translators>
                    <add name="NullTranslator" type="BundleTransformer.Core.Translators.NullTranslator, BundleTransformer.Core" enabled="false" />
                </translators>
                <minifiers>
                    <add name="NullMinifier" type="BundleTransformer.Core.Minifiers.NullMinifier, BundleTransformer.Core" />
                    <add name="MicrosoftAjaxJsMinifier" type="BundleTransformer.MicrosoftAjax.Minifiers.MicrosoftAjaxJsMinifier, BundleTransformer.MicrosoftAjax" />
                    <add name="UglifyJsMinifier" type="BundleTransformer.UglifyJs.Minifiers.UglifyJsMinifier, BundleTransformer.UglifyJs" />
                </minifiers>
                <fileExtensions>
                    <add fileExtension=".js" assetTypeCode="JavaScript"  />
                </fileExtensions>
            </js>
        </core>
        <microsoftAjax>
            <js outputMode="SingleLine"  />
        </microsoftAjax>
        <uglify>
            <jsEngine name="V8JsEngine" />
        </uglify>
    </bundleTransformer>

Here is my method inside the BundleConfig.cs file

        private static void BundleUsingBundleTransformer(BundleCollection bundles)
        {
            //var engineSwitcher = JsEngineSwitcher.Current;
            //engineSwitcher.EngineFactories.Add(new V8JsEngineFactory());
            //engineSwitcher.DefaultEngineName = V8JsEngine.EngineName;
            var nullBuilder = new NullBuilder();
            var nullOrderer = new NullOrderer();

            var resolver = new CustomBundleResolver();
            BundleResolver.Current = resolver;

            var bundleB = new CustomScriptBundle("~/bundles/bundleB").Include(
                "~/Scripts/TestA.js",
                "~/Scripts/TestB.js"
                );
            bundleB.Builder = nullBuilder;
            bundleB.Orderer = nullOrderer;

            bundles.Add(bundleB);

        }

First I used the MicrosoftAjaxMinifier, then I tried with the uglifyMinifier but the line break is still there. What am I missing?

Taritsyn commented 2 years ago

Hello!

While it does fulfill my requirement, the minification does not seem to remove line breaks between code from different source files. … As you can see, there is a line break in the minified file, while it is expected to be a single line as per the configuration I have.

This line break are added when combining of the code of two minified files. You can perform minification after combining files using the following settings in the Web.config file:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  …
  <bundleTransformer xmlns="http://tempuri.org/BundleTransformer.Configuration.xsd">
    <core>
      <css … combineFilesBeforeMinification="false" usePreMinifiedFiles="false" >
        …
      </css>
      <js … combineFilesBeforeMinification="false" usePreMinifiedFiles="false">
        …
      </js>
      …
    </core>
    …
  </bundleTransformer>
  …
</configuration>

P.S.: I recommend using the BundleTransformer.NUglify module instead of the BundleTransformer.MicrosoftAjax module, because it is its more modern counterpart.

shivp commented 1 year ago

Thank you for your reply. Since you mentioned that the line break is between files, I think it will not make much difference to the size of the Bundle. I checked that removing one line break reduces the size of the bundled file by 2 bytes. So if a bundle has 20 files, the size reduction will be 38 bytes. This is insignificant to me compared to the gains made by using BundleTransformer. Also, as per your suggestion, I am going with the BundleTransformer.NUglify module instead of the BundleTransformer.MicrosoftAjax module.