Error in js minification

May 13, 2014 at 10:57 AM
Edited May 13, 2014 at 12:10 PM
Hi,

Following the thread https://ajaxmin.codeplex.com/discussions/446616 I implemented concatenated js files with a generated sourceMap.

Consider the following javascript:
(function() {
    'use strict';

    /**
     * Initializes the module
     */
    function init() {

        var temp = 0;
        for (var i=0, len=10; i<len; i++) {
            temp += 1;
        }
        alert(temp);
    }
    
    init();
})();
minifies to:
(function(){"use strict";function n(){for(var n=0,t=0;t<en;t++)n+=1;alert(n)}n()})();
As you can see the second 'len' in the for loop is not parsed but just has its first letter removed.
When a space is added, i.e '< len', things work as expected.

I've tried the following:
  • Changed the var name(s)
  • Removed the sourceMap part
  • Concatenated as a string and minified the string as a whole
but the problem persists.

(checked 5.6 till 5.9)

mzZzl,
JamBo
Coordinator
Jun 6, 2014 at 4:56 PM
When I just run that code through 5.10, I get:
(function(){"use strict";function n(){for(var n=0,t=0;t<10;t++)n+=1;alert(n)}n()})()
Notice that the len variable is completely removed and the instance of len in the condition is replaced with the numeric literal (since len is assigned a constant, referenced in only that one place, and never modified).

What parameter switches, exactly, are you passing to AjaxMin? I'm thinking it must be some sort of combination of features that is causing the replacement to fail.
Jun 6, 2014 at 5:15 PM
Edited Jun 6, 2014 at 5:51 PM
Ronlo,

Just ran it with 5.10 and the problem still exists.
The code I use:

bundleContent is a simple file with listed files like @import "helpers.js";
// We need to write the content somewhere
var encoding = Encoding.GetEncoding("iso-8859-1", new JSEncoderFallback(), new DecoderReplacementFallback("?"));
var outputBuilder = new StringBuilder();
// Find all imports
Regex r = new Regex(@"@import\s*?(.*)\s*;+", RegexOptions.IgnoreCase);

// For the output
using (var outputWriter = new StringWriter(outputBuilder))
{
    // For the sourcemap
    using (var mapWriter = new StreamWriter(mapPath, false, encoding))
    {
        // Creating a sourceMap
        using (var sourceMap = new V3SourceMap(mapWriter))
        {
            // Start the creation of a sourcemap
            sourceMap.StartPackage(outputFilePath, mapPath);
            var settings = new CodeSettings
            {
                SymbolsMap = sourceMap,
                AllowEmbeddedAspNetBlocks = true,
                MinifyCode = true,
                TermSemicolons = true
            };

            // Create the minifier
            var minifier = new Minifier();
            // Loop all imports
            foreach (Match m in r.Matches(bundleContent))
            {
                // Get the file (remove quotes and spaces)
                string file = m.Groups[1].Value.Replace("'", string.Empty).Replace("\"", string.Empty).Trim();
                // Combine it with the directory location
                string path = Path.Combine(directory, file);
                // Set filename
                minifier.FileName = path;
                // Get the content
                outputWriter.Write(minifier.MinifyJavaScript(File.ReadAllText(path), settings));
            }

            // Done
            sourceMap.EndPackage();
            sourceMap.EndFile(outputWriter, Environment.NewLine);
        }
    }
}
tnx,

JamBo