ABP Global Assets - New way to bundle JavaScript/CSS files in Blazor WebAssembly app
We have introduced a new feature in the ABP framework to bundle the JavaScript/CSS files in the Blazor wasm app. This feature is called Global Assets.
With this feature, you don't need to run the abp bundle command to manually create/maintain the global.js and global.css files in your Blazor wasm app.
How Global Assets works?
The new Blazor wasm app has two projects:
MyProjectName(ASP.NET Core app)MyProjectName.Client(Blazor wasm app)
The MyProjectName reference the MyProjectName.Client project, and will be the entry point of the application, which means the MyProjectName project will be the host project of the MyProjectName.Client project.
The static/virtual files of MyProjectName can be accessed by the MyProjectName.Client project, so we can create dynamic global assets in the MyProjectName project and use them in the MyProjectName.Client project.
How it works in ABP?
We have created a new package WebAssembly.Theme.Bundling for the theme WebAssembly module and used the Volo.Abp.AspNetCore.Mvc.UI.Bundling.BundleContributor to add JavaScript/CSS files to the bundling system.
- LeptonXLiteTheme:
AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule - LeptonXTheme:
AbpAspNetCoreComponentsWebAssemblyLeptonXThemeBundlingModule - LeptonTheme:
AbpAspNetCoreComponentsWebAssemblyLeptonThemeBundlingModule - BasicTheme:
AbpAspNetCoreComponentsWebAssemblyBasicThemeBundlingModule
The new ThemeBundlingModule only depends on AbpAspNetCoreComponentsWebAssemblyThemingBundlingModule(new package). It's an abstractions module, which only depends on AbpAspNetCoreMvcUiBundlingAbstractionsModule.
We will get all JavaScript/CSS files on OnApplicationInitializationAsync method of AbpAspNetCoreMvcUiBundlingModule from bundling system and add them to IDynamicFileProvider service. After that, we can access the JavaScript/CSS files in the Blazor wasm app.
Add the Global Assets in the module
If your module has JavaScript/CSS files that need to the bundling system, You have to create a new project(YourModuleName.Blazor.WebAssembly.Bundling) to your module solution, and reference the new project in the MyProjectName project and module dependencies.
The new project should only depend on the AbpAspNetCoreComponentsWebAssemblyThemingBundlingModule and define BundleContributor classes to contribute the JavaScript/CSS files.
Q: The new project(
YourModuleName.Blazor.WebAssembly.Bundling) doesn't have thelibs/myscript.jsandlibs/myscript.cssfiles why the files can be added to the bundling system?
A: Because the
MyProjectName.Clientwill depend on theMyBlazorModule(YourModuleName.Blazor)that contains theJavaScript/CSSfiles, TheMyProjectNameis referencing theMyProjectName.Clientproject, so theMyProjectNameproject can access theJavaScript/CSSfiles in theMyProjectName.Clientproject and add them to the bundling system.
[DependsOn(
typeof(AbpAspNetCoreComponentsWebAssemblyThemingBundlingModule)
)]
public class MyBlazorWebAssemblyBundlingModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpBundlingOptions>(options =>
{
// Script Bundles
options.ScriptBundles.Get(BlazorWebAssemblyStandardBundles.Scripts.Global).AddContributors(typeof(MyModuleBundleScriptContributor));
// Style Bundles
options.StyleBundles.Get(BlazorWebAssemblyStandardBundles.Styles.Global).AddContributors(typeof(MyModuleBundleStyleBundleContributor));
});
}
}
public class MyModuleBundleScriptContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddIfNotContains("_content/MyModule.Blazor/libs/myscript.js");
}
}
public class MyModuleBundleStyleBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddIfNotContains("_content/MyModule.Blazor/libs/myscript.css");
}
}
Use the Global Assets in the Blazor WASM
MyCompanyName.MyProjectName.Blazor
Convert your MyCompanyName.MyProjectName.Blazor project to integrate the ABP module system and depend on the AbpAspNetCoreMvcUiBundlingModule and AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule/AbpAspNetCoreComponentsWebAssemblyLeptonXThemeBundlingModule:
- The
AbpAspNetCoreMvcUiBundlingModuleuses to create theJavaScript/CSSfiles to virtual files. - The
AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule/AbpAspNetCoreComponentsWebAssemblyLeptonXThemeBundlingModuleuses to add themeJavaScript/CSSto the bundling system.
Here is how your project files look like:
Program.cs:
public class Program
{
public async static Task<int> Main(string[] args)
{
//...
var builder = WebApplication.CreateBuilder(args);
builder.Host.AddAppSettingsSecretsJson()
.UseAutofac()
.UseSerilog();
await builder.AddApplicationAsync<MyProjectNameBlazorModule>();
var app = builder.Build();
await app.InitializeApplicationAsync();
await app.RunAsync();
return 0;
//...
}
}
MyProjectNameBlazorModule.cs:
[DependsOn(
typeof(AbpAutofacModule),
typeof(AbpAspNetCoreMvcUiBundlingModule),
typeof(AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule/AbpAspNetCoreComponentsWebAssemblyLeptonXThemeBundlingModule) //Should be added!
)]
public class MyProjectNameBlazorModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
//https://github.com/dotnet/aspnetcore/issues/52530
Configure<RouteOptions>(options =>
{
options.SuppressCheckForUnhandledSecurityMetadata = true;
});
// Add services to the container.
context.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents();
}
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var env = context.GetEnvironment();
var app = context.GetApplicationBuilder();
// Configure the HTTP request pipeline.
if (env.IsDevelopment())
{
app.UseWebAssemblyDebugging();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.MapAbpStaticAssets();
app.UseRouting();
app.UseAntiforgery();
app.UseConfiguredEndpoints(builder =>
{
builder.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode()
.AddAdditionalAssemblies(WebAppAdditionalAssembliesHelper.GetAssemblies<MyProjectNameBlazorClientModule>());
});
}
}
MyCompanyName.MyProjectName.Blazor.csproj:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.0.0" />
<PackageReference Include="Volo.Abp.Autofac" Version="9.0.0" />
<PackageReference Include="Volo.Abp.AspNetCore.Mvc.UI.Bundling" Version="9.0.0" />
<PackageReference Include="Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme.Bundling" Version="9.0.0" />
<!-- <PackageReference Include="Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXTheme.Bundling" Version="9.0.0" /> --> if you're using LeptonXTheme
<ProjectReference Include="..\MyProjectName.Blazor.Client\MyProjectName.Blazor.Client.csproj" />
</ItemGroup>
BlazorWebAssemblyBundlingModule in the ABP commercial
Here is the list of Bundling Modules in the ABP commercial. If you're using the pro template, you should add them to the MyCompanyName.MyProjectName.Blazor project.
| BundlingModules | Nuget Package |
|---|---|
| AbpAuditLoggingBlazorWebAssemblyBundlingModule | Volo.Abp.AuditLogging.Blazor.WebAssembly.Bundling |
| FileManagementBlazorWebAssemblyBundlingModule | Volo.FileManagement.Blazor.WebAssembly.Bundling |
| SaasHostBlazorWebAssemblyBundlingModule | Volo.Saas.Host.Blazor.WebAssembly.Bundling |
| ChatBlazorWebAssemblyBundlingModule | Volo.Chat.Blazor.WebAssembly.Bundling |
| CmsKitProAdminBlazorWebAssemblyBundlingModule | Volo.CmsKit.Pro.Admin.Blazor.WebAssembly.Bundling |
MyCompanyName.MyProjectName.Blazor.Client
- Remove the
global.JavaScript/CSSfiles from theMyCompanyName.MyProjectName.Blazor'swwwrootfolder. - Remove the
AbpCli:Bundlesection from theappsettings.jsonfile. - Remove all BundleContributor classes that inherit from IBundleContributor. Then, create
MyProjectNameStyleBundleContributorandMyProjectNameScriptBundleContributorclasses to add your style and JavaScript files. Finally, add them toAbpBundlingOptions.
public class MyProjectNameStyleBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add(new BundleFile("main.css", true));
}
}
public class MyProjectNameScriptBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add(new BundleFile("main.js", true));
}
}
Configure<AbpBundlingOptions>(options =>
{
var globalStyles = options.StyleBundles.Get(BlazorWebAssemblyStandardBundles.Styles.Global);
globalStyles.AddContributors(typeof(MyProjectNameStyleBundleContributor));
var globalScripts = options.ScriptBundles.Get(BlazorWebAssemblyStandardBundles.Scripts.Global);
globalScripts.AddContributors(typeof(MyProjectNameScriptBundleContributor));
});
Use the Global Assets in the Blazor WebApp
MyCompanyName.MyProjectName.Blazor.WebApp
Depending on the AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule/AbpAspNetCoreComponentsWebAssemblyLeptonXThemeBundlingModule in your MyCompanyName.MyProjectName.Blazor.WebApp project.
- The
AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule/AbpAspNetCoreComponentsWebAssemblyLeptonXThemeBundlingModuleuses to add themeJavaScript/CSSto the bundling system.
BlazorWebAssemblyBundlingModule in the ABP commercial
Here is the list of Bundling Modules in the ABP commercial. If you're using the pro template, you should add them to the MyCompanyName.MyProjectName.Blazor.WebApp project.
| BundlingModules | Nuget Package |
|---|---|
| AbpAuditLoggingBlazorWebAssemblyBundlingModule | Volo.Abp.AuditLogging.Blazor.WebAssembly.Bundling |
| FileManagementBlazorWebAssemblyBundlingModule | Volo.FileManagement.Blazor.WebAssembly.Bundling |
| SaasHostBlazorWebAssemblyBundlingModule | Volo.Saas.Host.Blazor.WebAssembly.Bundling |
| ChatBlazorWebAssemblyBundlingModule | Volo.Chat.Blazor.WebAssembly.Bundling |
| CmsKitProAdminBlazorWebAssemblyBundlingModule | Volo.CmsKit.Pro.Admin.Blazor.WebAssembly.Bundling |
MyCompanyName.MyProjectName.Blazor.WebApp.Client
- Remove the
global.JavaScript/CSSfiles from theMyCompanyName.MyProjectName.Blazor.WebApp.Client'swwwrootfolder. - Remove the
AbpCli:Bundlesection from theappsettings.jsonfile. - Remove all BundleContributor classes that inherit from IBundleContributor. Then, create
MyProjectNameStyleBundleContributorandMyProjectNameScriptBundleContributorclasses to add your style and JavaScript files. Finally, add them toAbpBundlingOptions.
public class MyProjectNameStyleBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add(new BundleFile("main.css", true));
}
}
public class MyProjectNameScriptBundleContributor : BundleContributor
{
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.Add(new BundleFile("main.js", true));
}
}
Configure<AbpBundlingOptions>(options =>
{
var globalStyles = options.StyleBundles.Get(BlazorWebAssemblyStandardBundles.Styles.Global);
globalStyles.AddContributors(typeof(MyProjectNameStyleBundleContributor));
var globalScripts = options.ScriptBundles.Get(BlazorWebAssemblyStandardBundles.Scripts.Global);
globalScripts.AddContributors(typeof(MyProjectNameScriptBundleContributor));
});
Check the Global Assets
Run the MyProject project and check the https://localhost/global.js and https://localhost/global.css files. You should be able to see the JavaScript/CSS files content from the Bundling system:

GlobalAssets(AbpBundlingGlobalAssetsOptions)
You can configure the JavaScript and CSS file names in the GlobalAssets property of the AbpBundlingOptions class.
The default values are global.js and global.css.
Conclusion
With the new Global Assets feature, you can easily bundle the JavaScript/CSS files in the Blazor wasm app. This feature is very useful for the Blazor wasm app, and it will save you a lot of time and effort. We hope you will enjoy this feature and use it in your projects.
Comments
Jiaqing Liu 36 weeks ago
Hi, I'm using Blazor Web App version 8.3.0. I can't find the package Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXTheme.Bundling. How can I get it?