打包工具选型

在 ASP.NET MVC 时代,我们常使用 BundleCollection 设置需要打包压缩的 js 和 css 文件,运行时框架会自动处理打包压缩过程并将最终结果传入响应。

ASP.NET Core 开始,不再提供内置的打包压缩组件,官方推荐 WebOptimizer 替代使用。

上述两者都是在运行时实时处理,应该至少在系统初始化时会占用一定的资源。

时间来到 .NET 大一统时代,截止目前(.NET7),我们仍然只能寻求外部组件的帮助。有一个编译期生成预期文件的组件 BuildBundlerMinifier,nuget 安装后进行简单的 JSON 配置即可使用,但遗憾的是,它不支持压缩包含 ES6 语法的 js,会报未将对象引用设置到对象的实例错误。

于是我们开始考虑独立于 .NET 平台的,较为成熟的方案,比如 gruntgulp

  • grunt: 使用 JSON 描述构建步骤
  • gulp:基于流传递(管道机制)

这两者都拥有丰富的插件,以应对各种需求。下面以更年轻更简单的 gulp 为例,说明如何使之与 Visual Studio 配合使用。

示例

假设有如下 .NET 项目,其中按约定静态文件存放在 wwwroot 目录下

安装 gulp

# 全局安装 gulp 或 gulp-cli,提供可在命令行执行的 gulp 指令
npm install -g gulp-cli

需要注意的是,我们还需要在待处理的目录下安装 gulp,否则后续运行命令时会提示 Local gulp not found. 错误。其实这是Gulp故意设计的,原因是为了版本和依赖的控制,也就是当别人 fork 你的代码,或者你过段时间拷贝到别的电脑上再 gulp 的时候,能控制该项目中 gulp 的版本和其他插件的版本始终保持不变。(这里的 gulp 其实也可看作插件,只是它是官方提供的。博主不怀疑 gulp 团队前向兼容的能力,推测是考虑第三方插件前向兼容的能力参差不齐的缘故。)

# 进入待处理的目录,此是 .net 项目下的一个子目录
cd wwwroot/
# 将此子目录初始化为 npm 项目
npm init -y
# 安装 gulp 插件,提供各种 gulp.xxx()
npm install gulp -D

此时在该目录下查看 gulp 版本

gulp --version
# 输出:
CLI version: 2.3.0 # 全局 cli 版本
Local version: 4.0.2 # 当前项目下 gulp 插件版本

安装需要的第三方插件

# 以下各插件功能请查阅相关资料
npm i -D gulp-cssmin gulp-autoprefixer gulp-uglify
# es6 语法转 es5,窃以为目前浏览器对 es6 的支持程度,大可不必
npm i -D gulp-babel @babel/core @babel/preset-env
# 提供合并若干文件为单一文件的功能
npm i -D gulp-concat

编写 gulpfile.js

在项目根目录下(wwwroot/)新建 gulpfile.js,编写任务脚本

// 加载 项目gulp 依赖包
const gulp = require('gulp'); // 加载 css相关依赖包
const autoprefixer = require('gulp-autoprefixer');
const cssmin = require('gulp-cssmin'); // 加载 js相关依赖包
const uglify = require('gulp-uglify');
const babel = require('gulp-babel'); // 加载文件合并处理包
const concat = require('gulp-concat'); // 打包 css
const cssHandler = function () {
return gulp.src('./css/main.css')
.pipe(autoprefixer())
.pipe(cssmin())
.pipe(concat('main.min.css'))
.pipe(gulp.dest('./css'))
} // 打包 js
const jsHandler = function () {
return gulp.src(['./js/instruction/*.js', './js/repos/*.js', './js/app/*.js'])
.pipe(babel({ presets: ['@babel/env'] }))
.pipe(uglify())
.pipe(concat('main.min.js'))
.pipe(gulp.dest('./js'))
} // 3-3,定义默认执行程序
module.exports.default = gulp.parallel(cssHandler, jsHandler)

注意,gulp.dest() 参数表示的是目标目录而非目标文件名(输出文件名默认同源文件名),如果要自定义输出文件名可使用 gulp-rename 插件;或如上使用 gulp-concat,它的目的是合并若干文件为单一文件,自然能指定生成的文件名咯。

完成上述步骤后,我们就可以在命令行执行 gulp 检查输出结果。

编译 .net 项目时自动打包

在 .net 项目根目录下(注意非 wwwroot/)新建一个批处理文件 package-statics.bat:

cd wwwroot
gulp

然后编辑项目文件(.csproj),在 节点下加入如下配置:

<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="call package-statics.bat" />
</Target>

意思很简单:在编译前先执行批处理文件,也就是先执行之前我们设置好的 gulp 流程。

如果你的项目采用了 CI/CD 自动构建,可能服务器上并没有安装 gulp,那么可以在本地先执行打包,将生成后的文件提交,然后在服务器上编译时跳过打包步骤,直接使用提交的文件。实现这个场景也很简单,只要在上述 节点内配置执行条件即可:<Target ... Condition="'$(Configuration)'=='DEBUG'">。参看演练:使用 MSBuild

ps:在页面中,我们希望开发时依然引用的是原文件,上线后才引用打包后文件,那么可以使用 <environment> 标记,通过判断环境变量达到这一目的:

<environment include="Development">
<link ... href="~/css/main.css" />
</environment>
<environment include="Production">
<link ... href="~/css/main.min.css" />
</environment>

参考资料

gulp打包详解

.net 项目静态文件自动压缩打包的更多相关文章

  1. gulp自动化打包及静态文件自动添加版本号

    前端自动化打包发布已是一种常态,尤其在移动端,测试过程中静态资源的缓存是件很头疼的事情,有时候明明处理的bug测试还是存在,其实就是缓存惹的祸,手机不比pc浏览器,清理缓存还是有点麻烦的.所以自动化实 ...

  2. Grunt针对静态文件的压缩,版本控制打包方案

    在讲之前先谈谈大致步骤:安装nodejs -> 全局安装grunt -> 项目创建package.json --> 项目安装grunt以及grunt插件 -> 配置Gruntf ...

  3. IDEA springboot 项目静态文件修改不更新的问题

    springboot 项目的页面和静态文件,在项目启动后,修改无效.按照下面的配置可以解决问题. 1.file-setting 勾选项目自动构建 2.使用快捷键 ctrl+ shift+ alt + ...

  4. Django项目静态文件加载失败问题

    在我们平时的开发过程中,为了方便调试程序,我们都是打开开发者模式,即Debug=True,当我们正式上线的时候肯定就需要把开发者模式关掉,用uwsgi部署上去以后,突然发现我们平时辛苦做的项目的静态文 ...

  5. winRAR将单独文件分别压缩打包

    2014-4-7 首先选中多个需要打包的文件,右键-->添加到压缩文件-->选中"文件"选项卡-->勾选下面的"把每个文件压缩到单独文件中. 如下图所示

  6. [转]C#如何把文件夹压缩打包然后下载

    public partial class _Default2 : System.Web.UI.Page{ protected void Page_Load(object sender, EventAr ...

  7. idea使用Maven创建的JavaWeb项目新建文件时没有打包到target目录报错

    背景:在使用tomcat发布这个项目时,浏览网页,js没有效果. 问题:发现打包之后没有同步到target里 解决办法:点击最右侧的Maven栏->所建项目->Lifecycle-> ...

  8. java/resteasy批量下载存储在阿里云OSS上的文件,并打包压缩

    现在需要从oss上面批量下载文件并压缩打包,搜了很多相关博客,均是缺胳膊少腿,要么是和官网说法不一,要么就压缩包工具类不给出 官方API https://help.aliyun.com/documen ...

  9. Linux文件压缩/打包/解压

    在Linux日常维护中,经常需要备份同步一些比较重要的文件,而在传输过程中如果文件比较大往往会非常慢,而且还会非常占用空间,这时候就需要我们使用压缩工具对大文件进行压缩打包,下面我们来介绍一下常用的压 ...

  10. webpack4.16压缩打包

    webpack4.16压缩打包 本文所用插件版本如下: nodejs:v8.11.3; npm:5.6.0 webpack:4.16 webpack的更新速度很快,差不多几个月就会出一版,最新的4系列 ...

随机推荐

  1. RochyLinux 8.6安装Oracle19c Client

    一.环境准备 1.1 软件下载 下载地址:https://www.oracle.com/database/technologies/oracle19c-linux-downloads.html 其中c ...

  2. 使用vSphere Update Manager 升级 ESXi 主机

    使用vSphere Update Manager 升级 ESXi 主机 vSphere Update Manager  vSphere Update Manager 是用于升级.迁移.更新和修补群集主 ...

  3. pysimplegui之画布,图形,表格和树结构元素

    画布元素 在我看来,tkinter Canvas 小部件是 tkinter 小部件中功能最强大的.虽然我尽我所能将用户与任何与 tkinter 相关的东西完全隔离,但 Canvas 元素是一个例外.它 ...

  4. [Windows]BAT脚本自定义函数

    1 helloworld @echo off call :helloworld helloworld goto :EOF :helloworld setlocal echo %1 endlocal&a ...

  5. 微信Token验证代码的实现

    微信开放第三方API接口, 申请地址: https://mp.weixin.qq.com/advanced/advanced?action=interface&t=advanced/inter ...

  6. The first week match's mistake-2

    旋转排列 (https://www.luogu.com.cn/problem/B3688) 解读一下题目: 要求从给定的数组拿出最后一个数字后 看看变化后的数组的最后一个数字是否是要求的数字 想到用栈 ...

  7. 从原理聊JVM(三):详解现代垃圾回收器Shenandoah和ZGC

    作者:京东科技 康志兴 Shenandoah Shenandoah一词来自于印第安语,十九世纪四十年代有一首著名的航海歌曲在水手中广为流传,讲述一位年轻富商爱上印第安酋长Shenandoah的女儿的故 ...

  8. react中refs详解

    https://zh-hans.reactjs.org/docs/refs-and-the-dom.html 字符串形式ref 1 <input ref="myinput" ...

  9. [C++提高编程] 3.2 vector容器

    文章目录 3.2 vector容器 3.2.1 vector基本概念 3.2.2 vector构造函数 3.2.3 vector赋值操作 3.2.4 vector容量和大小 3.2.5 vector插 ...

  10. 安装dataX的问题,com.alibaba.datax.common.exception.DataXException: Code:[Common-00], Describe

    文章目录 报错 安装: 解决方法 总结 报错 com.alibaba.datax.common.exception.DataXException: Code:[Common-00], Describe ...