Awesome
DartSassBuildWatcherTool
The tool was build to add support of the SASS(SCSS) files compilation in Razor Client Libraries (RCL) to CSS.
Also there is a --watch
option to detect *.sass
and *.scss
file changes in the directory and automatically trigger build operations.
This tool is used separatly of the .NET project files cause of Blazor WASM can't run watchers from the csproj libraries (.net 7).
How to install
The tool installes as global net tool.
dotnet tool install --global DartSassBuildWatcherTool
How to use
Watch
You can use the tool to automatically trigger build commands on files changes in specified directory.
All you need is to specify the wathing directory to the --watch
option.
General use:
dsbw --files /projects/scssproj/myfile.scss --watch /projects/scssproj
The command will use filesystem watch mechanism to detect file changes (create, delete, rename, move, content changes) of the *.sass
and *.scss
at /projects/scssproj
directory and will trigger the build-file command of the /projects/scssproj/myfile.scss.
Razor Client Library (RCL)
The DartSassBuildWatcherTool
bring the support of using the pattern when you want
to separate you core SASS files into the RCL (variables, mixins) and then use the RCL
in your frontend client applications. This pattern is moslty used in the microfrontends.
To use the tool you must specify the pathes in @import
or @use
or other path directives in the specific way.
Example of RCL Configuration
Step 1. Configure basic RCL wwwroot file structure
Create an "Razor Client Library" (RCL) library. Say the name will be BlazorWebKit
.
And the absolute path at the filesystem will be D:\Projects\BlazorWebKit
.
So the wwwroot directory will be at D:\Projects\BlazorWebKit\wwwroot
.
In the wwwroot
directory create basic SASS structure.
| wwwroot
| | blazorwebkit.scss
| | img
| | | add.svg
| | styles
| | | _variables.scss
| | | _mixins.scss
| | | _components.scss
| | | components
| | | | _button.scss
Step 2. Configure file imports at the scss files
The main goal in configuring the import
pathes is to use "absolute" path, but relative to the _content/BlazorWebKit
.
blazorwebkit.scss
@use "_content/BlazorWebKit/styles/_variables";
@use "_content/BlazorWebKit/styles/_mixins";
@use "_content/BlazorWebKit/styles/_components";
.alert {
border: 1px solid $border-dark;
}
nav ul {
@include horizontal-list;
}
img
styles/variables.scss
$base-color: #c6538c;
$border-dark: rgba($base-color, 0.88);
styles/mixins.scss
@mixin reset-list {
margin: 0;
padding: 0;
list-style: none;
}
@mixin horizontal-list {
@include reset-list;
li {
display: inline-block;
margin: {
left: -2px;
right: 2em;
}
}
}
styles/_components.scss
@use "_content/BlazorWebKit/styles/components/_button";
styles/components/_button.scss
@use "_content/BlazorWebKit/styles/_variables";
.button {
font-size: 14px;
font-family: inherit;
background-color: $base-color;
border: $border-dark;
mask-image: url('img/add.svg');
}
Step 3. Run the DartSassBuildWatcherTool and build the main theme blazorwebkit.css
dsbw --files D:\Projects\BlazorWebKit\wwwroot\blazorwebkit.scss \
--map _content/BlazorWebKit=D:\Projects\BlazorWebKit\wwwroot
Option --files
will compile the file blazorwebkit.scss
to the blazorwebkit.css
.
Option --map
will replace the path _content/BlazorWebKit
to the D:\Projects\BlazorWebKit\wwwroot
when resolving the @import
and @use
directives.
!Note that the image path (and fonts) from the img
directory must not include the full path (_content/BlazorWebKit
).
When you consume the library in the client app the Blazor css processor will automatically map library resources to the path _content/BlazorWebKit
.
Step 4. Pack and send the library to your nuget server.
At this stage you will receive ready to use library in your nuget storage.
Additional information
If you're using .NET 7 Blazor, the *.csproj
configuration of the RCL is pretty standard and doesn't require any additional configuration.
Example of the BlazorWebKit.csproj
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="7.0.0" />
</ItemGroup>
</Project>
If you are in active library development than you can use --watch
option.
dsbw --files D:\Projects\BlazorWebKit\wwwroot\blazorwebkit.scss \
--map _content/BlazorWebKit=D:\Projects\BlazorWebKit\wwwroot \
--watch D:\Projects\BlazorWebKit\wwwroot
Example of Frontend Client Application Configuration
Step 1. Consume BlazorWebKit library in your Blazor Client App
Create or use existing Blazor client application. Say it will be BlazorFrontend
at D:\Projects\BlazorFrontend\BlazorFrontend.csproj
If you are using Blazor WebAssembley (WASM) include in the wwwroot/index.html
the link to the BlazorWebKit
library style.
<html>
<head>
<!-- inside of head section -->
<link href="_content/BlazorWebKit/blazorwebkit.css" rel="stylesheet" />
</head>
<body>
<div id="app"></div>
</body>
</html>
Step 2. Create the component MyButton
Create the component MyButton
.
Components/MyButton.razor
<button @onclick="() => Clicked.InvokeAsync()" class="mybutton">
@ChildContent
</button>
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
/// <summary>
/// Occurs when the button is clicked.
/// </summary>
[Parameter]
public EventCallback<MouseEventArgs> Clicked { get; set; }
}
Create the style file for MyButton
component. And import the variables from the library.
Components/MyButton.razor.scss
@use "_content/BlazorWebKit/styles/_variables";
.mybutton {
border: $border-dark;
}
Step 3. Compile styles from directory Components to css
dsbw --dir D:\Projects\BlazorFrontend\Components \
--proj D:\Projects\BlazorFrontend\BlazorFrontend.csproj
Option --dir
will compile all *.scss
and *.sass
files corresponsive css
files.
Option --proj
will parse the csproj file and try to map installed directories to the path to installed nuget directory.
The tool will try to map libraries from <PackageReference>
to standard pathes:
- Windows:
%userprofile%\.nuget\packages
- Mac/Linux:
~/.nuget/packages
If the Client App references the library project by <ProjectReference>
, than the tool will use the path from <ProjectReference Include="<path-to-library>">
.
If you want to use Blazor WASM hot reload, than you can run the DartSassBuildWatcherTool
in the --watch
mode.
dsbw --dir D:\Projects\BlazorFrontend\Components \
--proj D:\Projects\BlazorFrontend\BlazorFrontend.csproj
--watch D:\Projects\BlazorFrontend\Components