mirror of https://github.com/abpframework/abp.git
committed by
GitHub
109 changed files with 1204 additions and 653 deletions
@ -0,0 +1,208 @@ |
|||
# 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: |
|||
|
|||
1. `MyProjectName` (ASP.NET Core app) |
|||
2. `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 the `libs/myscript.js` and `libs/myscript.css` files why the files can be added to the bundling system? |
|||
|
|||
> A: Because the `MyProjectName.Client` will depend on the `MyBlazorModule(YourModuleName.Blazor)` that contains the `JavaScript/CSS` files, The `MyProjectName` is referencing the `MyProjectName.Client` project, so the `MyProjectName` project can access the `JavaScript/CSS` files in the `MyProjectName.Client` project and add them to the bundling system. |
|||
|
|||
```csharp |
|||
[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.ScriptBundles.Get(BlazorWebAssemblyStandardBundles.Scripts.Global).AddContributors(typeof(MyModuleBundleStyleBundleContributor)); |
|||
}); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
```csharp |
|||
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 app |
|||
|
|||
### MyProject |
|||
|
|||
Convert your `MyProject` project to integrate the `ABP module` system and depend on the `AbpAspNetCoreMvcUiBundlingModule` and `AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule`: |
|||
|
|||
> If the `BlazorWebAssembly modules` in `MyProject.Client` contain `BundleContributor`, Please also add the `BlazorWebAssemblyBundlingModule` of the module to the `MyProject` project. |
|||
|
|||
* The `AbpAspNetCoreMvcUiBundlingModule` uses to create the `JavaScript/CSS` files to virtual files. |
|||
* The `AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule` uses to add theme `JavaScript/CSS` to the bundling system. |
|||
|
|||
Here is how your project files look like: |
|||
|
|||
**`Program.cs`:** |
|||
|
|||
```csharp |
|||
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`:** |
|||
|
|||
```csharp |
|||
[DependsOn( |
|||
typeof(AbpAutofacModule), |
|||
typeof(AbpAspNetCoreMvcUiBundlingModule), |
|||
typeof(AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule) //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>()); |
|||
}); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
**`MyProjectName.csproj`:** |
|||
|
|||
```xml |
|||
<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" /> |
|||
<ProjectReference Include="..\MyProjectName.Blazor.Client\MyProjectName.Blazor.Client.csproj" /> |
|||
</ItemGroup> |
|||
``` |
|||
|
|||
### MyProjectName.Client |
|||
|
|||
1. Remove the `global.JavaScript/CSS` files from the `MyProjectName.Client`'s `wwwroot` folder. |
|||
2. Refactor all BundleContributor classes that inherit from `IBundleContributor` to inherit from `BundleContributor` instead. |
|||
3. Remove the `AbpCli:Bundle` section from the `appsettings.json` file. |
|||
|
|||
### 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. |
|||
|
|||
## References |
|||
|
|||
* [Virtual Files](https://docs.abp.io/en/abp/latest/Virtual-Files) |
|||
* [Bundle Contributors](https://abp.io/docs/latest/framework/ui/mvc-razor-pages/bundling-minification#bundle-contributors) |
|||
* [Global Assets Pull Request](https://github.com/abpframework/abp/pull/19968) |
|||
|
|||
|
After Width: | Height: | Size: 360 KiB |
@ -0,0 +1,34 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Components.MauiBlazor.Theming.Bundling; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAspNetCoreMvcUiBundlingAbstractionsModule) |
|||
)] |
|||
public class AbpAspNetCoreComponentsMauiBlazorThemingBundlingModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpBundlingOptions>(options => |
|||
{ |
|||
options.GlobalAssets.Enabled = true; |
|||
options.GlobalAssets.GlobalStyleBundleName = MauiBlazorStandardBundles.Styles.Global; |
|||
options.GlobalAssets.GlobalScriptBundleName = MauiBlazorStandardBundles.Scripts.Global; |
|||
|
|||
options |
|||
.StyleBundles |
|||
.Add(MauiBlazorStandardBundles.Styles.Global, bundle => |
|||
{ |
|||
bundle.AddContributors(typeof(MauiStyleContributor)); |
|||
}); |
|||
|
|||
options |
|||
.ScriptBundles |
|||
.Add(MauiBlazorStandardBundles.Scripts.Global, bundle => |
|||
{ |
|||
bundle.AddContributors(typeof(MauiScriptContributor)); |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,14 @@ |
|||
namespace Volo.Abp.AspNetCore.Components.MauiBlazor.Theming.Bundling; |
|||
|
|||
public class MauiBlazorStandardBundles |
|||
{ |
|||
public static class Styles |
|||
{ |
|||
public static string Global = "MauiBlazor.Global"; |
|||
} |
|||
|
|||
public static class Scripts |
|||
{ |
|||
public static string Global = "MauiBlazor.Global"; |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Components.MauiBlazor.Theming.Bundling; |
|||
|
|||
public class MauiScriptContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/abp.js"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/lang-utils.js"); |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Components.MauiBlazor.Theming.Bundling; |
|||
|
|||
public class MauiStyleContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/libs/bootstrap/css/bootstrap.min.css"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/libs/fontawesome/css/all.css"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/css/abp.css"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.MauiBlazor.Theming/libs/flag-icon/css/flag-icon.css"); |
|||
context.Files.AddIfNotContains("_content/Blazorise/blazorise.css"); |
|||
context.Files.AddIfNotContains("_content/Blazorise.Bootstrap5/blazorise.bootstrap5.css"); |
|||
context.Files.AddIfNotContains("_content/Blazorise.Snackbar/blazorise.snackbar.css"); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Razor"> |
|||
|
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net9.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
<WarningsAsErrors>Nullable</WarningsAsErrors> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Bundling.Abstractions\Volo.Abp.AspNetCore.Mvc.UI.Bundling.Abstractions.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,37 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Bundling; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAspNetCoreMvcUiBundlingAbstractionsModule) |
|||
)] |
|||
public class AbpAspNetCoreComponentsWebAssemblyThemingBundlingModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpBundlingOptions>(options => |
|||
{ |
|||
options.GlobalAssets.Enabled = true; |
|||
options.GlobalAssets.GlobalStyleBundleName = BlazorWebAssemblyStandardBundles.Styles.Global; |
|||
options.GlobalAssets.GlobalScriptBundleName = BlazorWebAssemblyStandardBundles.Scripts.Global; |
|||
|
|||
options |
|||
.StyleBundles |
|||
.Add(BlazorWebAssemblyStandardBundles.Styles.Global, bundle => |
|||
{ |
|||
bundle.AddContributors(typeof(BlazorWebAssemblyStyleContributor)); |
|||
}); |
|||
|
|||
options |
|||
.ScriptBundles |
|||
.Add(BlazorWebAssemblyStandardBundles.Scripts.Global, bundle => |
|||
{ |
|||
bundle.AddContributors(typeof(BlazorWebAssemblyScriptContributor)); |
|||
}); |
|||
|
|||
options.MinificationIgnoredFiles.Add("_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Bundling; |
|||
|
|||
public class BlazorWebAssemblyScriptContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.AddIfNotContains("_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/abp.js"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/lang-utils.js"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/lang-utils.js"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/js/authentication-state-listener.js"); |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Bundling; |
|||
|
|||
public class BlazorWebAssemblyStandardBundles |
|||
{ |
|||
public static class Styles |
|||
{ |
|||
public static string Global = "BlazorWebAssembly.Global"; |
|||
} |
|||
|
|||
public static class Scripts |
|||
{ |
|||
public static string Global = "BlazorWebAssembly.Global"; |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Bundling; |
|||
|
|||
public class BlazorWebAssemblyStyleContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/bootstrap/css/bootstrap.min.css"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/fontawesome/css/all.css"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.Web/libs/abp/css/abp.css"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.WebAssembly.Theming/libs/flag-icon/css/flag-icon.css"); |
|||
context.Files.AddIfNotContains("_content/Blazorise/blazorise.css"); |
|||
context.Files.AddIfNotContains("_content/Blazorise.Bootstrap5/blazorise.bootstrap5.css"); |
|||
context.Files.AddIfNotContains("_content/Blazorise.Snackbar/blazorise.snackbar.css"); |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.BlazoriseUI/volo.abp.blazoriseui.css"); |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,16 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Razor"> |
|||
|
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net9.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
<WarningsAsErrors>Nullable</WarningsAsErrors> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.AspNetCore.Mvc.UI.Bundling.Abstractions\Volo.Abp.AspNetCore.Mvc.UI.Bundling.Abstractions.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,20 @@ |
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
public class AbpBundlingGlobalAssetsOptions |
|||
{ |
|||
public bool Enabled { get; set; } |
|||
|
|||
public string? GlobalStyleBundleName { get; set; } |
|||
|
|||
public string? GlobalScriptBundleName { get; set; } |
|||
|
|||
public string JavaScriptFileName { get; set; } |
|||
|
|||
public string CssFileName { get; set; } |
|||
|
|||
public AbpBundlingGlobalAssetsOptions() |
|||
{ |
|||
JavaScriptFileName = "global.js"; |
|||
CssFileName = "global.css"; |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
public class BundleParameterDictionary : Dictionary<string, string> |
|||
{ |
|||
public const string InteractiveAutoPropertyName = "InteractiveAuto"; |
|||
|
|||
public bool InteractiveAuto |
|||
{ |
|||
get |
|||
{ |
|||
return TryGetValue(InteractiveAutoPropertyName, out var value) && bool.Parse(value); |
|||
} |
|||
set |
|||
{ |
|||
this[InteractiveAutoPropertyName] = value.ToString(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,76 +0,0 @@ |
|||
using System; |
|||
using System.IO; |
|||
using System.Text.RegularExpressions; |
|||
|
|||
namespace Volo.Abp.Cli.Bundling.Styles; |
|||
|
|||
internal static class CssRelativePathAdjuster |
|||
{ |
|||
private static readonly Regex _rxUrl = new Regex(@"url\s*\(\s*([""']?)([^:)]+)\1\s*\)", RegexOptions.IgnoreCase | RegexOptions.Compiled); |
|||
|
|||
public static string Adjust( |
|||
string cssFileContents, |
|||
string absoluteInputFilePath, |
|||
string absoluteOutputPath) |
|||
{ |
|||
var matches = _rxUrl.Matches(cssFileContents); |
|||
|
|||
if (matches.Count <= 0) |
|||
{ |
|||
return cssFileContents; |
|||
} |
|||
|
|||
var cssDirectoryPath = Path.GetDirectoryName(absoluteInputFilePath); |
|||
|
|||
foreach (Match match in matches) |
|||
{ |
|||
string quoteDelimiter = match.Groups[1].Value; //url('') vs url("")
|
|||
string relativePathToCss = match.Groups[2].Value; |
|||
|
|||
// Ignore root relative references
|
|||
if (relativePathToCss.StartsWith("/", StringComparison.Ordinal)) |
|||
continue; |
|||
|
|||
//prevent query string from causing error
|
|||
var pathAndQuery = relativePathToCss.Split(new[] { '?' }, 2, StringSplitOptions.RemoveEmptyEntries); |
|||
var pathOnly = pathAndQuery[0]; |
|||
var queryOnly = pathAndQuery.Length == 2 ? pathAndQuery[1] : string.Empty; |
|||
|
|||
string absolutePath = GetAbsolutePath(cssDirectoryPath, pathOnly); |
|||
string serverRelativeUrl = MakeRelative(absoluteOutputPath, absolutePath); |
|||
|
|||
if (!string.IsNullOrEmpty(queryOnly)) |
|||
serverRelativeUrl += "?" + queryOnly; |
|||
|
|||
string replace = string.Format("url({0}{1}{0})", quoteDelimiter, serverRelativeUrl); |
|||
|
|||
cssFileContents = cssFileContents.Replace(match.Groups[0].Value, replace); |
|||
} |
|||
|
|||
return cssFileContents; |
|||
} |
|||
|
|||
private static string GetAbsolutePath(string cssFilePath, string pathOnly) |
|||
{ |
|||
return Path.GetFullPath(Path.Combine(cssFilePath, pathOnly)); |
|||
} |
|||
|
|||
private static readonly string _protocol = "file:///"; |
|||
private static string MakeRelative(string baseFile, string file) |
|||
{ |
|||
if (string.IsNullOrEmpty(file)) |
|||
return file; |
|||
|
|||
Uri baseUri = new Uri(_protocol + baseFile, UriKind.RelativeOrAbsolute); |
|||
Uri fileUri = new Uri(_protocol + file, UriKind.RelativeOrAbsolute); |
|||
|
|||
if (baseUri.IsAbsoluteUri) |
|||
{ |
|||
return Uri.UnescapeDataString(baseUri.MakeRelativeUri(fileUri).ToString()); |
|||
} |
|||
else |
|||
{ |
|||
return baseUri.ToString(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Bundling; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAspNetCoreComponentsWebAssemblyThemingBundlingModule) |
|||
)] |
|||
public class AbpAspNetCoreComponentsWebAssemblyBasicThemeBundlingModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpBundlingOptions>(options => |
|||
{ |
|||
var globalStyles = options.StyleBundles.Get(BlazorWebAssemblyStandardBundles.Styles.Global); |
|||
globalStyles.AddContributors(typeof(BasicThemeBundleStyleContributor)); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Bundling; |
|||
|
|||
public class BasicThemeBundleStyleContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.AddIfNotContains("_content/Volo.Abp.AspNetCore.Components.Web.BasicTheme/libs/abp/css/theme.css"); |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,15 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Razor"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net9.0</TargetFramework> |
|||
<PackageId>Volo.Abp.AspNetCore.Components.WebAssembly.BasicTheme.Bundling</PackageId> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Bundling\Volo.Abp.AspNetCore.Components.WebAssembly.Theming.Bundling.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -1,19 +1,14 @@ |
|||
using Volo.Abp.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace MyCompanyName.MyProjectName; |
|||
|
|||
/* Add your global styles/scripts here. |
|||
* See https://docs.abp.io/en/abp/latest/UI/Blazor/Global-Scripts-Styles to learn how to use it
|
|||
*/ |
|||
public class MyProjectNameBundleContributor : IBundleContributor |
|||
public class MyProjectNameBundleContributor : BundleContributor |
|||
{ |
|||
public void AddScripts(BundleContext context) |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
|
|||
} |
|||
|
|||
public void AddStyles(BundleContext context) |
|||
{ |
|||
context.Add("main.css", true); |
|||
context.Files.Add(new BundleFile("main.css", true)); |
|||
} |
|||
} |
|||
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,19 +1,14 @@ |
|||
using Volo.Abp.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Client; |
|||
|
|||
/* Add your global styles/scripts here. |
|||
* See https://abp.io/docs/latest/framework/ui/blazor/global-scripts-styles to learn how to use it
|
|||
*/ |
|||
public class MyProjectNameBundleContributor : IBundleContributor |
|||
public class MyProjectNameBundleContributor : BundleContributor |
|||
{ |
|||
public void AddScripts(BundleContext context) |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
|
|||
} |
|||
|
|||
public void AddStyles(BundleContext context) |
|||
{ |
|||
context.Add("main.css", true); |
|||
context.Files.Add(new BundleFile("main.css", true)); |
|||
} |
|||
} |
|||
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,19 +1,14 @@ |
|||
using Volo.Abp.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebApp.Client; |
|||
|
|||
/* Add your global styles/scripts here. |
|||
* See https://docs.abp.io/en/abp/latest/UI/Blazor/Global-Scripts-Styles to learn how to use it
|
|||
*/ |
|||
public class MyProjectNameBundleContributor : IBundleContributor |
|||
public class MyProjectNameBundleContributor : BundleContributor |
|||
{ |
|||
public void AddScripts(BundleContext context) |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
|
|||
} |
|||
|
|||
public void AddStyles(BundleContext context) |
|||
{ |
|||
context.Add("main.css", true); |
|||
context.Files.Add(new BundleFile("main.css", true)); |
|||
} |
|||
} |
|||
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,19 +1,14 @@ |
|||
using Volo.Abp.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client; |
|||
|
|||
/* Add your global styles/scripts here. |
|||
* See https://docs.abp.io/en/abp/latest/UI/Blazor/Global-Scripts-Styles to learn how to use it
|
|||
*/ |
|||
public class MyProjectNameBundleContributor : IBundleContributor |
|||
public class MyProjectNameBundleContributor : BundleContributor |
|||
{ |
|||
public void AddScripts(BundleContext context) |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
|
|||
} |
|||
|
|||
public void AddStyles(BundleContext context) |
|||
{ |
|||
context.Add("main.css", true); |
|||
context.Files.Add(new BundleFile("main.css", true)); |
|||
} |
|||
} |
|||
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,63 @@ |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.Routing; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using MyCompanyName.MyProjectName.Blazor.Client; |
|||
using Volo.Abp; |
|||
using Volo.Abp.AspNetCore.Components.WebAssembly.LeptonXLiteTheme.Bundling; |
|||
using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAutofacModule), |
|||
typeof(AbpAspNetCoreMvcUiBundlingModule), |
|||
typeof(AbpAspNetCoreComponentsWebAssemblyLeptonXLiteThemeBundlingModule) |
|||
)] |
|||
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>()); |
|||
}); |
|||
} |
|||
} |
|||
@ -1,43 +1,57 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.Routing; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using MyCompanyName.MyProjectName.Blazor; |
|||
using MyCompanyName.MyProjectName.Blazor.Client; |
|||
using Volo.Abp.AspNetCore.Components.WebAssembly.WebApp; |
|||
using Serilog; |
|||
using Serilog.Events; |
|||
|
|||
var builder = WebApplication.CreateBuilder(args); |
|||
namespace MyCompanyName.MyProjectName.Blazor; |
|||
|
|||
//https://github.com/dotnet/aspnetcore/issues/52530
|
|||
builder.Services.Configure<RouteOptions>(options => |
|||
public class Program |
|||
{ |
|||
options.SuppressCheckForUnhandledSecurityMetadata = true; |
|||
}); |
|||
|
|||
// Add services to the container.
|
|||
builder.Services.AddRazorComponents() |
|||
.AddInteractiveWebAssemblyComponents(); |
|||
|
|||
var app = builder.Build(); |
|||
|
|||
// Configure the HTTP request pipeline.
|
|||
if (app.Environment.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.MapStaticAssets(); |
|||
app.UseAntiforgery(); |
|||
|
|||
app.MapRazorComponents<App>() |
|||
.AddInteractiveWebAssemblyRenderMode() |
|||
.AddAdditionalAssemblies(WebAppAdditionalAssembliesHelper.GetAssemblies<MyProjectNameBlazorClientModule>()); |
|||
|
|||
await app.RunAsync(); |
|||
public async static Task<int> Main(string[] args) |
|||
{ |
|||
Log.Logger = new LoggerConfiguration() |
|||
#if DEBUG
|
|||
.MinimumLevel.Debug() |
|||
#else
|
|||
.MinimumLevel.Information() |
|||
#endif
|
|||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information) |
|||
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) |
|||
.Enrich.FromLogContext() |
|||
.WriteTo.Async(c => c.File("Logs/logs.txt")) |
|||
.WriteTo.Async(c => c.Console()) |
|||
.CreateLogger(); |
|||
|
|||
try |
|||
{ |
|||
Log.Information("Starting web host."); |
|||
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; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
if (ex is HostAbortedException) |
|||
{ |
|||
throw; |
|||
} |
|||
|
|||
Log.Fatal(ex, "Host terminated unexpectedly!"); |
|||
return 1; |
|||
} |
|||
finally |
|||
{ |
|||
Log.CloseAndFlush(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,16 +1,14 @@ |
|||
using Volo.Abp.Bundling; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace MyCompanyName.MyProjectName.Blazor.Host.Client; |
|||
|
|||
public class MyProjectNameBlazorHostBundleContributor : IBundleContributor |
|||
/* Add your global styles/scripts here. |
|||
* See https://docs.abp.io/en/abp/latest/UI/Blazor/Global-Scripts-Styles to learn how to use it
|
|||
*/ |
|||
public class MyProjectNameBlazorHostBundleContributor : BundleContributor |
|||
{ |
|||
public void AddScripts(BundleContext context) |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
|
|||
} |
|||
|
|||
public void AddStyles(BundleContext context) |
|||
{ |
|||
context.Add("main.css", true); |
|||
context.Files.Add(new BundleFile("main.css", true)); |
|||
} |
|||
} |
|||
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue