Skip to content

StaticWebAssets: ScopedCss does not regenerate on CssScope ItemGroup metadata changes #50646

@AdmiralSnyder

Description

@AdmiralSnyder

Describe the bug

When creating the temporary file for Scoped CSS, only the file date is considered to decide if the .razor.rz.scp.css is updated.
This is not sufficient if you change the <CssScope> metadata for individual .razor.css files in the .csproj, because those changes will be ignored.

solution

The relevant Task,

public bool SkipIfOutputIsNewer { get; set; } = true;

has a property named SkipIfOutputIsNewer

I suggest that that property should be surfaced as an MsBuild property, so i can force it to auto-regenerate everything, and also change the documentation https://learn.microsoft.com/en-us/aspnet/core/blazor/components/css-isolation?view=aspnetcore-9.0#css-isolation-configuration to mention that it needs to be put there.
alternatively (but that is a hard problem to solve), you could cache the CssScopes for every file and add an additional condition to modify those files where the CssScope was changed OR the file modification date differs.

Mitigation

we changed the explicit import of the Project Sdk=... to import the .targets and .props explicitly and then just overrode the target with one that explicitly uses the SkipIfOutputIsNewer parameter:

<Project>  
  <Import Sdk="Microsoft.NET.Sdk.Razor" Project="Sdk.props"/>
<!--...-->
  <Import Sdk="Microsoft.NET.Sdk.Razor" Project="Sdk.props"/>

<Target Name="_ProcessScopedCssFiles" 
        DependsOnTargets="ResolveScopedCssOutputs">
        <!--Inputs="@(_ScopedCss)" Outputs="@(_ScopedCssOutputs)"   we removed the inputs and outputs because we want this to always run for all files--> 

  <MakeDir Directories="$(_ScopedCssIntermediatePath)" />
  <RewriteCss 
    FilesToTransform="@(_ScopedCss)" 
    SkipIfOutputIsNewer="False" />  <!--we added this parameter since it's not surfaced as a property-->
  <ItemGroup>
    <FileWrites Include="@(_ScopedCss->'%(OutputFile)')" /> <!--we modified this to get to the Output file because we cannot use the initial % notification-->
  </ItemGroup>
</Target>
</Project>

To Reproduce

  1. Create a blazor project
  2. Build it
  3. observe that there's a .razor.rz.scp.css file in the
    obj\Debug\net9.0\scopedcss\DesignSystem\TextStyles\Body
    folder
  4. in the .csproj, add
<ItemGroup>
  <None Update="**\*.razor.css">
    <CssScope>something</CssScope>
  </None>
</ItemGroup>

to override the auto-generated css scope
6. build again
7. observe that the .razor.rz.scp.css file did not change
8. modify one (but only one) of the .razor.css files in the project
9. build again
10. observe that the .razor.rz.scp.css file for that modified .razor.css did indeed change
Include the dotnet --info output here

technical details

  • The IDE (VS / VS Code/ VS4Mac) you're running on, and its version
    VS 2022 17.14.13 on windows 11
    SDK 9.0.304

acknowledgements

Thanks @wasabii for tracking down the root cause. I was initially thinking that this is a problem with dotnet publish not properly clearing. . .
@davidwengier pinging you here since we talked about this on discord.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-AspNetCoreRazorSDK, BlazorWebAssemblySDK, dotnet-watchArea-NetSDKuntriagedRequest triage from a team member

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions