使用gulp加md5戳

请先了解gulp的基本用法:使用gulp部署web前端代码https://www.zybuluo.com/hzl201/note/1639542

目标

  1. cshtml文件引用js和css文件时若js或css文件有变化,则刷新浏览器后能自动加载最新的js或css文件,不需要清理浏览器缓存文件(目前能实现大部分js出现md5戳)。
  2. 开发人员不需要进行任何适配,保留当前的开发习惯和开发流程。
  3. cshtml文件加完md5戳以后能多次增加md5戳,不会出现运行多次后出现多个版本号的情况。
  4. cshtml文件转换后不能出现乱码。
  5. 出现新的cshtml文件后能自动加入转换列表(目前无法实现,只能手动添加)。

实施思路

分析源码
  • js和css文件有重名的情况,只能根据根目录的相对路径+文件名的方式实现索引的唯一性,使用gulp先生成一个映射表,映射表内容分别是:“相对路径+文件名”和处理后的“相对路径+文件名+md5戳”,再通过gulp查询映射表修改所有cshtml文件中的匹配内容。若cshtml文件引用js和css文件不是相对路径,则无法识别并转换。
  • 临矿pc端web将近2000个cshtml文件,其中有115个文件是GB2312格式的(又分为两种情况,若这些文件内容中没有中文字符,则不需要转换也能加md5戳,但只要内容存在中文字符,转换后必定乱码),需先转换成UTF-8格式,进行加md5处理后再转换成UTF-8 with BOM格式。其余的cshtml文件是UTF-8 with BOM格式的,可以直接加md5戳。
手动实现
  • 使用UltraCodingSwitch软件可进行手动把所有文件转换成UTF-8 with BOM格式,速度快,稳定性高。但无法集成到Jenkins的自动发布流程里。
  • https://i.loli.net/2020/01/04/jwliTrFdJZvQx9k.jpg
集成到Jenkins
  • 使用iconv可进行转换,下载地址:http://files.cnblogs.com/adgnat/iconv.7z,但转换前需要先分离cshtml文件,把GB2312格式的文件复制到iconv文件夹,再使用iconv转换成UTF-8格式,再复制到cshtmlmd5文件夹;其他的cshtml文件直接复制到cshtmlmd5文件夹。,若GB2312格式的cshtml文件直接复制到cshtmlmd5文件夹,则必然出现中文乱码。若不是GB2312格式的cshtml文件使用iconv进行处理,则文件内容会变成“锘”。
  • 需要把iconv.exe文件放在一个单独的文件夹,并添加好环境变量。否则Jenkins无法正确识别iconv命令。
  • https://i.loli.net/2020/01/04/IndMlpshHU4569b.jpg
  • gulp进行转换

实施步骤

手动获取cshmtl文件的转换列表
  • 检查是否有新的cshtml未转换。其中能转换的文件是gb2312格式的,需要加到gb2312处理的脚本里。全部文件是被删除的文件及路径。所有gb2312文件都被加到处理脚本(del和copy都加)以后,剩下的文件就是utf-8格式的,添加到utf-8的白名单里(del和copy都加)。
  • 只需要单独运行一次即可,在Jenkins里不需要集成这个方法。
@echo off
echo 检查是否有新的cshtml未转换
echo 清理临时文件夹
del /f /q /s D:\upload\lyweb-release\_PublishedWebsites\update\*.*
RD  /s /q  D:\upload\lyweb-release\_PublishedWebsites\update\
mkdir D:\upload\lyweb-release\_PublishedWebsites\update\

del /f /q /s D:\upload\lyweb-release\_PublishedWebsites\iconv\*.*
RD  /s /q  D:\upload\lyweb-release\_PublishedWebsites\iconv\
mkdir D:\upload\lyweb-release\_PublishedWebsites\iconv\

del /f /q /s D:\upload\lyweb-release\_PublishedWebsites\cshtmlmd5\*.*
RD  /s /q  D:\upload\lyweb-release\_PublishedWebsites\cshtmlmd5\
mkdir D:\upload\lyweb-release\_PublishedWebsites\cshtmlmd5\

echo 复制所有文件到iconv文件夹
echo d | xcopy D:\upload\lyweb-release\_PublishedWebsites\LRSMES.WebUI  D:\upload\lyweb-release\_PublishedWebsites\iconv /s /r /y

echo 删除iconv文件夹中已经被处理过的cshtml文件
call D:\upload\iconv\del-unc.bat
call D:\upload\iconv\del-gb2312.bat

echo 删除iconv文件夹中文件名有空格的的cshtml文件
del /f /q /s D:\upload\lyweb-release\_PublishedWebsites\iconv\Areas\MonitorWarning\Views\DM\"副本 Index.cshtml"

echo iconv检查
call D:\upload\iconv\iconv2.bat

echo iconv:cannot convert的cshtml文件是utf-8格式,请添加到utf-8的白名单copy-unc.bat和del-unc.bat里。先把所有的utf-8的文件都添加好。

echo 去除utf-8的文件后,下面的删除列表是gb2312文件,需添加到copy-gb2312.bat和del-gb2312.bat里。
del /f /q /s D:\upload\lyweb-release\_PublishedWebsites\iconv\*.cshtml
  • del-unc.bat内容如下:
@echo off
set path=D:\upload\lyweb-release\_PublishedWebsites\iconv


del /f /q %path%\Areas\Base\Views\_ViewStart.cshtml
del /f /q %path%\Areas\Base\Views\DataDictionary\Index.cshtml
del /f /q %path%\Areas\Base\Views\Demo\CheckPerson.cshtml
del /f /q %path%\Areas\Base\Views\DocCheckRecord\CheckEditPage.cshtml
del /f /q %path%\Areas\BDDM\Views\MineReport\JT_SC_ExpectReport.cshtml
  • del-gb2312.bat内容如下:
@echo off
set path=D:\upload\lyweb-release\_PublishedWebsites\iconv

del /f /q 	%path%\Areas\Base\Views\ExaminationType\ExaminationTypePage.cshtml
del /f /q 	%path%\Areas\Base\Views\ExaminationWebSiteConfig\Index.cshtml
del /f /q 	%path%\Areas\Base\Views\Ex_ExaminationItem\ExItemPage.cshtml
del /f /q 	%path%\Areas\Base\Views\MSG_MAIL_TEMP\MSG_MAIL_TEMPPage.cshtml
del /f /q 	%path%\Areas\Base\Views\MSG_SMS_TEMP\MSG_SMS_TEMPPage.cshtml
  • iconv2.bat的内容如下:
@echo off

d:
cd D:\upload\lyweb-release\_PublishedWebsites\iconv

for /r D:\upload\lyweb-release\_PublishedWebsites\iconv %%i in (*.cshtml) do (
echo 修改GB2312文件编码为UTF-8格式,名称为****.bkp
iconv -f GB2312 -t UTF-8 %%i > %%i.bkp
if exist %%i.bkp (
    echo 删除原GB2312格式文件
    del %%i
    echo 重命名UTF-8格式文件为原文件名称
    ren %%i.bkp %%~nxi
) else (
    echo pass
)
)

del /f /q /s D:\upload\lyweb-release\_PublishedWebsites\iconv\*.bkp

echo 执行完毕。此脚本将于10秒后自动关闭!
ping 127.0.0.1 -n 10 >nul
自动统一cshtml文件的格式
  • 需要集成到Jenkins里,打完full包和拷贝完semi包的文件后,运行这些脚本。
echo 把不需要转换的cshtml文件复制到临时目录cshtmlmd5
call D:\upload\iconv\copy-unc.bat

echo 把GB2312格式的cshtml文件复制到临时目录iconv
call D:\upload\iconv\copy-gb2312.bat

echo 把GB2312格式的cshtml文件的编码格式转换成utf-8,解决中文乱码问题
call D:\upload\iconv\iconv2.bat

echo 把GB2312转utf-8格式的cshtml文件从临时目录iconv复制到cshtmlmd5目录
echo d | xcopy D:\upload\lyweb-release\_PublishedWebsites\iconv  D:\upload\lyweb-release\_PublishedWebsites\cshtmlmd5 /s /r /y
  • copy-unc.bat的内容如下:
@echo off
echo 选用/S时对源目录下及其子目录下的所有文件进行COPY。除非指定/E参数,否则/S不会拷贝空目录,若不指定/S参数,则XCOPY只拷贝源目录本身的文件,而不涉及其下的子目录
set from=D:\upload\lyweb-release\_PublishedWebsites\LRSMES.WebUI
set to=D:\upload\lyweb-release\_PublishedWebsites\cshtmlmd5

del /f /q /s D:\upload\lyweb-release\_PublishedWebsites\cshtmlmd5\*.*
RD  /s /q  D:\upload\lyweb-release\_PublishedWebsites\cshtmlmd5\
mkdir D:\upload\lyweb-release\_PublishedWebsites\cshtmlmd5

echo f | xcopy 	%from%\Areas\Base\Views\_ViewStart.cshtml		%to%\Areas\Base\Views\_ViewStart.cshtml		 /r /y
echo f | xcopy 	%from%\Areas\Base\Views\DataDictionary\Index.cshtml		%to%\Areas\Base\Views\DataDictionary\Index.cshtml		 /r /y
echo f | xcopy 	%from%\Areas\Base\Views\Demo\CheckPerson.cshtml		%to%\Areas\Base\Views\Demo\CheckPerson.cshtml		 /r /y
echo f | xcopy 	%from%\Areas\Base\Views\DocCheckRecord\CheckEditPage.cshtml		%to%\Areas\Base\Views\DocCheckRecord\CheckEditPage.cshtml		 /r /y
echo f | xcopy 	%from%\Areas\Base\Views\DocCheckRecord\CheckPage.cshtml		%to%\Areas\Base\Views\DocCheckRecord\CheckPage.cshtml		 /r /y
  • copy-gb2312.bat的内容如下:
@echo off
echo 选用/S时对源目录下及其子目录下的所有文件进行COPY。除非指定/E参数,否则/S不会拷贝空目录,若不指定/S参数,则XCOPY只拷贝源目录本身的文件,而不涉及其下的子目录
set from=D:\upload\lyweb-release\_PublishedWebsites\LRSMES.WebUI
set to=D:\upload\lyweb-release\_PublishedWebsites\iconv

del /f /q /s D:\upload\lyweb-release\_PublishedWebsites\iconv\*.*
RD  /s /q  D:\upload\lyweb-release\_PublishedWebsites\iconv\
mkdir D:\upload\lyweb-release\_PublishedWebsites\iconv


echo f | xcopy 	%from%\Areas\Base\Views\ExaminationType\ExaminationTypePage.cshtml	 %to%\Areas\Base\Views\ExaminationType\ExaminationTypePage.cshtml	 /r /y
echo f | xcopy 	%from%\Areas\Base\Views\ExaminationWebSiteConfig\Index.cshtml	 %to%\Areas\Base\Views\ExaminationWebSiteConfig\Index.cshtml	 /r /y
echo f | xcopy 	%from%\Areas\Base\Views\Ex_ExaminationItem\ExItemPage.cshtml	 %to%\Areas\Base\Views\Ex_ExaminationItem\ExItemPage.cshtml	 /r /y
echo f | xcopy 	%from%\Areas\Base\Views\MSG_MAIL_TEMP\MSG_MAIL_TEMPPage.cshtml	 %to%\Areas\Base\Views\MSG_MAIL_TEMP\MSG_MAIL_TEMPPage.cshtml	 /r /y
echo f | xcopy 	%from%\Areas\Base\Views\MSG_SMS_TEMP\MSG_SMS_TEMPPage.cshtml	 %to%\Areas\Base\Views\MSG_SMS_TEMP\MSG_SMS_TEMPPage.cshtml	 /r /y
echo f | xcopy 	%from%\Areas\Base\Views\T_SYS_ROLE_CATEGORY\T_SYS_ROLE_CATEGORYPage.cshtml	 %to%\Areas\Base\Views\T_SYS_ROLE_CATEGORY\T_SYS_ROLE_CATEGORYPage.cshtml	 /r /y
获取js和css文件的映射表、对cshtml文件进行转换
  • 需要集成到Jenkins里,在统一cshtml文件格式后执行。由于gulp打包后无法执行后续的脚本,需要在Jenkins里再新建一个win的批处理才行。
echo gulp打包,获取所有js和css文件的md5戳,修改所有cshtml的引用信息,增加v,若有js或css文件被修改,则md5值会变化,相应的cshtml会更新js或css的文件版本信息,解决浏览器缓存未更新的问题,这样就不需要在客户端浏览器手动清理缓存了。

echo 复制gulp依赖包
call C:\"Program Files"\7-Zip\7z.exe x D:\upload\gulp.7z -oD:\upload\lyweb-release\_PublishedWebsites

echo 执行gulp打包命令
ping 127.0.0.1 -n 3 >nul
d:
cd D:\upload\lyweb-release\_PublishedWebsites
gulp
合并到semi包
  • 在Jenkins里新建一个windows batch command,在gulp转换后执行。添加到semi包打成压缩包的脚本之前。
echo 把经过gulp转换后带md5戳的cshtml文件复制到d盘的upload目录的update目录

echo d | xcopy D:\upload\lyweb-release\_PublishedWebsites\update D:\upload\update /s /r /y

验证

未对cshtml文件加md5戳之前打开pc端平台按f12查看js文件时是这样的,是没有md5戳的:
  • https://i.loli.net/2020/01/04/e24wCGT8AqYPOzM.jpg
未对cshtml文件加md5戳之前打开gb2312格式的cshtml文件是这样的:
  • https://i.loli.net/2020/01/04/sOCmg43j9iPFzSv.jpg
使用iconv转换后的gb2312格式的cshtml文件是这样的:
  • https://i.loli.net/2020/01/04/ajYqwpAMUftXk7v.jpg
错误示范:使用iconv转换utf-8格式的cshtml文件是这样的:
  • https://i.loli.net/2020/01/04/nfGHuW4thZTMgF5.jpg
使用gulp处理cshtml文件前是这样的:
  • https://i.loli.net/2020/01/04/YRSWTc9aZfiGNX1.jpg
使用gulp处理cshtml文件后加md5戳是这样的:
  • https://i.loli.net/2020/01/04/8fE4jXWVBduotUN.jpg
集成到semi包并进行更新后是这样的,js文件已经有md5戳了,以后只要代码更新后,执行Jenkins打包部署工程后,js文件若发生变化,md5戳也会变化,相应的刷新浏览器就能自动加载最新的js文件:
  • https://i.loli.net/2020/01/04/3saceowdNm4vjQA.jpg