umbraco / Umbraco-CMS

Umbraco is a free and open source .NET content management system helping you deliver delightful digital experiences.
https://umbraco.com
MIT License
4.4k stars 2.66k forks source link

"AppDomain" cachebuster still uses the value of "Version" in it's generated URLs. #15165

Open shropgov-neil opened 10 months ago

shropgov-neil commented 10 months ago

Which Umbraco version are you using? (Please write the exact version, example: 10.1.0)

12.3.1

Bug summary

The generated URL for a Smidge bundle will always use the "Umbraco.CMS.RuntimeMinification.Version" value, regardless of the value of "Umbraco.CMS.RuntimeMinification.CacheBuster".

Specifics

I've had an ongoing issue since v10 where all my bundles are generated with the URL "/sb/{bundle}.v1.{css/js}", despite "CacheBuster" being set to "AppDomain" - the only way to change "v1" is to set the "Umbraco.CMS.RuntimeMinification.Version" value manually.

We do not want to be setting the version string manually, but need the URL to change on each deploy to avoid browsers aggressivly caching out of date assets.

It doesn't matter what value I set "CacheBuster" to (AppDomain or Timestamp), the version value will always be the value of "Version" (or "v1", if you leave it blank).

This happens in both Debug and Production, and the values of "Umbraco.CMS.RuntimeMinification.UseInMemoryCache" and "Umbraco.CMS.RuntimeMinification.KeepFileExtensions" do not make a difference.

Steps to reproduce

Create a custom Smidge bundle (with SmidgeHelper.Create{Js/Css}Bundle()), add at least one file to the bundle (with Require{Js/Css}()).

Set "Umbraco.CMS.RuntimeMinification.CacheBuster" to "AppDomain". Do not set a value for ""Umbraco.CMS.RuntimeMinification.Version".

Render the reference with one of the SmidgeLinkTagHelper / SmidgeScriptTagHelper, with debug set to false.

Check the href/src value outputted in the source code.

Try setting a value of Version (while keeping it set to "AppDomain"), and check the source again.

Expected result / actual result

I would expect to see a unique filename for every cycle of the AppPool, what I actually see is "style.v1.css" every single time (or whatever the value of "Version" is).


This item has been added to our backlog AB#35172

github-actions[bot] commented 10 months ago

Hi there @shropgov-neil!

Firstly, a big thank you for raising this issue. Every piece of feedback we receive helps us to make Umbraco better.

We really appreciate your patience while we wait for our team to have a look at this but we wanted to let you know that we see this and share with you the plan for what comes next.

We wish we could work with everyone directly and assess your issue immediately but we're in the fortunate position of having lots of contributions to work with and only a few humans who are able to do it. We are making progress though and in the meantime, we will keep you in the loop and let you know when we have any questions.

Thanks, from your friendly Umbraco GitHub bot :robot: :slightly_smiling_face:

shropgov-neil commented 10 months ago

I've done some more digging and it appears it's something to do with not passing the configuration options to the native smidge functions - so the built in SmidgeHelper isn't using them.

I trawled the source code and found an undocumented Umbraco.Cms.Web.Common.RuntimeMinification.SmidgeRuntimeMinifier which re-implements CreateCssBundle and CreateJsBundle for the back office - if I inject this into my view and use those functions, the files are generated with the correct AppDomain cachebuster. This then works for the first page load, but subsequent page loads crash with "The bundle name {bundle} already exists" which persists until the cache is cleared.

Can we either get the config options passed to the native functions, or (if this is the supported way to do it) get the SmidgeRuntimeMinifier method documented somewhere?

dhymik commented 9 months ago

Thank you for raising this issue. I was pulling my hair out about this myself as well. I hope this can be fixed soon.

shropgov-neil commented 9 months ago

If it helps, as a workaround I created my own service, injected IRuntimeMinifier and IBundleManager so that I could overload the functions to check the bundles didn't already exist before creating them. Then just injected that into my view to keep that cleaner.

Seems awfully hacky, but it works until a proper documented resolution is provided.

shropgov-neil commented 9 months ago

A slightly better, but no less hacky fix was to go back to using the proper SmidgeHelper class, but with this in Startup.cs

  services.Configure<SmidgeOptions>(options =>
      {
        string cachebuster = _config.GetSection("Umbraco:CMS:RuntimeMinification").GetValue<string>("CacheBuster") ?? "AppDomain";
        Type cacheBusterType = Enum.Parse<RuntimeMinificationCacheBuster>(cachebuster) switch
        {
          RuntimeMinificationCacheBuster.AppDomain => typeof(AppDomainLifetimeCacheBuster),
          RuntimeMinificationCacheBuster.Version => typeof(ConfigCacheBuster),
          RuntimeMinificationCacheBuster.Timestamp => typeof(TimestampCacheBuster),
          _ => throw new NotImplementedException(),
        };

        options.DefaultBundleOptions.DebugOptions.FileWatchOptions.Enabled = true;
        options.DefaultBundleOptions.DebugOptions.SetCacheBusterType(cacheBusterType);
        options.DefaultBundleOptions.ProductionOptions.SetCacheBusterType(cacheBusterType);
        options.DefaultBundleOptions.ProductionOptions.ProcessAsCompositeFile = true;
      });

Hope that helps someone while we wait for an official answer.

Migaroez commented 9 months ago
nhaberl commented 7 months ago

Any news here ?

thenexus00 commented 7 months ago

Hi, Also not seeing caching being updated when "AppDomain" set and restarting an application pool.

azure-boards[bot] commented 7 months ago

❌ There was a problem linking to Azure Boards work item(s):

Please check the IDs and try again using the AB# syntax. Learn more

azure-boards[bot] commented 7 months ago

❌ There was a problem linking to Azure Boards work item(s):

Please check the IDs and try again using the AB# syntax. Learn more

azure-boards[bot] commented 7 months ago

❌ There was a problem linking to Azure Boards work item(s):

Please check the IDs and try again using the AB# syntax. Learn more

azure-boards[bot] commented 7 months ago

❌ There was a problem linking to Azure Boards work item(s):

Please check the IDs and try again using the AB# syntax. Learn more

azure-boards[bot] commented 7 months ago

❌ There was a problem linking to Azure Boards work item(s):

Please check the IDs and try again using the AB# syntax. Learn more

shropgov-neil commented 7 months ago

@UmbracoHQ Can someone pelase disable the azure-boards bot (or fix the issue) so we're not getting spammed hourly?

kikodev714 commented 6 months ago

A slightly better, but no less hacky fix was to go back to using the proper SmidgeHelper class, but with this in Startup.cs

  services.Configure<SmidgeOptions>(options =>
      {
        string cachebuster = _config.GetSection("Umbraco:CMS:RuntimeMinification").GetValue<string>("CacheBuster") ?? "AppDomain";
        Type cacheBusterType = Enum.Parse<RuntimeMinificationCacheBuster>(cachebuster) switch
        {
          RuntimeMinificationCacheBuster.AppDomain => typeof(AppDomainLifetimeCacheBuster),
          RuntimeMinificationCacheBuster.Version => typeof(ConfigCacheBuster),
          RuntimeMinificationCacheBuster.Timestamp => typeof(TimestampCacheBuster),
          _ => throw new NotImplementedException(),
        };

        options.DefaultBundleOptions.DebugOptions.FileWatchOptions.Enabled = true;
        options.DefaultBundleOptions.DebugOptions.SetCacheBusterType(cacheBusterType);
        options.DefaultBundleOptions.ProductionOptions.SetCacheBusterType(cacheBusterType);
        options.DefaultBundleOptions.ProductionOptions.ProcessAsCompositeFile = true;
      });

Hope that helps someone while we wait for an official answer.

This code helped me. Thanks! I'm actually using "Version" mode but I'm wondering if there's also a way I could also influence the version number instead of using what's in the appConfig. I'm trying to obtain it from a SharedAssembly class.