0

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?

7
  • change it to what? And why? What's wrong with what it produces? Commented Feb 26, 2018 at 15:35
  • 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. Commented Feb 26, 2018 at 15:39
  • 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. Commented Feb 26, 2018 at 15:40
  • 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) Commented Feb 26, 2018 at 15:43
  • "AngularJS Scripts which can't be minified" again why can't they? In theory any JS is minifiable Commented Feb 26, 2018 at 15:43

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Although this is not directly answering the question, this is the solution to the problem.
0

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

2 Comments

We also want to move towards WebPack, but right now that's not a priority, so we have to stick with the MVC bundler. I initially thought it would be quite extensible but it just seems to allow you some ordering of scripts and that's basically it.
That's understandable - normally I would have kept quiet, but I just wanted to give you some re-assurance that moving to something like WebPack is DEFINITELY a good ultimate goal. Best of luck with it all :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.