#help-with-umbraco
Optimal settings for Smidge (Runtimeminification) in local dev and production
c

CodeSharePaul

09/12/2023, 9:30 AM
Hi all, We've been having some issues with smidge in local dev. When working on css changes, they don't get picked up unless we do a rebuild which really slows down the workflow for our front end devs. Please can you help me work out what the optimal settings for smidge (RuntimeMinification) should be for local development without needing to rebuild and for when the site is published? Kind regards Paul
m

Mike Chambers

09/12/2023, 9:32 AM
Though I think we go timestamp for development, and AppDomain for production
c

CodeSharePaul

09/12/2023, 9:34 AM
Thanks Mike, there is a clue saying that we should set to AppDomain or Version in production. I'd like to avoid versions so that might be the one then > Caches will be busted when the app restarts.
for production that is
We've tried using timestamp in local dev but it still doesn't help
m

Mike Chambers

09/12/2023, 9:35 AM
also depends on how you are using smidge frontend.. if you are using the umbraco abstraction... then the appDomain gets combined with umbraco version + assembly version too..
and hosting:debug is sorted for you too.
c

CodeSharePaul

09/12/2023, 9:36 AM
We are using it like this:
Copy code
cs
@await SmidgeHelper.CssHereAsync()
Copy code
cs
SmidgeHelper.RequiresCss("/css/wmn-homepage.css");
m

Mike Chambers

09/12/2023, 9:37 AM
then you have to add in environment and debug checks too I think.
as this won't be looking at the appsettings values at all.
c

CodeSharePaul

09/12/2023, 9:37 AM
Do you have an example of a different way to use it then please?
m

Mike Chambers

09/12/2023, 9:49 AM
There was a discussion I had with p-m-j that put me right on these things.. https://discord.com/channels/869656431308189746/915999362751029278/915999516551958528
but boils down to..
Copy code
csharp
@inject IRuntimeMinifier runtimeMinifier
await runtimeMinifier.RenderCssHereAsync("sitewide-css")
then in production your version string/hash is from
$"{version ?? Assembly.Name}_{umbracoVersion}_{Assembly.Version}"
it's more specifically for the backoffice cache to change on umbraco version update...
and also if you already minify your files then name xxx.min.(css|js) then nuglify will ignore them for recompression during bundling.
here's the IRuntimeMinifier concrete implementation for inspiration or tweaking to your own desires.. https://github.com/umbraco/Umbraco-CMS/blob/contrib/src/Umbraco.Web.Common/RuntimeMinification/SmidgeRuntimeMinifier.cs
Just noticed also you are using the RequireCss.. several discussions on the smidge git repo how that isn't really the recommended approach any more.
c

CodeSharePaul

09/12/2023, 10:06 AM
Thanks Mike, I've read throught the thread now. It is interesting and has helped me understand it more. I am adding to my bundles from the views rather than in startup.cs, so when I want to render the css i don't have a bundle name. Do i have to put my bundles in startup.cs now and not have the benefit of using the views? Is there a way around this?
and also the reason why compared to CDF no support for partials.. At a clients request I did implement something (around your example I think) for adding in the HttpContext.Items
this approach
Copy code
csharp
public static IHtmlHelper RequiresPartialCss(this IHtmlHelper htmlHelper, String script, int priority = 1000)
{
    var x = htmlHelper.ViewContext.HttpContext.Items["_csss_"];
    var s = (Dictionary<string, rOptions>)(x ?? new Dictionary<string, rOptions>());

    s.TryAdd(script, new rOptions() { Priority = priority });

    htmlHelper.ViewContext.HttpContext.Items["_csss_"] = s;

    return htmlHelper;
}
Copy code
csharp
public static HtmlString RenderPartialViewCss(this IHtmlHelper htmlHelper)
{
    // use urlHelper.Content() to translate "~/"
    var urlHelperFactory = htmlHelper.ViewContext.HttpContext.RequestServices.GetRequiredService<IUrlHelperFactory>();
    var urlHelper = urlHelperFactory.GetUrlHelper(htmlHelper.ViewContext);

    var umbracoVersion = htmlHelper.ViewContext.HttpContext.RequestServices.GetRequiredService<IUmbracoVersion>();
    var runtimeMinifier = htmlHelper.ViewContext.HttpContext.RequestServices.GetRequiredService<IRuntimeMinifier>();
    var hostingEnvironment = htmlHelper.ViewContext.HttpContext.RequestServices.GetRequiredService<IHostingEnvironment>();

    var version = UrlHelperExtensions.GetCacheBustHash(hostingEnvironment, umbracoVersion, runtimeMinifier);

    var x = htmlHelper.ViewContext.HttpContext.Items["_csss_"];
    var s = (Dictionary<string, rOptions>)(x ?? new Dictionary<string, rOptions>());
    foreach (var item in s.OrderBy(x => x.Value.Priority))
    {
        var src = urlHelper.Content($"{item.Key}");
        var cssTag = $"<link type=\"text/css\" href=\"{src}?v={version}\" rel=\"stylesheet\"></script>";
        htmlHelper.ViewContext.Writer.Write(cssTag);               
    }
    return new HtmlString(String.Empty);
}
Copy code
csharp
private class rOptions
{
    public int Priority { get; set; } = 1000;
    public bool Defer { get; set; } = false;

}
Also one big restriction for me to move away from requires was that it's now singular and no priority in smidge.. so can't replicate CDF header and footer css/js containers to render into.. or control that dependant scripts are rendered in the correct priority. Also most of the newer projects for me are with frontenders with webpack/vite/ etc providing bundles already so no need for smidge 😉 And the bundles get built as part of the build in VS with npm/webpack task runner.
c

CodeSharePaul

09/12/2023, 10:59 AM
Ok so I don't think the bundles in the startup are an issue. I'm gonna use them with the runtime minifier as you suggested. As always you've been so helpful. #MVP I'll report back if I get stuck or it works or doesn't work etc
@Mike Chambers any idea how to make this use defer?
Copy code
@await RuntimeMinifier.RenderJsHereAsync("wmn-single-clubpage")
m

Mike Chambers

09/12/2023, 11:15 AM
I don't think smidge supports defer does it from the methods.. could you use the tag helper?
<script src="mn-single-clubpage" type="text/javascript" debug="true" defer="defer"></script>
?
but then you might be back to losing what you gained with the IRuntimeMinifier.
c

CodeSharePaul

09/12/2023, 11:26 AM
I can live without using smidge for this one i need to defer.
But now i'm getting a weird issue
It's creating the link element as content and not an Element
m

Mike Chambers

09/12/2023, 11:29 AM
Not sure I follow.. what were you expecting?
c

CodeSharePaul

09/12/2023, 11:29 AM
I wanted it to go in the head
m

Mike Chambers

09/12/2023, 11:31 AM
hmmm. does it do that if not in an mvc section?
c

CodeSharePaul

09/12/2023, 11:32 AM
Yes, just tried it
m

Mike Chambers

09/12/2023, 11:34 AM
can't say as I've seen that before...
it's not the inspector correcting you html helpfully.. is it the same viewing the source?
c

CodeSharePaul

09/12/2023, 11:47 AM
Copy code
@Html.Raw(await RuntimeMinifier.RenderCssHereAsync("wmn-homepage"))
got it working
But it doesn't show the debug=true in the link like i was expecting
That was the whole point of this way of doing it wasn't it?
seems like what PMJ was saying is that it should be handled for us. Now time to test making a change to the css/js
And in PMJ's example he said use @Html.Raw lol
u

.rockerby

09/12/2023, 12:03 PM
Just following on from this point, the settings we have in dev are:
Copy code
"Umbraco": {
    "CMS": {
      "Hosting": {
        "Debug": true
      },
      "RuntimeMinification": {
        "UseInMemoryCache": true,
        "CacheBuster": "Timestamp"
      }
    }
},
Compared to that in production of the below (where we increment the version in a deployment pipeline):
Copy code
"Umbraco": {
    "CMS": {
      "Hosting": {
        "Debug": false
      },
      "RuntimeMinification": {
        "UseInMemoryCache": false,
        "CacheBuster": "Version",
        "Version": "1.0.0"
      }
    }
  },
c

CodeSharePaul

09/12/2023, 12:17 PM
Thanks @.rockerby
m

Mike Chambers

09/12/2023, 12:20 PM
the debug=true I think will be a processor instruction to the taghelper that will be removed on output generation.. you do get the defer though? https://github.com/Shazwazza/Smidge/blob/develop/src/Smidge/TagHelpers/SmidgeScriptTagHelper.cs
u

.rockerby

09/12/2023, 12:24 PM
we use the debug attribute to unbundle the scripts and make dev easier. here's a sample cshtml:
Copy code
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage

@using Microsoft.Extensions.Options
@using Umbraco.Cms.Core.Configuration.Models
@inject IOptions<HostingSettings> hostingSettings

@{
    var debugMode = hostingSettings.Value.Debug;
    
    SmidgeHelper
        .CreateCssBundle("core-css-bundle")
        .RequiresCss(
            "/_assets/styles/style.css");
}

@*  Load the bundle into the markup - debug mode turns off the
    bundling and spits each file out in it's own script tag *@
<link rel="stylesheet" href="core-css-bundle" media="screen, print" debug="@debugMode" />
c

CodeSharePaul

09/12/2023, 12:28 PM
It works by the way @Mike Chambers the css changes happen automatically even when using the bundle way
Thanks ever so much for your help
I might write an extension method that takes in an HtmlString and lets you add attributes such as defer etc
Kevin mentions it at the end of his post he just loops through them instead of an extension method though
m

Mike Chambers

09/12/2023, 12:32 PM
@.rockerby useInMemoryCache here will only be for the backoffice though, and also use JSMin rather than Nuglify if that's an issue.. (as umbraco smidge implementation swaps it out)
d

Dean Leigh

09/12/2023, 12:45 PM
I think I have to change the setting
Copy code
"RuntimeMinification": {
        "UseInMemoryCache": false,
when I want to test locally. Either way I have it working in a client site I can screen share @CodeSharePaul
c

CodeSharePaul

09/12/2023, 2:45 PM
Thanks Dean, I've got it sorted now. I'll see if I can put it all into a blog post
Here's my blog post with the final code I used and the extension methods I made for adding attributes https://codeshare.co.uk/blog/how-to-set-up-smidge-properly-in-umbraco/
o

oalberto

09/18/2023, 12:34 PM
Amazing post @CodeSharePaul 👌 I’ve struggled with this as well.
141 Views