gulp的安装与配置,对css与js自动添加版本号
最近项目需要,需要自动给js和css添加版本号,在网上查了很多资料,FIS3已哈希命名的方式,这样产生了很多无用的文件,并且js文件中已require.js方式加载的js文件无法进行哈希替换。
gulp是基于Nodejs的自动任务运行器,基本流程就是先安装nodejs,通过nodejs的npm全局安装和项目安装gulp,其次在项目里安装所需要的gulp插件,然后新建gulp的配置文件gulpfile.js并写好配置信息(定义gulp任务),最后通过命令提示符运行gulp(webstorm神器更简单)。
gulp插件在安装过程中碰到一些问题,综合各资料安装步骤如下:
安装nodejs就不说了,一步步默认,打开cmd控制台,直接查看node版本,检测是否安装成功

全局安装gulp,出现warn不要紧,等他慢慢转,表示正在联网下载...
npm install -g gulp
全局安装完成后,通过cmd进入项目目录创建package.json文件,这是基于nodejs项目必不可少的配置文件,它是存放在项目根目录的普通json文件:

直接在后面加上 -y 会自动生成,省去一步步的选择填空操作。
注:可不使用npm init方式,可选择手动创建package.json配置文件
查看项目文件根目录,是否新建package.json,且内容是否和你终端中输入的一致。
package.json内容如下
{ "name": "test", "version": "1.0.0", "description": "我是描述", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
接着在cmd项目目录下开始本地安装gulp各种插件,在这里找你需要的插件。有四个是用得最多的,必备的
1、语法检查 (gulp-jshint)
2、合并文件 (gulp-concat)
3、压缩代码 (gulp-uglify)
4、文件重命名 (gulp-rename)
本地安装gulp
注:全局安装gulp是为了执行gulp任务,本地安装gulp则是为了调用gulp插件的功能
进入你的项目文件路径中后,执行
npm install gulp --save-dev

注:项目文件中多了 node_modules 文件夹,里面是你本地安装的插件
此处,我们是要给项目自动添加版本号,所以安装下面的插件
npm install --save-dev gulp-rev npm install --save-dev gulp-rev-collectornpminstall--save-dev gulp-asset-revnpm install --save-dev run-sequence
--save-dev 是可以省掉你手动修改package.json文件的步骤,正常情况下得连同版本号手动将他们添加到模块配置文件package.json中的依赖里
安装配置完成,要开始写代码啦。
在项目目录下新建Gulpfile.js文件,gulp有五种方法:task,run,watch,src,和dest.
//引入gulp和gulp插件 var gulp = require('gulp'), assetRev = require('gulp-asset-rev'), runSequence = require('run-sequence'), rev = require('gulp-rev'), revCollector = require('gulp-rev-collector'); //定义css、js源文件路径 var cssSrc = '*.css', jsSrc = '*.js'; //为css中引入的图片/字体等添加hash编码 gulp.task('assetRev', function(){ return gulp.src(cssSrc) //该任务针对的文件 .pipe(assetRev()) //该任务调用的模块 .pipe(gulp.dest('src/css')); //编译后的路径 }); //CSS生成文件hash编码并生成 rev-manifest.json文件名对照映射 gulp.task('revCss', function(){ return gulp.src(cssSrc) .pipe(rev()) .pipe(rev.manifest()) .pipe(gulp.dest('rev/css')); }); //js生成文件hash编码并生成 rev-manifest.json文件名对照映射 gulp.task('revJs', function(){ return gulp.src(jsSrc) .pipe(rev()) .pipe(rev.manifest()) .pipe(gulp.dest('rev/js')); }); //Html替换css、js文件版本 gulp.task('revHtml', function () { return gulp.src(['rev/**/*.json', '*.html', '*.js']) .pipe(revCollector()) .pipe(gulp.dest('View')); }); //开发构建 gulp.task('default', function (done) { condition = false; runSequence( //需要说明的是,用gulp.run也可以实现以上所有任务的执行,只是gulp.run是最大限度的并行执行这些任务,而在添加版本号时需要串行执行(顺序执行)这些任务,故使用了runSequence. ['assetRev'], ['revCss'], ['revJs'], ['revHtml'], done); });
执行gulp命令后的效果
//rev目录下生成了manifest.json对应文件 { "default.css": "default-803a7fe4ae.css" } <link rel="stylesheet" href="../css/default-803a7fe4ae.css"> <script src="../js/app-3a0d844594.js"></script>
很显然这不是我们需要的效果
3.更改gulp-rev和gulp-rev-collector
打开node_modules\gulp-rev\index.js 第134行 manifest[originalFile] = revisionedFile; 更新为: manifest[originalFile] = originalFile + '?v=' + file.revHash;
打开node_modules\rev-path\index.js(由于版本变化,可能不在此目录) 9行 return modifyFilename(pth, (filename, ext) => `${filename}-${hash}${ext}`); 更新为: return modifyFilename(pth, (filename, ext) => `${filename}-${ext}`);
打开node_modules\gulp-rev-collector\index.js 40行 let cleanReplacement = path.basename(json[key]).replace(new RegExp( opts.revSuffix ), '' ); 修改为 let cleanReplacement = path.basename(json[key]).split('?')[0];
再执行gulp命令,得到的结果如下(效果正确):
<link rel="stylesheet" href="../css/default.css?v=803a7fe4ae"> <script src="../js/app.js?v=3a0d844594"></script>
但是假如我们更改了css和js后,再执行gulp命令,得到的结果会如下:
<link rel="stylesheet" href="../css/default.css?v=33379df310?v=803a7fe4ae"> <script src="../js/app.js?v=3a0d844594?v=3a0d844594"></script>
有没有发现,会在版本号后面再添加一个版本号,因为gulp只替换了原来文件名,这样又不符合预期效果了,所以我们想到,还需要修改插件的替换正则表达式。
4.继续更改gulp-rev-collector
打开node_modules\gulp-rev-collector\index.js 第164行 regexp: new RegExp( prefixDelim + pattern, 'g' ),
更新为: regexp: new RegExp( prefixDelim + pattern+'(\\?v=\\w{10})?', 'g' ),
现在你不管执行多少遍gulp命令,得到的html效果都是
<link rel="stylesheet" href="../css/default.css?v=5a636d79c4"> <script src="../js/app.js?v=3a0d844594"></script>

浙公网安备 33010602011771号