0
votes

Is it possible to change the rendered output of a ScriptBundle in ASP.NET MVC? When configuring the bundles with EnableOptimizations = false, the output for each script included in the bundle is something like this:

 <script src="~/Scripts/path/to/script"></script>

I would like to change this "template" based on the ScriptBundle (for all bundles would also be fine). Is there a way to change this?

2
change it to what? And why? What's wrong with what it produces? - ADyson
Need to add a version query parameter. The scripts currently can't be bundled and minified, and rewriting the scripts is not an option right now. But still we want to use fresh files whenever we change the version of the application. - Eddi
is this to do with caching? Otherwise what would a query parameter achieve? Do these links point to static files or some server-side script which generates the output? It's not clear. Why can't you bundle and minify? I'm not sure you can do what you want via the Scripts.Render helper, it doesn't seem to accept any other parameters. So you can either make your own helper, or just write the <script tags directly. - ADyson
Exactly, i'm including every Script within a specific subdirectory in this ScriptBundle (AngularJS Scripts which can't be minified to be specific; hence EnableOptimizations is disabled) - Eddi
"AngularJS Scripts which can't be minified" again why can't they? In theory any JS is minifiable - ADyson

2 Answers

1
votes

Have a look at the below code, which will always give fresh file.

using System.IO;
using System.Web;
using System.Web.Hosting;
using System.Web.Optimization;

namespace TestProj
{
    public class BundleConfig
    {
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new ScriptBundle("~/bundles/common").Include("~/Scripts/CommonScripts.js").WithLastModifiedToken());

            BundleTable.EnableOptimizations = false;
        }
    }

    internal static class BundleExtensions
    {
        public static Bundle WithLastModifiedToken(this Bundle sb)
        {
            sb.Transforms.Add(new LastModifiedBundleTransform());
            return sb;
        }
        public class LastModifiedBundleTransform : IBundleTransform
        {
            public void Process(BundleContext context, BundleResponse response)
            {
                foreach (var file in response.Files)
                {
                    var lastWrite = File.GetLastWriteTime(HostingEnvironment.MapPath(file.IncludedVirtualPath)).Ticks.ToString();
                    file.IncludedVirtualPath = string.Concat(file.IncludedVirtualPath, "?v=", lastWrite);
                }
            }
        }
    }
}

The output will be

"/Scripts/CommonScripts.js?v=636180193140000000"

Here i am adding the last modified date of the file as query parameter. So whenever the file changes browser will get the fresh file all the time. Or instead of last updated time you can add version like '1.0.0' in the query parameter.

0
votes

I wrestled with MVC bundling for a long time too. It was great to begin with, but you start to fight a losing battle with it when you need to do anything out of the ordinary (like your question).

I'm sorry this doesn't directly answer your question, but I moved to WebPack because of issues like this, and have never looked back.

https://webpack.js.org