使用gulp自动化打包合并前端静态资源(CSSJS文件压缩添加版本号)
Posted Aoobruce
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用gulp自动化打包合并前端静态资源(CSSJS文件压缩添加版本号)相关的知识,希望对你有一定的参考价值。
现在正在做的项目更新迭代比较频繁,会经常对前端代码打包部署,手动整合代码文件很麻烦并且浪费时间,所以决定使用gulp来代替手工完成这项工作。
前端静态资源在发版更新时会面临客户端浏览器缓存的问题(可参考这篇文章),解决这个问题可以采用两类方法:覆盖方法(引用资源时加版本号,不修改资源文件名)、非覆盖方法(修改资源文件名),本篇文章主要采用的是第一种加版本号的方式,主要用gulp给静态资源自动加版本号和压缩CSS、JS。
原理:通过对JS,CSS文件内容进行Hash运算,生成一个文件的唯一Hash字符串,若对文件内容进行了修改则Hash号会发生变化。在html中引用文件时将版本号加在后面。
原始HTML:
1 <link href="css/global.css" rel="stylesheet" type="text/css" /> 2 <script src="js/fun.js"></script>
使用后HTML:
1 <link href="css/global.css?v=b40a6f2a9f" rel="stylesheet" type="text/css" /> 2 <script src="js/fun.js?v=3a08b5fa87"></script>
一、环境配置(安装gulp)
首先安装node、npm(此处省略)
安装gulp以及用到的插件,并在项目目录下创建文件gulpfile.js。
$ npm install --global gulp --安装全局gulp $ npm install --save-dev gulp $ npm install --save-dev gulp-rev $ npm install --save-dev gulp-rev-collector $ npm install --save-dev run-sequence $ npm install --save-dev gulp-clean $ npm install --save-dev gulp-minify-css $ npm install --save-dev gulp-uglify
在项目目录下创建文件gulpfile.js
项目目录结构:
node_modules中是安装的gulp和各种插件
二、编写gulpfile.js
1 //引入gulp和gulp插件 2 var gulp = require(\'gulp\'), 3 runSequence = require(\'run-sequence\'), 4 rev = require(\'gulp-rev\'), 5 clean = require(\'gulp-clean\'), 6 minifycss=require(\'gulp-minify-css\'), 7 uglify=require(\'gulp-uglify\'), 8 revCollector = require(\'gulp-rev-collector\'); 9 10 //定义css、js源文件路径 11 var cssSrc = \'./**/*.css\', //选择目录下所有css 12 jsSrc = \'./**/*.js\', //选择目录下所有css 13 srcExclude = \'!./node_modules/**/*\', //排除node_modules中的文件 14 cssFile = \'css/**/*\', //css文件夹 15 imageFile = \'image/**/*\', //图片文件夹 16 jsFile = \'js/**/*\', //js文件夹 17 jsCompressPath = \'Publish/js/*.js\', //压缩Publish中的js 18 cssCompressPath = \'Publish/css/*.css\'; //压缩Publish中的css 19 20 21 //CSS生成文件hash编码并生成 rev-manifest.json文件名对照映射 22 gulp.task(\'revCss\', function(){ 23 return gulp.src([cssSrc, srcExclude]) 24 .pipe(rev()) 25 .pipe(rev.manifest()) 26 .pipe(gulp.dest(\'rev/css\')); 27 }); 28 29 //js生成文件hash编码并生成 rev-manifest.json文件名对照映射 30 gulp.task(\'revJs\', function(){ 31 return gulp.src([jsSrc, srcExclude]) 32 .pipe(rev()) 33 .pipe(rev.manifest()) 34 .pipe(gulp.dest(\'rev/js\')); 35 }); 36 37 38 //Html替换css、js文件版本 39 gulp.task(\'revHtml\', function () { 40 return gulp.src([\'rev/**/*.json\', \'*.html\']) 41 .pipe(revCollector()) 42 .pipe(gulp.dest(\'Publish\')); 43 }); 44 45 //拷贝除HTML外其他的文件 46 gulp.task(\'copy\', function(){ 47 return gulp.src([cssFile, jsFile, imageFile],{ base: \'.\'}) 48 .pipe(gulp.dest(\'Publish\')); 49 }); 50 51 //压缩JS 52 gulp.task(\'jscompress\', function(){ 53 return gulp.src(jsCompressPath) 54 .pipe(uglify()) 55 .pipe(gulp.dest("Publish/js")); 56 }); 57 58 //压缩CSS 59 gulp.task(\'csscompress\', function(){ 60 return gulp.src(cssCompressPath) 61 .pipe(minifycss()) 62 .pipe(gulp.dest("Publish/css")); 63 }); 64 65 //开发构建 66 gulp.task(\'dev\', function (done) { 67 condition = false; 68 runSequence( 69 [\'clean\'], 70 [\'revCss\'], 71 [\'revJs\'], 72 [\'revHtml\'], 73 [\'copy\'], 74 [\'jscompress\'], 75 [\'csscompress\'], 76 done); 77 }); 78 79 gulp.task(\'clean\', function(){ 80 gulp.src(\'rev\',{read:false}).pipe(clean()); 81 return gulp.src(\'Publish\',{read:false}).pipe(clean()); 82 }); 83 84 85 gulp.task(\'default\', [\'dev\']);
三、更改插件代码
在项目目录下直接执行gulp命令
$ gulp
会得到如下效果:
1 <link href="css/global-b40a6f2a9f.css" rel="stylesheet" type="text/css" /> 2 <script src="js/fun-3a08b5fa87.js"></script>
需要更改gulp-rev、rev-path、gulpl-rev-collector插件的代码:
1.node_modules/gulp-rev/index.js
第135行:manifest[originalFile] = revisionedFile;
更改为:manifest[originalFile] = originalFile + \'?v=\' + file.revHash;
2.node_modules/rev-path/index.js
第9行:return modifyFilename(pth, (filename, ext) => `${filename}-${hash}${ext}`);
更改为:return modifyFilename(pth, (filename, ext) => `${filename}${ext}`);
3.node_modules/gulp-rev-collector/index.js
第40行:var cleanReplacement = path.basename(json[key]).replace(new RegExp( opts.revSuffix ), \'\' );
更改为:var cleanReplacement = path.basename(json[key]).split(\'?\')[0];
这里需要注意插件的版本不一样,需要改动的地方会有不同;
本文这里所有插件的版本为:
gulp@3.9.1 gulp-rev@8.1.1 gulp-rev-collector@1.2.4 rev-path@2.0.0 run-sequence@2.2.1 gulp-clean@0.4.0 gulp-minify-css@1.2.4 gulp-uglify@3.0.0
改完之后的效果
1 <link href="css/global.css?v=b40a6f2a9f" rel="stylesheet" type="text/css" /> 2 <script src="js/fun.js?v=3a08b5fa87"></script>
四、小结
gulp的任务的执行是异步的,想要保证任务执行的顺序,需要使用run-sequence插件
1 gulp.task(\'dev\', function (done) { 2 condition = false; 3 runSequence( 4 [\'clean\'], 5 [\'revCss\'], 6 [\'revJs\'], 7 [\'revHtml\'], 8 [\'copy\'], 9 [\'jscompress\'], 10 [\'csscompress\'], 11 done); 12 });
这里顺序执行任务:
先清除旧的rev和Pulish文件夹及其目录下所有文件(clean),之后生成CSS文件名对照映射的JSON文件(revCSS),再之后生成JS文件名对照映射的JSON文件(revJS),之后替换掉HTML中的链接,加上版本号(revHTML),将除了HTML之外其他的静态资源拷贝到Publish中(copy),然后压缩Publish/js中的JS文件,并将压缩后的文件替换掉原来的未压缩文件(jscompress),最后压缩Publish/css中的CSS文件,并替换掉未压缩文件(csscompress)。
PS:
1.在写路径时,"!"是排除的标识,可以排除一些文件,如:
gulp.src([\'./**/*.css\', \'!./node_modules/**/*\'])
这里选中的文件就是除了node_modules中的其他文件夹下的CSS文件
2.拷贝时若要保持路径,需要加一个base选项,即:
gulp.src(\'Publish/css/*.css\',{ base: \'.\'})
之后也可以分别对测试环境和生产环境编写任务,使用命令分开打包。
以上是关于使用gulp自动化打包合并前端静态资源(CSSJS文件压缩添加版本号)的主要内容,如果未能解决你的问题,请参考以下文章