glup统一替换资源版本号实践

1.背景介绍

公司项目前端框架依赖于.net的aspx框架,代码迭代时间长,大部分代码较为老旧,资源文件(如js,css,图片等)与前端文件(html,aspx)依赖关系复杂,改动一个资源文件,为了去除缓存,需要修改多个地方的依赖版本。

对于一次完整的发布,所改动的资源文件数量较多,所需要改动的依赖版本号更是数量庞大,不免有所遗漏,导致缓存的存在.寻求一种一键自动统一替换依赖版本号的方案刻不容缓。

2.gulp的接入

2.1 gulp介绍

当下最热门的前端构建工具当属gulp和webpack,所谓“工欲善其事,必先利其器”,一个好的构建工具能大大提升开发效率,此处我们采用gulp实现资源版本的统一管理。

gulp是一个自动化构建工具,它能够将将开发流程中让人痛苦或耗时的任务自动化,从而减少你所浪费的时间、创造更大价值。

好的构建工具往往是由一系列插件组合而成,此处简单介绍一下gulp的一些常用插件:
gulp-imagemin 压缩图片
gulp-sass 将scss文件转为css
gulp-postcss 与autoprefixer配合使用
gulp-open 默认浏览器打开指定页面
gulp-htmlmin 最小化html文件
gulp-minify-css 最小化css
gulp-uglify 混淆js文件
gulp-concat 合并js,css文件
gulp-replace 对指定文件内容进行替换,可以用正则
gulp-usemin 将html中外链的css和js文件
gulp-zip 将文件打包成zip
gulp-sequence 串行执行任务,相对于gulp.task中依赖的任务是并行执行的
gulp-rev-all 对js或css文件加MD5戳,缓存用
gulp-asset-rev 资源文件替换
gulp-clean 清楚文件/文件夹
gulp-sequence 序列化执行task
gulp-bom 文件编码格式添加bom

2.2 gulpfile的文件编写

此处我们使用以上4个插件(gulp-asset-rev gulp-clean gulp-sequence gulp-bom)来实现统一修改版本的方案
首先我们先创建package.json引入插件与gulp:
//引入插件

"devDependencies": {
    "gulp": "3.9.1",
    "gulp-asset-rev": "0.0.15",
    "gulp-clean": "0.3.2",
    "gulp-bom": "3.0.0",
    "gulp-sequence": "1.0.0",
  },

然后我们需要创建gulpfile.js编写自动化流程

const gulp = require('gulp');
const clean = require('gulp-clean');
const assetRev = require('gulp-asset-rev');
const bom = require('gulp-bom');
const gulpSequence = require('gulp-sequence').use(gulp);
gulp.task('API', function() {
    return gulp.src("./API/**/*").pipe(assetRev({verStr:'xx.xx.xx'})).pipe(bom('in')).pipe(gulp.dest('./dist/API'));
});
gulp.task('CMS', function() {
    return gulp.src("./CMS/**/*").pipe(assetRev({verStr:'xx.xx.xx'})).pipe(bom('in')).pipe(gulp.dest('./dist/CMS'));
});
// 清理api
gulp.task('cleanAPI', function() {
    return gulp.src('API', {read: false}) .pipe(clean())
});
// 清理cms
gulp.task('cleanCMS', function() {
    return gulp.src('CMS', {read: false}).pipe(clean())
});
gulp.task('updateAPI', function() {
    return gulp.src("./dist/API/**/*")
    .pipe(bom('out')).pipe(gulp.dest('./API'));
});
gulp.task('updateCMS', function() {
    return gulp.src("./dist/CMS/**/*")
        .pipe(bom('out')).pipe(gulp.dest('./CMS'));
});
//删除已使用完毕的生成的文件夹,
gulp.task('clean', function() {
    return gulp.src('dist', {
        read: false
    }).pipe(clean());
});

gulp.task('update-Api', gulpSequence('API', 'cleanAPI', 'updateAPI'))

gulp.task('update-CMS', gulpSequence('CMS', 'cleanCMS', 'updateCMS'))
//主要流程: 依次进行update-CMS,update-API,clean 3个task
gulp.task('default', gulpSequence('update-CMS','update-API','clean')); //gulp执行顺序

2.3 插件的修改

使用过程中发现插件的效果并不完全是我们想要的效果,所以需要对nodemodule中的插件进行代码修改,
gulp-asset-rev 改动地方如下:
( 1 ) 注释原有的版本替换,不符合我们的需求

//注释掉该段代码
//if (options.verStr) {
//   src += options.verStr;
//    return tag + '"' + src + '"';
//}

( 2 ) 因为原有文件已有版本号后缀,需要进行兼容,每次都重新添加

//新增该段代码
var assetIndex = assetPath.indexOf('?');
var srcIndex = src.indexOf('?');
    if( assetIndex > -1 ){
    assetPath = assetPath.substr(0,assetIndex);
}
if( srcIndex > -1 ){
    src = src.substr(0,srcIndex);
}

( 3 ) glup-asset-rev使用的是本地文件的md5作为版本号,该方案的好处是只改动有新改动文件的依赖版本号,缺点是文件路径不规范或者使用网络地址的资源无法获取md5,添加使用统一传入的版本号作为备选方案

//修改

//如果获取md5
 src = src += '?v=' + md5;
else{
//使用传入的版本号
if (options.verStr) {
    src = src += '?v=' + options.verStr;
}

gulp-bom 改动地方如下:
( 1 ) aspx文件要求编码格式为utf-8 with bom格式,所以需要引入gulp-bom,但是图片等文件在utf-8 with bom的编码格式下将被损坏,所以需要过滤
//新增

var fileExtension = file.path.substring(file.path.lastIndexOf('.') + 1);
//产出输出  需要过滤.net框架文件
if (fileExtension != 'html' && fileExtension != 'aspx'
    &&  fileExtension != 'svc' &&  fileExtension != 'config'
    &&  fileExtension != 'cs' &&  fileExtension != 'pubxml') {      
    callback(null, file);
    return;
}

2.4多人共同使用

以上本地修改了nodemodules中的三方package的代码,修改的内容在重新安装依赖就没有了,那要如何防止这种情况以及如何多人一起使用修改后的三方库代码呢.
一般常用办法有两个:

  • 下载别人代码到本地,放在src目录,修改后手动引入。
  • fork 别人的代码到自己仓库,修改后,从自己仓库安装这个插件。

此处我们使用patch-package来进行多人协作
首先引入

"dependencies": {
    "patch-package": "6.2.2"
  }

安装完后使用

npx patch-package gulp-asset-rev
npx patch-package gulp-bom

运行后会在项目根目录下的patches目录中创建2个补丁文件,补丁文件会在每次npm install的时候进行应用,达到多人共同使用的目的。

3.使用

3.1如何使用

相关自动化文件,补丁已经上传,等v4.5.3版本发布后,使用front_master新拉的分支都会有相关配置,使用起来较为简单:
第一步: npm install 安装依赖
第二步: gulp 执行gulpfile.js 进行自动化
如有报错,请查看node版本,npm版本
(ps:此处使用 node版本号 11.15.0 npm版本号 6.7.0)

3.2使用过程中的建议

在后续开发中,资源文件(js,css,图片)尽量使用相对路径,如
<script type="text/javascript" src="../static/js/base.js"></script>
而不是根目录表示法
<script type="text/javascript" src="/static/js/base.js"></script>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容