I am trying to concat lots of .js files into a single one using Microsoft Web Optimization framework. Everything works, but within those files I have several that are already minified & uglified and there is not need to process them again.
For example I have recaptcha_ajax.js file and it causes following errors when it's appended:
/* Minification failed. Returning unminified contents.
(715,29-36): run-time error JS1019: Can't have 'break' outside of loop: break t
(714,293-300): run-time error JS1019: Can't have 'break' outside of loop: break t
(678,210-217): run-time error JS1019: Can't have 'break' outside of loop: break t
(671,1367-1374): run-time error JS1019: Can't have 'break' outside of loop: break t
(665,280-287): run-time error JS1019: Can't have 'break' outside of loop: break t
*/
I've tried to take take recaptcha_ajax.js out of bundle and reference it directly, but then other errors popup - so, I need that file within the bundle at certain position.
I just need to be able to say - do not minify & uglify recaptcha_ajax.js - just add it to the bundle.
Is there a way to do this? Here is how I see it:
var b = new ScriptBundle("~/bundles/myjsbundle");
b.IncludeDirectory("~/ScriptsMine/", "*.js", true);
// some command like:
// b.DoNotMinifyOrUglify("~/ScriptsMine/recaptcha_ajax.js");
bundles.Add(b);
To enable bundling and minification, set the debug value to "false". You can override the Web. config setting with the EnableOptimizations property on the BundleTable class. The following code enables bundling and minification and overrides any setting in the Web.
Minification is just removing unnecesary whitespace and redundant / optional tokens like curlys and semicolons, and can be reversed by using a linter. Uglification is the act of transforming the code into an "unreadable" form, that is, renaming variables/functions to hide the original intent...
Both bundling and minification are the two separate techniques to reduce the load time. The bundling reduces the number of requests to the Server, while the minification reduces the size of the requested assets.
Uglifying is transforming the code into an "unreadable" form by changing variable names, function names, etc, to hide the original content. Once it is used there's no way to reverse it back. Some libraries like UglifyJS does minification when used, by removing unnecessary parts.
Bundles transform each file by using a collection of IItemTransform
and concatenate result. Then it transform the result by using a collection of IBundleTransform
.
The default script bundle minifies the complete bundle content by using JsMinify
(which implements IBundleTransform
).
So to prevent some file from minifying, you have to create your own IBundleBuilder
which minifies the bundle file by file by using an IItemTransform
.
public class CustomScriptBundle : Bundle
{
public CustomScriptBundle(string virtualPath)
: this(virtualPath, null)
{
}
public CustomScriptBundle(string virtualPath, string cdnPath)
: base(virtualPath, cdnPath, null)
{
this.ConcatenationToken = ";" + Environment.NewLine;
this.Builder = new CustomBundleBuilder();
}
}
public class CustomBundleBuilder : IBundleBuilder
{
internal static string ConvertToAppRelativePath(string appPath, string fullName)
{
return (string.IsNullOrEmpty(appPath) || !fullName.StartsWith(appPath, StringComparison.OrdinalIgnoreCase) ? fullName : fullName.Replace(appPath, "~/")).Replace('\\', '/');
}
public string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable<BundleFile> files)
{
if (files == null)
return string.Empty;
if (context == null)
throw new ArgumentNullException("context");
if (bundle == null)
throw new ArgumentNullException("bundle");
StringBuilder stringBuilder = new StringBuilder();
foreach (BundleFile bundleFile in files)
{
bundleFile.Transforms.Add(new CustomJsMinify());
stringBuilder.Append(bundleFile.ApplyTransforms());
stringBuilder.Append(bundle.ConcatenationToken);
}
return stringBuilder.ToString();
}
}
public class CustomJsMinify : IItemTransform
{
public string Process(string includedVirtualPath, string input)
{
if (includedVirtualPath.EndsWith("min.js", StringComparison.OrdinalIgnoreCase))
{
return input;
}
Minifier minifier = new Minifier();
var codeSettings = new CodeSettings();
codeSettings.EvalTreatment = EvalTreatment.MakeImmediateSafe;
codeSettings.PreserveImportantComments = false;
string str = minifier.MinifyJavaScript(input, codeSettings);
if (minifier.ErrorList.Count > 0)
return "/* " + string.Concat(minifier.Errors) + " */";
return str;
}
}
Then use the CustomScriptBundle
instead of ScriptBundle
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new CustomScriptBundle("~/bundles/Sample").Include(
"~/Scripts/a.js",
"~/Scripts/b.js",
"~/Scripts/c.js"));
}
If you provide a min.js
file it will be used instead of minifying it.
The optimization framework takes filenames into account.
Try to rename your *.js file to recaptcha_ajax.min.js. If I'm correct, then it should skip the uglify/minify process.
Reference data : http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification (scroll down a bit to find this quote:)
The preceding code creates a new JavaScript bundle named ~/bundles/jquery that includes all the appropriate (that is debug or minified but not .vsdoc) files in the Scripts folder that match the wild card string "~/Scripts/jquery-{version}.js". For ASP.NET MVC 4, this means with a debug configuration, the file jquery-1.7.1.js will be added to the bundle. In a release configuration, jquery-1.7.1.min.js will be added. The bundling framework follows several common conventions such as:
- Selecting “.min” file for release when “FileX.min.js” and “FileX.js” exist.
- Selecting the non “.min” version for debug.
- Ignoring “-vsdoc” files (such as jquery-1.7.1-vsdoc.js), which are used only by IntelliSense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With