-
-
Notifications
You must be signed in to change notification settings - Fork 173
Unbundling scripts for debugging
Vitor edited this page Nov 30, 2020
·
5 revisions
During debugging it can be useful for your application to include all of the component scripts instead of the bundle. One option for this is to use an HTML Helper to generate the script elements in your view.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using System.IO;
using System.Text;
namespace MyApplication
{
public static class Bundler
{
const string FILENAME = "bundleconfig.json";
public static MvcHtmlString RenderScripts(string bundlePath, bool? expandBundle = null)
{
if (expandBundle ?? HttpContext.Current.IsDebuggingEnabled)
{
// we're expanding the bundle so get the desired bundle configuration
string baseFolder = HttpContext.Current.Server.MapPath("");
var configFile = Path.Combine(baseFolder, FILENAME);
var bundles = GetBundles(configFile);
var bundle = (from b in bundles where b.OutputFileName.Equals(bundlePath, StringComparison.InvariantCultureIgnoreCase) select b).FirstOrDefault();
if (bundle == null)
return null;
// build script elements for each input file in the bundle
var sb = new StringBuilder();
var inputFiles = GetBundleInputFiles(baseFolder, bundle);
foreach (var inFile in inputFiles)
{
var fullPath = VirtualPathUtility.ToAbsolute(string.Format("~/{0}", inFile));
if (bundlePath.EndsWith(".css"))
{
sb.AppendLine(string.Format("<link href='{0}' rel='stylesheet'></link>", fullPath));
}
else
{
sb.AppendLine(string.Format("<script src='{0}' type='text/javascript'></script>", fullPath));
}
}
return new MvcHtmlString(sb.ToString());
}
else
{
// we're not expanding the bundle to just add as-is
var fullPath = VirtualPathUtility.ToAbsolute(string.Format("~/{0}", bundlePath));
if (bundlePath.EndsWith(".css"))
{
return new MvcHtmlString(string.Format("<link href='{0}' rel='stylesheet'></link>", fullPath));
}
else
{
return new MvcHtmlString(string.Format("<script src='{0}' type='text/javascript'></script>", fullPath));
}
}
}
// below is mostly copied from Mads Kristensen's BundlerMinifier -> BundleHandler.cs
static List<string> GetBundleInputFiles(string baseFolder, Bundle bundle)
{
List<string> inputFiles = new List<string>();
string ext = Path.GetExtension(bundle.OutputFileName);
foreach (string inFile in bundle.InputFiles)
{
string fullPath = Path.Combine(baseFolder, inFile);
if (Directory.Exists(fullPath))
{
DirectoryInfo dir = new DirectoryInfo(fullPath);
var files = dir.GetFiles("*" + ext, SearchOption.TopDirectoryOnly);
inputFiles.AddRange(files.Select(f => string.Format("{0}/{1}", inFile, f.Name)));
}
else
{
inputFiles.Add(inFile);
}
}
return inputFiles;
}
static IEnumerable<Bundle> GetBundles(string configFile)
{
FileInfo file = new FileInfo(configFile);
if (!file.Exists)
return Enumerable.Empty<Bundle>();
string content = File.ReadAllText(configFile);
return JsonConvert.DeserializeObject<IEnumerable<Bundle>>(content);
}
}
class Bundle
{
[JsonProperty("outputFileName")]
public string OutputFileName { get; set; }
[JsonProperty("inputFiles")]
public List<string> InputFiles { get; set; } = new List<string>();
[JsonProperty("minify")]
public Dictionary<string, object> Minify { get; set; } = new Dictionary<string, object> { { "enabled", true } };
[JsonProperty("includeInProject")]
public bool IncludeInProject { get; set; }
[JsonProperty("sourceMaps")]
public bool SourceMaps { get; set; }
}
}
The second parameter expandBundle
is optional and if omitted expanding the bundle is based on HttpContext.Current.IsDebuggingEnabled
.
@Bundler.RenderScripts("Content/myApp/bundle.js")
...or to you can make the choice yourself..
@Bundler.RenderScripts("Content/myApp/bundle.js", true)
@Bundler.RenderScripts("Content/myApp/bundle.js", false)
ASP.NET Core requires a different way to bundle, I have included a way here https://gist.github.com/mohamedmansour/cd50123f8575daba7a7f12847b12da5d
Alternatively, using UnbundleTagHelper will allow you to write
<unbundle src="~/js/site.js">
and have it expand to
<script src="/js/my_file1.js"></script>
<script src="/js/my_file2.js"></script>
/*!
- Font Awesome Free 5.8.1 by @fontawesome - https://fontawesome.com
- License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) */