question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItΒ collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Blazor Server scoped CSS missing after dotnet publish

See original GitHub issue

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I’m not sure this is the correct repository to post this issue in, but I have not been able to find any other place that seems more fit.

Our issue is: When we run dotnet publish for our Blazor Server App in Azure Pipelines, we are missing some key styles in the output publish folder. If we use just a default Blazor Server project template from .NET 6, the missing files in the publish\wwwroot folder include the following:

  • {AssemblyName}.styles.css
  • css\site.css
  • css\bootstrap\bootstrap.min.css
  • css\open-iconic\font\css\open-iconic-bootstrap.min.css

If we run dotnet publish with the same parameters on our local machines and in GitHub Actions, it is working as expected and we get the correct stylesheet files in the publish folder.

It seems that in Azure Pipelines, the DefineStaticWebAssets task is skipped:

1:7>Target "_ComputeScopedCssStaticWebAssets" in file "/opt/hostedtoolcache/dotnet/sdk/6.0.201/Sdks/Microsoft.NET.Sdk.Razor/targets/Microsoft.NET.Sdk.Razor.ScopedCss.targets" from project "/home/vsts/work/1/s/src/BlazorTestApp.csproj" (target "_CollectAllScopedCssAssets" depends on it):
    Task "DefineStaticWebAssets" skipped, due to false condition; (@(_ScopedCss) != '') was evaluated as ( != '').
1:7>Done building target "_ComputeScopedCssStaticWebAssets" in project "BlazorTestApp.csproj".

In GitHub, the same task has the following output:

1:7>Target "_ComputeScopedCssStaticWebAssets" in file "/home/runner/.dotnet/sdk/6.0.201/Sdks/Microsoft.NET.Sdk.Razor/targets/Microsoft.NET.Sdk.Razor.ScopedCss.targets" from project "/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/BlazorTestApp.csproj" (target "_CollectAllScopedCssAssets" depends on it):
    Task "DefineStaticWebAssets"
      RelativePath 'Shared/MainLayout.razor.rz.scp.css' normalized to 'Shared/MainLayout.razor.rz.scp.css' found for candidate '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/MainLayout.razor.rz.scp.css' and will be used for matching.
      Identity for candidate '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/MainLayout.razor.rz.scp.css' is '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/MainLayout.razor.rz.scp.css' because it starts with content root '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/'.
      RelativePath 'Shared/NavMenu.razor.rz.scp.css' normalized to 'Shared/NavMenu.razor.rz.scp.css' found for candidate '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/NavMenu.razor.rz.scp.css' and will be used for matching.
      Identity for candidate '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/NavMenu.razor.rz.scp.css' is '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/NavMenu.razor.rz.scp.css' because it starts with content root '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/'.
    Done executing task "DefineStaticWebAssets".
1:7>Done building target "_ComputeScopedCssStaticWebAssets" in project "BlazorTestApp.csproj".

Expected Behavior

I expect to have the following files in the publish\wwwroot folder after running dotnet publish:

  • {AssemblyName}.styles.css
  • css\site.css
  • css\bootstrap\bootstrap.min.css
  • css\open-iconic\font\css\open-iconic-bootstrap.min.css

Steps To Reproduce

  1. Create a default Blazor Server app using .NET 6.
  2. Create a minimalistic Azure Pipelines build pipeline (e.g. similar to the one found in the sample repo - https://github.com/dynsim/BlazorServerScopedCSSIssue/blob/main/azure-pipelines.yml)
  3. Run the application that was published and see that the styles are missing.

Exceptions (if any)

Publishing locally and in GitHub Actions.

.NET Version

6.0.201

Anything else?

Additional info

A sample repository can be found here: https://github.com/dynsim/BlazorServerScopedCSSIssue

What we have tried:

File outputs

Azure Pipelines

|-- publish
|   └── appsettings.Development.json
|   └── appsettings.json
|   └── BlazorTestApp
|   └── BlazorTestApp.deps.json
|   └── BlazorTestApp.dll
|   └── BlazorTestApp.pdb
|   └── BlazorTestApp.runtimeconfig.json
|   └── web.config
|   └── wwwroot\favicon.ico
|   └── wwwroot\css\bootstrap\bootstrap.min.css.map
|   └── wwwroot\css\open-iconic\FONT-LICENSE
|   └── wwwroot\css\open-iconic\ICON-LICENSE
|   └── wwwroot\css\open-iconic\README.md
|   └── wwwroot\css\open-iconic\font\fonts\open-iconic.eot
|   └── wwwroot\css\open-iconic\font\fonts\open-iconic.otf
|   └── wwwroot\css\open-iconic\font\fonts\open-iconic.svg
|   └── wwwroot\css\open-iconic\font\fonts\open-iconic.ttf
|   └── wwwroot\css\open-iconic\font\fonts\open-iconic.woff

GitHub Actions

|-- publish
|   └── appsettings.Development.json
|   └── appsettings.json
|   └── BlazorTestApp
|   └── BlazorTestApp.deps.json
|   └── BlazorTestApp.dll
|   └── BlazorTestApp.pdb
|   └── BlazorTestApp.runtimeconfig.json
|   └── web.config
|   └── wwwroot\BlazorTestApp.styles.css
|   └── wwwroot\favicon.ico
|   └── wwwroot\css\site.css
|   └── wwwroot\css\bootstrap\bootstrap.min.css
|   └── wwwroot\css\bootstrap\bootstrap.min.css.map
|   └── wwwroot\css\open-iconic\FONT-LICENSE
|   └── wwwroot\css\open-iconic\ICON-LICENSE
|   └── wwwroot\css\open-iconic\README.md
|   └── wwwroot\css\open-iconic\font\css\open-iconic-bootstrap.min.css
|   └── wwwroot\css\open-iconic\font\fonts\open-iconic.eot
|   └── wwwroot\css\open-iconic\font\fonts\open-iconic.otf
|   └── wwwroot\css\open-iconic\font\fonts\open-iconic.svg
|   └── wwwroot\css\open-iconic\font\fonts\open-iconic.ttf
|   └── wwwroot\css\open-iconic\font\fonts\open-iconic.woff

.NET info

Azure Pipelines

.NET SDK (reflecting any global.json):
 Version:   6.0.201
 Commit:    ef40e6aa06

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  20.04
 OS Platform: Linux
 RID:         ubuntu.20.04-x64
 Base Path:   /opt/hostedtoolcache/dotnet/sdk/6.0.201/

Host (useful for support):
  Version: 6.0.3
  Commit:  c24d9a9c91

.NET SDKs installed:
  6.0.201 [/opt/hostedtoolcache/dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.3 [/opt/hostedtoolcache/dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.3 [/opt/hostedtoolcache/dotnet/shared/Microsoft.NETCore.App]

GitHub Actions

.NET SDK (reflecting any global.json):
 Version:   6.0.201
 Commit:    ef40e6aa06

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  20.04
 OS Platform: Linux
 RID:         ubuntu.20.04-x64
 Base Path:   /home/runner/.dotnet/sdk/6.0.201/

Host (useful for support):
  Version: 6.0.3
  Commit:  c24d9a9c91

.NET SDKs installed:
  6.0.201 [/home/runner/.dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.3 [/home/runner/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.3 [/home/runner/.dotnet/shared/Microsoft.NETCore.App]

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:9 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
javiercncommented, Mar 28, 2022

@dynsim thanks for the additional details.

We then added a Sass builder as a NuGet reference (we use LibSassBuilder), that compiles the .CSS files as part of the build process. However, this does not seem to be sufficient for the .CSS files to be included in the published files - they need to be there before the publish command is executed. It’s not exactly clear to us if this is the expected behavior, or if there is something we are missing. I don’t know if you can see a logical explanation for that? Maybe that package compiles the files too late in the build process? We tried with a couple of other packages (e.g. Delegate.SassBuilder, which is suggested in the docs), but that produced the same result, even though the docs states that [the package] can compile SASS/SCSS files at the beginning of the build process before CSS isolation occurs. I’ll leave it up to you to decide if this is the expected behavior.

This seems like an issue in how the CSS files are built. It normally means that the files got generated too late. We created a package in November and did a blog post around the time to help make this scenario easier. You can check the details here

In general, I would recommend against generating build artifacts in a location that makes them susceptible to be included in source control or as part of the build inputs. This is a bit different in .NET Core vs other build systems because the inputs are in many cases implicitly added (you don’t need to list them all and there are β€œdefault patterns” that discover them) so whenever possible, it is best to place the outputs in a separate folder, (like the obj folder).

In general, if you want your files/assets to be considered, they should be generated before AssignTargetPaths. The blog post I linked above goes into a lot of detail on how this works build wise.

We are also looking to productionize this scenario (that is, making easier to integrate third-party client asset toolchains) in 7.0 and are gathering feedback/interest about it, so please take a moment to upvote this issue if this is something you care about.

I think the behavior here is expected and that additional steps are needed to correctly integrate within the build process, if the guidance provided above doesn’t help, please update the repro and let us know, and we can take another look to see if there’s something amiss.

0reactions
msftbot[bot]commented, Mar 29, 2022

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Scoped CSS issue in Blazor Server - asp.net core
I was missing the publish part of the pipeline. task: DotNetCoreCLI@2. displayName: 'dotnet publish'. inputs: command: publish. projects: |. '**Β ...
Read more >
CSS Isolation in Blazor Server (Net 7) project not working
CSS isolation works by adding deterministic attributes to all components and Css selectors, thus they can be scoped at runtime to the componentΒ ......
Read more >
ASP.NET Core Blazor CSS isolation
Learn how CSS isolation scopes CSS to Razor components, which can simplify CSS and avoid collisions with other components or libraries.
Read more >
Use CSS isolation in your Blazor projects - Dave Brock
I'm excited to see Blazor now supporting CSS isolationβ€”also known as scoped CSS. This post discusses how to use CSS isolation with theΒ ......
Read more >
Host and deploy ASP.NET Core Blazor WebAssembly
Learn how to host and deploy Blazor WebAssembly using ASP.NET Core, Content Delivery Networks (CDN), file servers, and GitHub Pages.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found