ABP Blazor 的 Bundling 和 Minification

news/2025/1/8 12:06:38/文章来源:https://www.cnblogs.com/yada/p/18657370

Bundling(打包)指将多个JavaScript文件、CSS文件合并成一个或几个文件的过程。

Bundling的主要目的:

  • 减少HTTP请求:通过合并文件,可以减少浏览器需要发起的HTTP请求数量,从而加快首页加载速度。
  • 依赖管理:自动处理模块之间的依赖关系,确保代码正确执行。
  • 代码分割:支持将代码分割成多个块(chunks),按需加载,进一步优化性能。

Minification(压缩)指在不更改功能的情况下从代码中删除不必要的字符,例如将变量名称缩短为一个字符、删除注释和不必要的空格。

Minification的主要目的:

  • 减少文件体积:通过去除不必要的字符,可以显著减少文件的大小,从而减少传输的时间和带宽消耗。
  • 提高加载速度:较小的文件可以更快的加载,加快页面的加载速度。

有许多方法可以打包(bundling)和压缩(minification)客户端资源(JavaScript和CSS文件)。最常见的方法是:

  • 使用Bundler & Minifier Visual Studio扩展或NuGet包。
  • 使用Gulp/Grunt任务管理器及其插件。

ABP是模块化的,各个模块使用的脚本和样式需要在index.html文件中引用。ABP提供了一种内置的方式,简单、动态、模块化地执行Bundling和Minification。

ABP的App.razor文件如下:

<!DOCTYPE html>
<html lang="@CultureInfo.CurrentCulture.Name" dir="@rtl">
<head>...<AbpStyles BundleName="@BlazorLeptonXLiteThemeBundles.Styles.Global" WebAssemblyStyleFiles="GlobalStyles" @rendermode="InteractiveAuto" />...
</head>
<body class="abp-application-layout @rtl">...<AbpScripts BundleName="@BlazorLeptonXLiteThemeBundles.Scripts.Global" WebAssemblyScriptFiles="GlobalScripts" @rendermode="InteractiveAuto" /><script src="_framework/blazor.web.js"></script></body>
</html>
@code{private List<string> GlobalStyles =>["global.css",];private List<string> GlobalScripts =>["global.js"];
}

<AbpStyles>​标签将输出为:

<link rel="stylesheet" href=“...” />

<AbpScripts>​标签将输出为:

<script src="..." />

对于Blazor Server和Blazor WebAssembly,执行Bundling和Minification的原理有所不同。

Blazor Server 中

Blazor Server中的 Bundling 和 Minification 是动态执行的,它与ABP MVC的Bundling过程很相似(使用的标签不同)。通过在模块类中ConfigureServices​方法中配置AbpBundlingOptions​选项,添加js和css bundle。

需要添加Volo.Abp.AspNetCore.Mvc.UI.Bundling​NuGet包,默认情况下,这个包已经安装在启动模板中。因此,大多数时候,您不需要手动安装它。如果没有使用启动模板,可以使用ABP CLI将其安装到项目中。在项目文件夹(包含.csproj​文件的文件夹)中执行以下命令:

abp add-package Volo.Abp.AspNetCore.Mvc.UI.Bundling

创建一个新的Bundle

Configure<AbpBundlingOptions>(options =>
{options.ScriptBundles.Add("MyGlobalBundle", bundle => {bundle.AddFiles("/libs/jquery/jquery.js","/libs/bootstrap/js/bootstrap.js","/libs/toastr/toastr.min.js","/scripts/my-global-scripts.js");});        
});

配置现有的Bundle

Configure<AbpBundlingOptions>(options =>
{options.StyleBundles.Configure(BlazorLeptonXLiteThemeBundles.Styles.Global,bundle =>{bundle.AddFiles("/blazor-global-styles.css");//You can remove the following line if you don't use Blazor CSS isolation for componentsbundle.AddFiles(new BundleFile("/Avalon.Blazor.styles.css", true));bundle.AddFiles(new BundleFile("/Avalon.Blazor.Client.styles.css", true));});
});

Bundle Contributor

可以创建一个BundleContributor​的派生类,更清晰的管理js和css文件。

public class BlazorLeptonXLiteThemeScriptContributor : BundleContributor
{public override void ConfigureBundle(BundleConfigurationContext context){context.Files.AddIfNotContains("/_content/Avalon.Abp.AspNetCore.Components.Web.LeptonXLiteTheme/side-menu/libs/bootstrap/js/bootstrap.bundle.js");context.Files.AddIfNotContains("/_content/Avalon.Abp.AspNetCore.Components.Web.LeptonXLiteTheme/side-menu/libs/jquery/jquery.min.js");context.Files.AddIfNotContains("/_content/Avalon.Abp.AspNetCore.Components.Web.LeptonXLiteTheme/side-menu/libs/bootstrap-datepicker/js/bootstrap-datepicker.min.js");}
}
public class BlazorLeptonXLiteThemeStyleContributor : BundleContributor
{public override void ConfigureBundle(BundleConfigurationContext context){context.Files.AddIfNotContains("/_content/Avalon.Abp.AspNetCore.Components.Web.LeptonXLiteTheme/side-menu/libs/chart.js/Chart.min.css");context.Files.AddIfNotContains("/_content/Avalon.Abp.AspNetCore.Components.Web.LeptonXLiteTheme/side-menu/libs/bootstrap-datepicker/css/bootstrap-datepicker.min.css");context.Files.AddIfNotContains("/_content/Avalon.Abp.AspNetCore.Components.Web.LeptonXLiteTheme/side-menu/libs/bootstrap-icons/font/bootstrap-icons.css");var rtlPostfix = CultureHelper.IsRtl ? ".rtl" : string.Empty;context.Files.AddIfNotContains($"/_content/Avalon.Abp.AspNetCore.Components.Web.LeptonXLiteTheme/side-menu/css/abp-bundle{rtlPostfix}.css");context.Files.AddIfNotContains($"/_content/Avalon.Abp.AspNetCore.Components.Web.LeptonXLiteTheme/side-menu/css/blazor-bundle{rtlPostfix}.css");context.Files.AddIfNotContains($"/_content/Avalon.Abp.AspNetCore.Components.Web.LeptonXLiteTheme/side-menu/css/bootstrap-dim{rtlPostfix}.css");context.Files.AddIfNotContains($"/_content/Avalon.Abp.AspNetCore.Components.Web.LeptonXLiteTheme/side-menu/css/layout-bundle{rtlPostfix}.css");context.Files.AddIfNotContains($"/_content/Avalon.Abp.AspNetCore.Components.Web.LeptonXLiteTheme/side-menu/css/font-bundle{rtlPostfix}.css");}
}

在模块类中ConfigureServices​方法中如下配置AbpBundlingOptions​选项:

public override void ConfigureServices(ServiceConfigurationContext context)
{Configure<AbpBundlingOptions>(options =>{options.StyleBundles.Add(BlazorLeptonXLiteThemeBundles.Styles.Global, bundle =>{bundle.AddContributors(typeof(BlazorLeptonXLiteThemeStyleContributor));});options.ScriptBundles.Add(BlazorLeptonXLiteThemeBundles.Scripts.Global, bundle =>{bundle.AddContributors(typeof(BlazorLeptonXLiteThemeScriptContributor));});});
}

Contributor依赖

一个bundle contributor可以对其他contributor有一个或多个依赖关系

[DependsOn(typeof(MyDependedBundleContributor))] //Define the dependency
public class MyExtensionStyleBundleContributor : BundleContributor
{//...
}

当添加一个bundle contributor时,它的依赖项会自动地递归添加。依赖根据依赖顺序添加并去重。

标准Package的Contributors

所有标准NPM包都有内置的contributor。例如,如果您的contributor依赖于bootstrap,您可以直接声明它,而不是自己添加bootstrap.css。

[DependsOn(typeof(BootstrapStyleContributor))] //Define the bootstrap style dependency
public class MyExtensionStyleBundleContributor : BundleContributor
{//...
}

使用标准包的内置contributors的优点:

  • 防止您键入无效的资源路径。
  • 防止在资源路径更改时更改您的contributor(依赖的contributor将处理它)。
  • 防止多个模块添加重复的文件。
  • 递归地管理依赖项(必要时添加依赖项的依赖项)。

需要按照Volo.Abp.AspNetCore.Mvc.UI.Packages​NuGet包。默认情况下,这个包已经安装在启动模板中。因此,大多数时候,您不需要手动安装它。如果没有使用启动模板,可以使用ABP CLI将其安装到项目中。在项目文件夹(包含.csproj​文件的文件夹)中执行以下命令:

abp add-package Volo.Abp.AspNetCore.Mvc.UI.Packages

访问IServiceProvider

虽然很少需要,但BundleConfigurationContext​有一个ServiceProvider​属性,你可以在ConfigureBundle​方法中解析服务依赖。

Bundle继承

在某些特定情况下,可能需要创建从其他bundle继承的新bundle。从一个bundle继承(递归地)将继承该bundle的所有文件和contributors。然后,派生的bundle可以添加或修改文件和contributors,而无需修改原始bundle。例子:

services.Configure<AbpBundlingOptions>(options =>
{options.StyleBundles.Add("MyTheme.MyGlobalBundle", bundle => {bundle.AddBaseBundles("MyGlobalBundle") //Can add multiple.AddFiles("/styles/mytheme-global-styles.css");});
});

Bundling模式

development​环境中,ABP将包文件分开添加到页面中。ABP会为其他环境(staging​、production​……)自动进行打包和最小化。大多数情况下,这是你想要的行为。但是,在某些情况下,您可能需要手动配置它。有四种模式:

  • Auto​: 根据环境自动确定模式。
  • None​: 没有捆绑或缩小。
  • Bundle​: 捆绑但不缩小。
  • BundleAndMinify​: 捆绑和缩小。

你可以在模块的ConfigureServices​中配置AbpBundlingOptions​。

示例:

Configure<AbpBundlingOptions>(options =>
{options.Mode = BundlingMode.Bundle;
});

Blazor WebAssembly中

Blazor WebAssembly中的 Bundling 和 Minification 是不是动态执行的,而是通过bundle命令执行。

创建Bundle Contributor

在Blazor WebAssembly项目中,创建一个实现IBundleContributor​接口的类。

IBundleContributor​接口包含两个方法,都以BundleContext​作为参数:

  • AddScripts(...)
  • AddStyles(...)
public class MyProjectBundleContributor : IBundleContributor
{public void AddScripts(BundleContext context){context.Add("site.js");}public void AddStyles(BundleContext context){context.Add("main.css");context.Add("custom-styles.css");}
}

默认情况下,启动模板中有一个实现IBundleContributor​接口的<ProjectName>BundleContributor​类。所以,大多数时候,您不需要手动添加它。

配置

在Blazor WebAssembly项目的wwwroot/appsettings.json​文件的AbpCli.Bundle​节点中包含了Bundling配置。

示例如下:

{"AbpCli": {"Bundle": {"Mode": "BundleAndMinify", /* Options: None, Bundle, BundleAndMinify */"Name": "global","IsBlazorWebApp": true,"InteractiveAuto": true,"Parameters": {}}}
}
  • Mode​:捆绑和缩小模式。可用的值有:

    • BundleAndMinify​:将所有文件捆绑到一个文件中,并缩小内容。
    • Bundle​:将所有文件捆绑成一个文件,但不要缩小。
    • None​:单独添加文件,不要捆绑。
  • Name​:包文件名。默认值为global​。

  • Parameters​:您可以在此部分中定义其他键/值对参数。abp bundle​命令自动将这些参数发送给bundle贡献者,您可以在bundle贡献者中检查这些参数,并根据这些值采取一些操作。例如想要从bundle中排除某些资源:

    public class MyProjectNameBundleContributor : IBundleContributor
    {public void AddScripts(BundleContext context){}public void AddStyles(BundleContext context){var excludeThemeFromBundle = bool.Parse(context.Parameters.GetValueOrDefault("ExcludeThemeFromBundle"));context.Add("mytheme.css", excludeFromBundle: excludeThemeFromBundle);context.Add("main.css");}
    }
    

bundle命令

在Blazor WebAssembly项目中执行bundle命令:

abp bundle

bundle命令将检测IBundleContributor​接口的实现类中包含的js和css,并读取appsettings.json​文件中的配置,根据配置打包资源,并更新index.html​文件。

例如,根据以上配置,将在wwwroot​生成global.css​和global.js​ bundle包,在App.razor文件文件的<AbpStyles>​标签和<AbpScripts>​标签的WebAssemblyScriptFiles​属性中引用了这两个bundle包。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/865276.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SwanLab最全使用教程:看这篇就够了

SwanLab是一个用于可视化和监控深度学习模型的工具。本文介绍了SwanLab的安装、启动和使用方法,并提供了参考链接。前言 机器学习通常涉及在训练期间可视化和度量模型的性能。 有许多工具可用于此任务。 在本文中,我们将重点介绍 SwanLab 开源工具,它可以服务于各种深度学习…

维修ABB IRB6700机器人的平衡缸3HAC043477出现异响

当ABB IRB6700机器人的平衡缸3HAC043477出现异响时,可能需要进行内部零件的检查和更换。以下是一些建议的步骤:1、检查IRB6700机械臂平衡缸的密封性:确保平衡缸的密封性良好,没有气体泄漏。如果发现有气体泄漏,可能需要更换密封件。2、检查活塞和缸体的磨损情况:如果活塞…

探索编程知识的宝库:www.readview.site 深度揭秘

在当今这个数字化浪潮汹涌澎湃的时代,编程技能已经如同基石一般,支撑着各行各业的创新与变革。无论是开发炫酷的手机应用、构建智能的物联网系统,还是投身于热门的大数据分析领域,扎实的编程功底都是迈向成功的关键一步。而在众多的学习资源中,www.readview.site 脱颖而出…

探索编程知识的宝库:[www.readview.site](http://www.readview.site) 深度揭秘

在当今这个数字化浪潮汹涌澎湃的时代,编程技能已经如同基石一般,支撑着各行各业的创新与变革。无论是开发炫酷的手机应用、构建智能的物联网系统,还是投身于热门的大数据分析领域,扎实的编程功底都是迈向成功的关键一步。而在众多的学习资源中,www.readview.site 脱颖而出…

Mysql连接报错排查解决记录

Mysql连接报错排查解决记录 背景:系统:uos server-1060e​ 运行环境kvm虚拟机​ mysql版本:5.7.44, for Linux (x86_64)问题现象: 宿主机重启后,kvm虚拟机内的mysql服务无法远程连接了。通过不同的客户端工具连接,报错现象分别如下: dbeaver-ce 工具连接报错: Can no…

CDS标准视图:维修工单工艺数据 I_MAINTORDEROPERATIONDATA

视图名称:维修工单工艺数据 I_MAINTORDEROPERATIONDATA 视图类型:基础 视图代码:点击查看代码 @EndUserText.label: Maintenance Order Operation Data @VDM.viewType: #COMPOSITE @AccessControl.authorizationCheck: #CHECK @AbapCatalog.sqlViewName: IPMORDOPERDATA @Cl…

关于const的使用

1、修饰整型变量const int a 就是声明了一种常量表示该变量的内容不可改变 2、对于修饰指针的const就有说法了 const int *a 和int* const a这是两种不同的用法 第一种: const int *a表示定义了一个指向const变量的指针,但是指针本身不是const类型,也就是说指针本身可以修改…

UOS系统mysql服务安装

UOS系统mysql服务安装 背景 1、安装环境:kvm虚拟机2、运行环境:uos server-1060e3、架构:x864、安装mysql版本:mysql-5.71、安装准备 # Mysql官网 https://downloads.mysql.com/archives/community/ # 下载安装包 wget -i -c http://dev.mysql.com/get/mysql57-community-…

使用Docker搭建npm私有仓库

由于文章格式和图片解析问题,为了更好的阅读体验,读者可前往 阅读原文在公司团队内一般都会拥有私有的工具包或者其他依赖,这些东西又是比较敏感的信息,因此如npm私库的搭建在公司内部必不可少。 私库搭建方式有很多,本篇通过docker+nexus3的进行搭建。 本人使用ARM架构Ce…

认识Token和Cookie

认识Token和Cookie 1、token和cookie有什么区别? ​ 1.1 存储位置及方式:Cookie是浏览器用来存储本地信息的文件,有一定的存储限制,而Token是由服务器按一定算法生成的密令,可以由前端指定存放到localStorage、sessionStorage或cookie中。 ​ 1.2 功能特性:每次浏览器…

开发微信小程序游戏,有没有类似Debug真机图形的方法

1)开发微信小程序游戏,有没有类似Debug真机图形的方法2)Unity中如何实现动态实时的车削效果3)动态创建的Texture,有什么办法可以让他保持ASTC么4)Unity转微信小游戏的日志问题这是第416篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术…