[关闭]
@hzl201 2019-12-11T15:48:09.000000Z 字数 8060 阅读 1356

使用gulp部署web前端代码

web gulp 部署


目的

需处理的文件格式

  1. js文件:js
  2. css文件:css
  3. 图片文件:png jpg gif ico svg (ico、svg文件用的少,这次未压缩)
  4. html文件:cshtml html htm (其中cshtml有引用的空格,不能删除,所以不要压缩cshtml文件)

使用gulp工具

先安装node.js工具 去node.js官网下载最新的安装包
然后在shell里查看node和npm的版本信息

node -v
npm -v

安装gulp,这里安装的是gulp4
新建一个项目目录如test
shell里进行该目录,创建初始配置文件package.json

npm init -y

执行gulp的安装,先全局安装,目的是能够执行gulp命令

npm install -g gulp

再进入项目目录局部安装一次gulp

npm install --save-dev gulp

在项目目录下分别安装以下插件gulp-rev、gulp-rev-collerctor 、run-sequence、gulp-convert-encoding、gulp-clean-css、gulp-htmlmin、gulp-imagemin、gulp-minify-css、gulp-uglify

npm install --save-dev gulp-rev gulp-rev-collerctor run-sequence gulp-convert-encoding gulp-clean-css gulp-htmlmin gulp-imagemin gulp-minify-css gulp-uglify

安装后会在package.json中添加这些插件的版本信息

"gulp": "^4.0.2",
"gulp-clean-css": "^4.2.0",
"gulp-convert-encoding": "^2.0.1",
"gulp-htmlmin": "^5.0.1",
"gulp-imagemin": "^6.2.0",
"gulp-minify-css": "^1.2.4",
"gulp-rev": "^9.0.0",
"gulp-rev-collector": "^1.3.1",
"gulp-uglify": "^3.0.2",
"run-sequence": "^2.2.1"

若要对js和css文件加版本信息,还需要修改配置文件

(1)更改gulp-rev文件(node_modules--->gulp-rev--->index.js)

manifest[originalFile] = revisionedFile; 改为

manifest[originalFile] = > originalFile + '?v=' + file.revHash;

(2)更改gulp-rev-collector(node_modules--->gulp-rev-collector--->index.js)

var cleanReplacement = path.basename(json[key]).replace(new RegExp( opts.revSuffix ), '' );

改为 var cleanReplacement = path.basename(json[key]).split('?')[0];

(3)更改rev-path文件(node_module--->rev-path--->index.js)

return modifyFilename(pth, (filename, ext) => ${filename}-${hash}${ext});
改为 return modifyFilename(pth, (filename, ext) => ${filename}${ext}
);

(4)更改gulp-rev-collector(node_modules--->gulp-rev-collector--->index.js)
regexp: new RegExp( prefixDelim + pattern, 'g' ),
改为 regexp: new RegExp( prefixDelim + pattern+'(\\?v=\\w{10})?', 'g' ),

————————————————
版权声明:本文为CSDN博主「我在等风也等你啊」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/github_37077700/article/details/88960863

但这里有一个bug,若html里引用js或css文件时已经加过版本号了,则会导致重复加了版本号。?v=0e56781b2b是加的md5戳,有重复。

~/Scripts/Bus/CommonPrint.js?v=0e56781b2b?v=4.7.0

目前只能让开发人员引用文件时都不加版本信息,即?v=xxxx。
不要写成这种:

~/Scripts/Bus/CommonPrint.js?v=4.7.0

经过测试,把第四部的替换内容改为:

regexp: new RegExp( prefixDelim + pattern + '(\\?v=[\\w\\.]{1,10})?', 'g' ),

能处理html中js和css以前有版本信息导致重复的情况。

而且html里引用js和css文件时要从根目录进行引用,因为要根据映射表进行关键字匹配。
先../到Scripts等目录,或者直接~/Scripts,而不能写成相对路径。若js和css文件之间相互引用则不受影响,css引用image都是用相对路径,导致image无法添加md5戳。

新建gulpfile.js文件和dist、app、rev目录
gulpfile.js是gulp的配置
app为需要处理的文件目录
dist为输出目录
rev是临时文件
修改gulpfile.js文件

先依次加载插件

var gulp = require("gulp"),
    runSequence = require('run-sequence'),
    rev = require('gulp-rev'),
    cleanCss = require('gulp-clean-css'),
    imagemin = require('gulp-imagemin'),
    htmlmin = require('gulp-htmlmin'),
    uglify = require('gulp-uglify'),
    revCollector = require('gulp-rev-collector');
var convertEncoding = require('gulp-convert-encoding');

再分别编写压缩命令
1.js和css生成文件hash编码并生成rev-manifest.json文件名对照映射

//定义js和css源文件路径,+(js|css)匹配当前目录下所有以.js或者.css结尾的文件
var jscssSrc = "app/**/*.+(js|css)";

//js和css生成文件hash编码并在rev/js-css目录下生成rev-manifest.json文件名对照映射
gulp.task('revJscss', function () {
    return gulp.src(jscssSrc)
        .pipe(rev())
        .pipe(rev.manifest())
        .pipe(gulp.dest('rev/js-css'));
});

(1)把不需要转换的cshtml文件复制到临时目录cshtmlmd5
(2)把GB2312格式的cshtml文件复制到临时目录iconv
(3)把GB2312格式的cshtml文件的编码格式转换成utf-8,解决中文乱码问题
(4)把GB2312转utf-8格式的cshtml文件从临时目录iconv复制到cshtmlmd5目录
(5)gulp打包,获取所有js和css文件的md5戳,修改所有cshtml的引用信息,增加v,若有js或css文件被修改,则md5值会变化,相应的cshtml会更新js或css的文件版本信息,解决浏览器缓存未更新的问题,这样就不需要在客户端浏览器手动清理缓存了。
(6)执行7z压缩命令,单独生成带有md5戳的cshtml文件

2.csHtml替换js、css版本

发现vs工具生成的cshtml文件默认采用utf-8-bom格式,但有些cshtml是gb2312格式的,这些gb2312格式的cshtml文件无法转换,容易造成中文乱码。
gb2312是gbk的子集,需先转换成unicode编码,再转换成utf-8-bom。

gb2312  只能表示简体中文。如果将 gb2312 的字体串转化为 UTF-8 的字符串,繁体中文是会乱码的。解决方案是先将
gb2312 转化为 GBK 编码,再转化为 UTF-8 编码。

GBK 是 gb2312 的超集,它兼容 gb2312 编码,同时还包括繁体中文编码。 ————————————————
版权声明:本文为CSDN博主「lizhihaoweiwei」的原创文章,遵循 CC 4.0 BY-SA
版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lizhihaoweiwei/article/details/27332309

gulp默认转换后的文件是utf-8不带bom,可以使用convertEncoding转换成utf-8-bom格式的文件,或使用gulp-bom进行转换。

安装gulp-utf8-convert无法解决所有gbk乱码的问题,所以只有两条路:
1.源码提交时强制都使用utf_8带bom。2.打包时先把所有gbk转换成utf-8,先做一次转换,再加md5戳。

目前可行的方法是先把cshtml文件统一转成utf-8或utf-8带bom的编码格式,手动使用UltraCodingSwitch转换,能转成功,再把转换后的文件加md5戳,最终转成utf-8带bom的编码格式。但这样无法实现完全自动化,需要研究iconv的命令行。
win下载iconv
iconv.exe下载地址:http://files.cnblogs.com/adgnat/iconv.7z

参考这里编写脚本
https://blog.csdn.net/xlyrh/article/details/54092987

把iconv.exe放在windows/system32目录一份,再放D:\upload\iconv一份,修改系统的环境配置,新增path,添加,然后重启Jenkins,否则在自动化执行时会提示'iconv' 不是内部或外部命令,也不是可运行的程序。

我是先
d:
cd d:\目标文件夹
for /r d:\目标文件夹
修改了一下,真正自动化运行时把最下面的暂停去掉。

转换后用notepad++查看已转换的gbk格式的文件,发现还是乱码,因为默认没有使用utf-8打开,在编码里使用utf-8就不会乱码。这个其实无所谓。

//csHtml替换js、css版本
gulp.task('revCshtml', function () {
    return gulp.src(['rev/**/*.json', 'dist/**/*.cshtml'])          
        .pipe(revCollector())
        .pipe(convertEncoding({ iconv: { decode: {}, encode: { addBOM: true}}, to: "utf8" }))
        .pipe(gulp.dest('update'));
});

3.Html和htm替换js、css版本

//Html和htm替换js、css版本
gulp.task('revHtml',function(){
    return gulp.src(['rev/**/*.json', 'app/**/*.+(html|htm)',])
           .pipe(revCollector())
           .pipe(gulp.dest('dist/html'));
});

4.压缩 css 文件
只压缩,不合并。

// 压缩 css 文件
gulp.task('cssMin', function() {
    // 1. 找到文件
  return  gulp.src('app/**/*.css')
    // 2. 压缩文件
        .pipe(cleanCss({ compatibility: 'ie7' })) //浏览器兼容ie7,也可写成ie8
        // 3. 另存压缩后的文件
        .pipe(gulp.dest('dist/cssmin'));
});

5.压缩image
图片压缩用时较长,可以只在输出到生产环境时再压缩。

//压缩image
gulp.task('imageMin', function() {
    return gulp.src('app/9/**/*.+(png|jpg|gif)')
        .pipe(imagemin({
            optimizationLevel: 5, // 取值范围:0-7(优化等级),默认:3  
            progressive: true,  // 无损压缩jpg图片,默认:false 
            interlaced: true    // 隔行扫描gif进行渲染,默认:false 
        }))
        .pipe(gulp.dest('dist/9'));
});

6.压缩html

//压缩html
gulp.task('htmlMin',function() {
    return gulp.src('app/**/*.+(html|htm)')
      .pipe(htmlmin({
        collapseWhitespace:true,   //从字面意思应该可以看出来,清除空格,压缩html,这一条比较重要,作用比较大,引起的改变压缩量也特别大。
        collapseBooleanAttributes:true,   //省略布尔属性的值,比如:<input checked="checked"/>,那么设置这个属性后,就会变成 <input checked/>。
        removeComments:true,   //清除html中注释的部分,我们应该减少html页面中的注释。
        removeEmptyAttributes:true,   //清除所有的空属性。
        removeScriptTypeAttributes:true,   //清除所有script标签中的type="text/javascript"属性。
        removeStyleLinkTypeAttributes:true,   //清除所有Link标签上的type属性。
        minifyJS:true,   //压缩html中的javascript代码。
        minifyCSS:true   //压缩html中的css代码。
    }))
      .pipe(gulp.dest('dist/htmlmin'));
});

7.压缩js
只压缩,不合并。js文件压缩是最难的,有些js文件编写时不规范,默认js都是使用es2015语法编写的,若js文件时es6语法,需要先用babel进行转换。
js文件压缩费时费力,这里为了简化操作,分为三个步骤。

(1)首先是要依次执行js文件的检查,把无法压缩的js文件删除,保存好需要删除的文件路径及文件名,直到所有js文件都能正常压缩。
(2) 根据需要删除的js文件黑名单,在执行js压缩前先把这些js文件移动到临时目录,删除app目录下的js文件。若某个js的目录里有问题的js文件太多,需要把这整个目录都列入黑名单。
(3)由于js压缩很费时间,按照js所在的目录进行同步压缩。
(4)压缩后,把黑名单里移动到临时目录的js文件都移动到压缩后的目录里。

//压缩Areas的js
gulp.task('uglifyJsAreas',function(){
    return gulp.src('update/Areas/**/*.js')
      //.pipe(rename({suffix: '.min'})) 针对生成好的项目原则上没必要重新生成带min的文件 会导致引用的版本不一致  直接在源文件上压缩发布即可
      .pipe(uglify())
      .pipe(gulp.dest('dist/Areas'));
});

//压缩Content的js
gulp.task('uglifyJsContent',function(){
    return gulp.src('update/Content/**/*.js')
      //.pipe(rename({suffix: '.min'})) 针对生成好的项目原则上没必要重新生成带min的文件 会导致引用的版本不一致  直接在源文件上压缩发布即可
      .pipe(uglify())
      .pipe(gulp.dest('dist/Content'));
});

//压缩Scripts的js
gulp.task('uglifyJsScripts',function(){
    return gulp.src('update/Scripts/**/*.js')
      //.pipe(rename({suffix: '.min'})) 针对生成好的项目原则上没必要重新生成带min的文件 会导致引用的版本不一致  直接在源文件上压缩发布即可
      .pipe(uglify())
      .pipe(gulp.dest('dist/Scripts'));
});

8.选择默认需要执行的任务
各个任务都测试无误后,再把输出文件的目录修改为app

在gulpfile.js文件最下面添加以下内容

//开发构建,gulp.series 用于串行(顺序)执行,gulp.parallel 用于并行执行,可以嵌套gulp.series('clean', gulp.parallel('scripts', 'styles')
gulp.task('default', gulp.parallel('cssMin','imageMin','htmlMin','uglifyJsAreas','uglifyJsContent','uglifyJsScripts'));

但若是执行js加版本号的操作,需先执行完js和css文件生成映射表的任务,再并行执行html文件、cshtml文件的修改

//开发构建,异步执行,按顺序执行,先执行revJscss,再并行执行revCshtml和revHtml
gulp.task('default', gulp.series('revJscss', gulp.parallel('revHtml', 'revCshtml')));

9.集成到Jenkins,实现自动化构建操作
有时候Jenkins在打包时无法识别gulp命令,需把C:\Users\Administrator\AppData\Roaming\npm加到系统变量里,这个系统变量PATH,直接追加就好(多个变量值用分号;隔开),不要删除已经有的系统变量PATH。
先检查路径找到node全局文件路径,输入npm config get prefix

参考

gulp为css,js添加版本号
使用前端构建工具批量为页面中引用的js文件添加版本号的历程
gulp中出现windows1252的中文乱码问题的终极解决方案
UTF-8带BOM格式与UTF-8无BOM格式转换
GB2312 转化为 UTF-8 中文乱码
python批处理将utf-8格式文件转为gbk格式
Python对中文字符的处理(utf-8/ gbk/ unicode)
windows开发-utf-8和gbk互转闲谈
文件编码批量转换为utf-8
将文件转成utf8编码的gulp插件——gulp-utf8-convert
gulp生成utf-8文件的同时,也生成gbk版本
windows下对多个文件批量进行编码转换
使用windows命令和iconv.exe批量转换文件编码
jenkins cnpm不是内部或外部命令

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注