From 3d38d397aed001c1c482447ba4b62aaf5b115866 Mon Sep 17 00:00:00 2001 From: Javier Calvarro Nelson Date: Fri, 4 Sep 2020 19:54:44 +0200 Subject: [PATCH] [Blazor] CSS isolation follow-ups (#25565) This change includes several improvements to CSS isolation that we have gathered from validation and usage feedback. We have switched from producing a single scoped CSS bundle file for the entire application with all the scoped css files from the current project, referenced projects and package projects to producing one bundle per referenced project/package and to include those bundles into an "application" bundle throught CSS @import statements. We have cleaned up the bundle names to make them more unique by including the project name on them and we have also cleaned up the bundle extensions. We have decided to put the individual bundles generated for the project scoped css assets into the static web assets base path of the project, so that when developers reference assets from their scoped css files (like using the CSS url function) the path they use matches what they have inside their library wwwroot folder. We have decided to put the application bundle on the root path of the application provided that the developer has not overriden the default StaticWebAssetsBasePath. This is so that the bundle location is consistent across templates, and can be found at ProjectName.styles.css independent of whether the app is a blazor webassembly app or a server side blazor app. For cases where the default StaticWebAssetBasePath has been overriden, the value is respected and the bundle is placed at $(StaticWebAssetBasePath)/ProjectName.styles.css. Packaged razor class libraries with scoped css files now package a "project" bundle instead of the individual files. --- .../integrationtests/ServiceWorkerAssert.cs | 2 +- .../WasmPublishIntegrationTest.cs | 4 +- ....NET.Sdk.BlazorWebAssembly.Current.targets | 9 +- .../E2ETest/Tests/ComponentRenderingTest.cs | 4 + .../BasicTestApp/wwwroot/index.html | 3 + .../ComponentFromPackage.razor.css | 3 + .../TestContentPackage/wwwroot/styles.css | 3 +- .../TestServer/Components.TestServer.csproj | 17 +- .../TestServer/Pages/_ServerHost.cshtml | 3 +- .../BlazorServerWeb-CSharp/Pages/_Host.cshtml | 2 +- .../Client/wwwroot/index.html | 6 +- .../integrationtests/PackIntegrationTest.cs | 76 +++- .../ScopedCssIntegrationTests.cs | 76 +++- .../StaticWebAssetsIntegrationTest.cs | 52 ++- .../src/ApplyCssScopes.cs | 9 +- .../src/ComputeCssScope.cs | 3 +- .../src/ConcatenateCssFiles.cs | 68 ++- .../src/GenerateStaticWebAssetsManifest.cs | 80 +--- .../src/GenerateStaticWebAsssetsPropsFile.cs | 37 +- .../src/ResolveAllScopedCssAssets.cs | 13 +- .../src/ValidateStaticWebAssetsUniquePaths.cs | 8 +- .../Microsoft.NET.Sdk.Razor.ScopedCss.targets | 249 ++++++++--- ...soft.NET.Sdk.Razor.StaticWebAssets.targets | 50 ++- .../Sdk.Razor.CurrentVersion.targets | 6 +- .../test/ApplyCssScopesTest.cs | 160 +++++++ .../test/ComputeCssScopesTests.cs | 139 ++++++ .../test/ConcatenateFilesTest.cs | 394 ++++++++++++++++++ .../DiscoverDefaultScopedCssItemsTests.cs | 56 +++ ...erateAspNetCoreStaticAssetsManifestTest.cs | 86 +--- .../GenerateStaticWebAssetsPropsFileTest.cs | 134 +++--- .../test/Microsoft.NET.Sdk.Razor.Test.csproj | 11 +- .../test/ResolveAllScopedCssAssetsTest.cs | 124 ++++++ .../Generated/Counter.razor.rz.scp.css | 3 + .../Generated/FetchData.razor.rz.scp.css | 3 + .../Generated/Index.razor.rz.scp.css | 3 + .../TestFiles/Generated/lib.bundle.scp.css | 3 + .../Generated/package.bundle.scp.css | 3 + .../ValidateStaticWebAssetsUniquePathsTest.cs | 94 ++++- 38 files changed, 1599 insertions(+), 397 deletions(-) create mode 100644 src/Components/test/testassets/TestContentPackage/ComponentFromPackage.razor.css create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/ApplyCssScopesTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/ComputeCssScopesTests.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/ConcatenateFilesTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/DiscoverDefaultScopedCssItemsTests.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/ResolveAllScopedCssAssetsTest.cs create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/TestFiles/Generated/Counter.razor.rz.scp.css create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/TestFiles/Generated/FetchData.razor.rz.scp.css create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/TestFiles/Generated/Index.razor.rz.scp.css create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/TestFiles/Generated/lib.bundle.scp.css create mode 100644 src/Razor/Microsoft.NET.Sdk.Razor/test/TestFiles/Generated/package.bundle.scp.css diff --git a/src/Components/WebAssembly/Sdk/integrationtests/ServiceWorkerAssert.cs b/src/Components/WebAssembly/Sdk/integrationtests/ServiceWorkerAssert.cs index 8597d10480..a107f6bd66 100644 --- a/src/Components/WebAssembly/Sdk/integrationtests/ServiceWorkerAssert.cs +++ b/src/Components/WebAssembly/Sdk/integrationtests/ServiceWorkerAssert.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; diff --git a/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs b/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs index c4be79c220..4d77ffa367 100644 --- a/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs +++ b/src/Components/WebAssembly/Sdk/integrationtests/WasmPublishIntegrationTest.cs @@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output. // Verify scoped css - Assert.FileExists(result, blazorPublishDirectory, "_framework", "scoped.styles.css"); + Assert.FileExists(result, blazorPublishDirectory, "blazorwasm.styles.css"); // Verify referenced static web assets Assert.FileExists(result, blazorPublishDirectory, "_content", "RazorClassLibrary", "wwwroot", "exampleJsInterop.js"); @@ -663,7 +663,7 @@ namespace Microsoft.AspNetCore.Razor.Design.IntegrationTests Assert.FileExists(result, blazorPublishDirectory, "_framework", "System.Text.Json.dll"); // Verify dependencies are part of the output. // Verify scoped css - Assert.FileExists(result, blazorPublishDirectory, "_framework", "scoped.styles.css"); + Assert.FileExists(result, blazorPublishDirectory, "blazorwasm.styles.css"); // Verify static assets are in the publish directory Assert.FileExists(result, blazorPublishDirectory, "index.html"); diff --git a/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets b/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets index ceef7f00b1..2afa59307e 100644 --- a/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets +++ b/src/Components/WebAssembly/Sdk/src/targets/Microsoft.NET.Sdk.BlazorWebAssembly.Current.targets @@ -266,11 +266,18 @@ Copyright (c) .NET Foundation. All rights reserved. $(GetCurrentProjectStaticWebAssetsDependsOn); - AddScopedCssBundle; + _BlazorWasmReplaceBundle; _BlazorWasmPrepareForRun; + + + + + + + <_BlazorBuildBootJsonPath>$(IntermediateOutputPath)blazor.boot.json diff --git a/src/Components/test/E2ETest/Tests/ComponentRenderingTest.cs b/src/Components/test/E2ETest/Tests/ComponentRenderingTest.cs index 30e821e027..839ea3159b 100644 --- a/src/Components/test/E2ETest/Tests/ComponentRenderingTest.cs +++ b/src/Components/test/E2ETest/Tests/ComponentRenderingTest.cs @@ -344,6 +344,10 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests var specialStyleDiv = appElement.FindElement(By.ClassName("special-style")); Assert.Equal("50px", specialStyleDiv.GetCssValue("padding")); + // This style is isolated to the component and comes from the bundle that gets generated for BasicTestApp + // and that includes the @import for the TestContentPackage.bundle.scp.css file + Assert.Equal("20px", specialStyleDiv.GetCssValue("font-size")); + // The external components are fully functional, not just static HTML var externalComponentButton = specialStyleDiv.FindElement(By.TagName("button")); Assert.Equal("Click me", externalComponentButton.Text); diff --git a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html index 20c78f34f2..584dcc44bb 100644 --- a/src/Components/test/testassets/BasicTestApp/wwwroot/index.html +++ b/src/Components/test/testassets/BasicTestApp/wwwroot/index.html @@ -9,6 +9,9 @@ + + + diff --git a/src/Components/test/testassets/TestContentPackage/ComponentFromPackage.razor.css b/src/Components/test/testassets/TestContentPackage/ComponentFromPackage.razor.css new file mode 100644 index 0000000000..7703d4b4e1 --- /dev/null +++ b/src/Components/test/testassets/TestContentPackage/ComponentFromPackage.razor.css @@ -0,0 +1,3 @@ +div { + font-size: 20px; +} diff --git a/src/Components/test/testassets/TestContentPackage/wwwroot/styles.css b/src/Components/test/testassets/TestContentPackage/wwwroot/styles.css index 95137fe983..1b4c995098 100644 --- a/src/Components/test/testassets/TestContentPackage/wwwroot/styles.css +++ b/src/Components/test/testassets/TestContentPackage/wwwroot/styles.css @@ -1,10 +1,9 @@ -.special-style { +.special-style { background-image: url('./face.png'); padding: 50px; background-repeat: repeat-x; border: 5px dashed red; font-family: "Comic Sans MS"; - font-size: 20px; font-weight: bold; animation: hideous-rainbow 1s infinite; } diff --git a/src/Components/test/testassets/TestServer/Components.TestServer.csproj b/src/Components/test/testassets/TestServer/Components.TestServer.csproj index 59b8fe5685..5030a5fc78 100644 --- a/src/Components/test/testassets/TestServer/Components.TestServer.csproj +++ b/src/Components/test/testassets/TestServer/Components.TestServer.csproj @@ -1,4 +1,4 @@ - + $(DefaultNetCoreTargetFramework) @@ -36,19 +36,4 @@ - - - - - - diff --git a/src/Components/test/testassets/TestServer/Pages/_ServerHost.cshtml b/src/Components/test/testassets/TestServer/Pages/_ServerHost.cshtml index ebd2beeaf9..2421d246ad 100644 --- a/src/Components/test/testassets/TestServer/Pages/_ServerHost.cshtml +++ b/src/Components/test/testassets/TestServer/Pages/_ServerHost.cshtml @@ -10,6 +10,7 @@ + @@ -41,8 +42,6 @@ - -