gulp总结
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gulp总结相关的知识,希望对你有一定的参考价值。
Gulp学习文档
常用插件说明:
gulp安装
安装:npm install --global gulp 全局安装
npm install -save-dev gulp 项目的开发依赖
在项目根目录下创建一个名为gulpfile.js
var gulp=require(‘gulp’);
Gulp.task(‘default’,function(){
//任务代码
});
gulp 执行。
-v 或 --version 会显示全局和项目本地所安装的 gulp 版本号
--require <module path> 将会在执行之前 reqiure 一个模块。这对于一些语言编译器或者需要其他应用的情况来说来说很有用。你可以使用多个--require
--gulpfile <gulpfile path> 手动指定一个 gulpfile 的路径,这在你有很多个 gulpfile 的时候很有用。这也会将 CWD 设置到该 gulpfile 所在目录
--cwd <dir path> 手动指定 CWD。定义 gulpfile 查找的位置,此外,所有的相应的依赖(require)会从这里开始计算相对路径
-T 或 --tasks 会显示所指定 gulpfile 的 task 依赖树
--tasks-simple 会以纯文本的方式显示所载入的 gulpfile 中的 task 列表
--color 强制 gulp 和 gulp 插件显示颜色,即便没有颜色支持
--no-color 强制不显示颜色,即便检测到有颜色支持
--silent 禁止所有的 gulp 日志
1、全局安装gulp
npm install -g gulp
2、项目下安装gulp和gulp-uglify
cmd切换到项目目录,执行npm install gulp和npm install gulp-uglify
3、安装完毕后,项目的gulp文件夹下,新增文件gulpfile.js(注意该文件名不可更改),并在gulpfile.js文件中写入代码。
4、执行:(gulp + task名,如果为default,直接执行gulp即可)
安装package.json文件
当你有一个静态文件夹的时候,想要对它进行压缩打包,要先
1.cmd进入到该目录下,安装package.json文件.安装方法是 npm init 就安装成功了。
这个办法叫指令办法,另外一个办法是通过npm安装,方法:
npm install --save-dev或者:npm install
Npm相关说明,参数说明
--save是保存配置信息至package.json(package.json是nodejs的配置文件)
-dev是保存至package.json的devDependences节点下面,不指定-dev会保存至dependencies下面
为什么要保存至package.json?
因为nodejs非常庞大,保存至package.json文件会有利于版本管理,同时,方便其他的开发者,可以直接进行下载即可。
如何找到gulp,及gulp资料
一点gulp教程:http://www.ydcss.com/archives/18#why
Gulp在github地址:
https://github.com/Platform-CUF/use-gulp
Gulp插件网:
Npm官网:
如何找npm能搜到的东西,比如查找gulp的所有插件,在npm官网上的搜索框,输入gulp,搜索。
总结一些常用的gulp插件名称以及它的用法。
参考博客:
https://www.cnblogs.com/Darren_code/p/gulp.html
Glob格式
Glob格式,http://www.jianshu.com/p/ce7cf53274bb,glob格式。
匹配规则
不同语言的 glob 库支持的规则会略有不同。下面是 node-glob 的匹配规则。
* 匹配任意 0 或多个任意字符
? 匹配任意一个字符
[...] 若字符在中括号中,则匹配。若以 ! 或 ^ 开头,若字符不在中括号中,则匹配
!(pattern|pattern|pattern) 不满足括号中的所有模式则匹配
?(pattern|pattern|pattern) 满足 0 或 1 括号中的模式则匹配
+(pattern|pattern|pattern) 满足 1 或 更多括号中的模式则匹配
*(a|b|c) 满足 0 或 更多括号中的模式则匹配
@(pattern|pat*|pat?erN) 满足 1 个括号中的模式则匹配
** 跨路径匹配任意字符
压缩html插件(‘gulp-htmlmin’)
https://www.npmjs.com/package/gulp-htmlmin
npm i gulp-htmlmin --save-dev
例子:
var gulp=require(‘gulp’)
var htmlmin=require(‘gulp-htmlmin’)
Gulp.task(‘minifyhtml’,function(){
gulp.src(‘src/*.html’)
.pipe(htmlmin({collapseWhitespace: true}))
.pipe(gulp.dest(‘dest’))
})
压缩image图片插件(‘gulp-imagemin‘)
https://www.npmjs.com/package/gulp-imagemin
$ npm install --save-dev gulp-imagemin
const gulp = require(‘gulp‘);
const imagemin = require(‘gulp-imagemin‘);
gulp.task(‘default‘, () =>
gulp.src(‘src/images/*‘)
.pipe(imagemin())
.pipe(gulp.dest(‘dist/images‘)));
压缩js插件(‘gulp-uglify’)
Minify files with UglifyJS.
Gulp压缩js是利用Uglifyjs插件进行压缩的,所以要详细了解配置参数,需要查询关键词“Uglifyjs”搜索。网址:http://lisperator.net/uglifyjs/
Github网址:https://github.com/mishoo/UglifyJS2有参数说明。
参数说明中文翻译文档segmentfault总结网址:https://segmentfault.com/a/1190000008995453
Gulp过滤文件,是用语法!,排除已经压缩过的.min.css
用glob格式。
- var gulp = require(‘gulp‘),
- uglify= require(‘gulp-uglify‘);
- gulp.task(‘jsmin‘, function () {
- gulp.src([‘src/js/*.js‘, ‘!src/js/**/{test1,test2}.js‘])
- .pipe(uglify({
- mangle: true,//类型:Boolean 默认:true 是否修改变量名
- compress: true,//类型:Boolean 默认:true 是否完全压缩
- preserveComments: ‘all‘ //保留所有注释
- }))
- .pipe(gulp.dest(‘dist/js‘));
- });
过滤文件,比如.min.js结尾的文件
例子:
var condition = function(f){
if(f.path.endswith(‘.min.js‘)){
return false;
}
return true;
};
gulp.task(‘jsmin‘, function (cb) {
return gulp.src([SRC_DIR+‘/**/*.js‘])
.pipe(sourcemaps.init())
.pipe(gulpif(condition, uglify({mangle: {except: [‘require‘ ,‘exports‘ ,‘module‘ ,‘$‘]}}))) //排除混淆关键字
.pipe(sourcemaps.write(‘.‘))
.pipe(gulp.dest(DEST_DIR));
});
压缩解决条件过滤,条件语句:
gulp-if:可以完美解决问题,且足够优雅。
gulp-filter:可以完美解决问题,但是相比gulp-if略显麻烦。更复杂的场景下用gulp-filter比gulp-if方便。
gulp-ignore:更为强大的过滤,在仅仅只是过滤而不拷贝的情况下首推。
压缩css插件(‘gulp-clean-css‘)
gulp plugin to minify CSS, using clean-css
安装:npm install gulp-clean-css --save-dev
let gulp = require(‘gulp‘);
let cleanCSS = require(‘gulp-clean-css‘);
gulp.task(‘minify-css‘, () => {
return gulp.src(‘styles/*.css‘)
.pipe(cleanCSS())
.pipe(gulp.dest(‘dist‘));
});
压缩if条件(‘gulp-if‘)
var gulpif = require(‘gulp-if‘);
var uglify = require(‘gulp-uglify‘);
var condition = true; // TODO: add business logic
gulp.task(‘task‘, function() {
gulp.src(‘./src/*.js‘)
.pipe(gulpif(condition, uglify()))
.pipe(gulp.dest(‘./dist/‘));
});
例子2:
var gulpif = require(‘gulp-if‘);
var uglify = require(‘gulp-uglify‘);
var beautify = require(‘gulp-beautify‘);
var condition = function (file) {
// TODO: add business logic
return true;
}
gulp.task(‘task‘, function() {
gulp.src(‘./src/*.js‘)
.pipe(gulpif(condition, uglify(), beautify()))
.pipe(gulp.dest(‘./dist/‘));
});
If(condition返回true){
uglify()
}else{
beautify()
}
作用如上解释。
压缩rename重命名(‘gulp-rename‘)
例子:
var rename = require("gulp-rename");
//1 rename via string
gulp.src("./src/main/text/hello.txt")
.pipe(rename("main/text/ciao/goodbye.md"))
.pipe(gulp.dest("./dist")); // ./dist/main/text/ciao/goodbye.md
//2 rename via function
gulp.src("./src/**/hello.txt")
.pipe(rename(function (path) {
path.dirname += "/ciao";
path.basename += "-goodbye";
path.extname = ".md"
}))
.pipe(gulp.dest("./dist")); // ./dist/main/text/ciao/hello-goodbye.md
//3 rename via hash
gulp.src("./src/main/text/hello.txt", { base: process.cwd() })
.pipe(rename({
dirname: "main/text/ciao",
basename: "aloha",
prefix: "bonjour-",
suffix: "-hola",
extname: ".md"
}))
.pipe(gulp.dest("./dist")); // ./dist/main/text/ciao/bonjour-aloha-hola.md
压缩rev文件加hash(‘gulp-rev‘)
安装:$ npm install --save-dev gulp-rev
Static asset revisioning by appending content hash to filenames unicorn.css → unicorn-d41d8cd98f.css
主要是css文件
只有当文件内容有改变的时候,hash值会变,不然第一次打包与第二次打包的hash值是不变的。生成的hash不会主动替换到文件引用中,别的文件名会带hash,src执行的html文件不带,rev-replace后html胡=会带,所以要rename,引用带hash,需要使用rev-place。
实例代码:
const gulp = require(‘gulp‘);
const rev = require(‘gulp-rev‘);
gulp.task(‘default‘, () =>
gulp.src(‘src/**/*.css‘) // src目录下面的所有以.css结尾的css文件
.pipe(rev()) // 加hash值
.pipe(gulp.dest(‘dist‘)) //src目录下面的所有以.css结尾的css文件加完hash输出到dist目录下面
.pipe(rev.manifest()) //创建一个资源对照文件rev-manifest.json
.pipe(gulp.dest(‘dist‘))//rev-manifest.json输出到dist目录下
);
//1.src/*.css:指src的直接子目录,没有的话,也不会有dist目录;
//2.src/**/*.css能匹配到src下面所有以.css结尾的文件
//rev()作用是名字前加hash
?压缩(‘gulp-rev-replace‘)
Gulp-rev生的hash,没有替换到对应的文件,所有用这个替换掉。
但是html文件也替换了,所以要rename,都是一连串的产生问题,解决问题。
压缩useref(‘gulp-useref‘)
<!-- build:js vendor.js -->
<!-- build:js dist-rjs/js/vendor.js -->
<script type="text/javascript" src="../js/index.js"></script>
<!-- /build -->
<!-- endbuild -->
gulp.src(‘src/**/*.html‘,{base:‘.‘}) //找到指定的文件html
.pipe(useref())
.pipe(gulp.dest(‘dist‘)) //输出到dist目录下面
结果会:
在dist目录下面出现 dist-rjs/js/vendor.js这种结构得文件和文件夹,
vendor.js和 src="../js/index.js"一模一样。html会变成这样
<script type="text/javascript" src="dist-rjs/js/vendor.js"></script>
以下理解是错误的。
作用是讲html文件中的css或者js引用文件的href属性的值改变成你要填的值。
例子:
var gulp = require(‘gulp‘),
useref = require(‘gulp-useref‘),
gulpif = require(‘gulp-if‘),
uglify = require(‘gulp-uglify‘),
minifyCss = require(‘gulp-clean-css‘);
gulp.task(‘html‘, function () {
return gulp.src(‘app/*.html‘)
.pipe(useref())
.pipe(gulpif(‘*.js‘, uglify()))
.pipe(gulpif(‘*.css‘, minifyCss()))
.pipe(gulp.dest(‘dist‘));
});
这段解读是:app文件夹下面的html文件中的js后者css文件的href或者src指定路径的值给换成你自己指定的内容,只起到换内容的作用,即换引用路径。
转换前:
<html>
<head>
<!-- build:css css/combined.css -->
<link href="css/one.css" rel="stylesheet">
<link href="css/two.css" rel="stylesheet">
<!-- endbuild -->
</head>
<body>
<!-- build:js scripts/combined.js -->
<script type="text/javascript" src="scripts/one.js"></script>
<script type="text/javascript" src="scripts/two.js"></script>
<!-- endbuild -->
</body>
</html>
转换后:
<html>
<head>
<link rel="stylesheet" href="css/combined.css"/>
</head>
<body>
<script src="scripts/combined.js"></script>
</body>
</html>
?(‘gulp-processhtml‘)与useref对比,尽量用useref
安装:
Npm install --save-dev gulp-processhtml
我认为与gulp-useref的作用有点类似,但是又有点差别。我认为gulp-processhtml在html页面上能识别的是<!-- build:js vendor.js --><!-- /build -->以/build结尾的。不能识别endbuld结尾的。
Gulp-processhtml总结:(不喜欢用)
1,只能识别以/build结尾的html里面的。如:<!-- build:js vendor.js --><!-- /build -->
- 只作src路径替换,不会新生成/dist-rjs/js/vendor.js到相应的目录下。
- Processhtml有remove的功能(不常用,还有别的。。。)
如:
gulp.task(‘default‘, () =>
gulp.src(‘src/html/index.html‘,{base:‘.‘})
.pipe(processhtml())
.pipe(gulp.dest(‘dist‘))
);
这段代码就只能产出:/src/html/index.html,,,,,独这一个文件。只是script标签有build的地方的src被替换了。仅仅起到了替换src地址的作用。
Gulp-useref总结:(喜欢用)
- 识别以endbuild结尾的html里的。如:<!-- build:js vendor.js --><!-- endbuild -->endbuild无反斜杠。
- 不仅作src路径替换,而且dist的目录会多出你要的资源。
如:
gulp.task(‘default‘, () =>
gulp.src(‘src/html/index.html‘,{base:‘.‘})
.pipe(useref())
.pipe(gulp.dest(‘dist‘))
);
产出物是:/src/html/index.htnl,/src/dist-js/js/cendor.js,
<!-- build:css css/css.css inline -->
<link rel="stylesheet" type="text/css" href="../css/index-1.css">
<link rel="stylesheet" type="text/css" href="../css/index-2.css">
<link rel="stylesheet" type="text/css" href="../fonts/iconfont/iconfont.css">
<!-- endbuild -->
还会将这多行css进行合并,生成到/src/css/css.css.
压缩gulp-autoprefixer,css兼容前缀
安装:npm install --save-dev gulp-autoprefixer
“一点”资料:http://www.ydcss.com/archives/94
使用前图:
使用后图:
Windows开发人员手册:
https://msdn.microsoft.com/zh-cn/library/hh757293(v=vs.85).aspx
https://msdn.microsoft.com/zh-cn/library/hh757293(v=vs.85).aspx
压缩gulp-connect
gulp-connect实现网页热加载,实现网页自动刷新。不用,略。
压缩(‘gulp-clean‘)清理文件和文件夹
例子:
//清理dist目录
gulp.task(‘cleanDist‘, function(){
return gulp.src(‘dist‘)
.pipe(clean({force: true}));
});
//清理 temp file/folder
gulp.task(‘cleanTmpFile‘, function(){
return gulp.src([‘dist-rjs‘, ‘src/vendor.js‘, ‘src/common.js‘, ‘src/navMenus.js‘, ‘src/appUrls.js‘])
.pipe(clean({force: true}));
});
意思是将兄弟节点dist-rjs全部删除,还有兄弟节点src下面的4个js文件删除。
压缩(‘gulp-sequence‘)任务顺序执行
Run a series of gulp tasks in order.
例子:
var gulp = require(‘gulp‘)
var gulpSequence = require(‘gulp-sequence‘)
gulp.task(‘test‘, gulpSequence([‘a‘, ‘b‘], ‘c‘, [‘d‘, ‘e‘], ‘f‘))
压缩(‘gulp-concat‘)合并内容,改名字
只有这个命令的话,没有进行压缩,进行了合并,进行命名。
例如这段:
gulp.task(‘js‘, function(){
return gulp.src(config.js,{base:‘.‘})
.pipe(uglify({
mangle: false}))
.pipe( concat( "app.min.js" ) )
.pipe(gulp.dest(‘dist-rjs/build_home‘));
});
意思是:对gulpfile.js的兄弟config.js进行uglify压缩,(//mangle: true,//类型:Boolean 默认:true 是否修改变量名 )false就是不修改变量名,然后命名为app.min.js输出到dist-rjs/build_home目录下面
说明:多个文件的时候用数组,一个文件的时候直接‘aaa’就可以了,gulp-concat只进行合并和重命名,没进行压缩。
压缩注入require(‘gulp-inject‘)
安装npm install --save-dev gulp-inject
如图:合并使用,<!-- inject:js --><!-- endinject -->这是一对,先注入js文件,再buld。
Html页面:
Gulpfile.js的使用地方:
var sources = gulp.src([‘testconcat.css‘, ‘testautoprefixer.css‘], {read: false});
gulp.task(‘default‘, () =>
gulp.src(‘src/html/index.html‘,{base:‘.‘})
.pipe(inject(sources))
.pipe(gulp.dest(‘dist‘))
);
替换前:
替换后:
inject标签没有消失掉,只做了src的路径替换。不会拷贝文件到dist目录,而且如果html中的innject里面之前包裹了资源,执行后,这些资源会不存在了,被替换掉了。
原有被替换,原没有则增加新增资源。
压缩之打包require(‘gulp-zip‘)
var zip = require(‘gulp-zip‘);
例子:
//将dist目录压缩打包
gulp.task(‘zip‘, function() {
return gulp.src(‘dist/**/*‘)
.pipe(zip(‘dist.zip‘))
.pipe(gulp.dest(‘dist‘));
});
压缩改cssurl路径require(‘gulp-modify-css-urls‘)
var modifyCssUrls = require(‘gulp-modify-css-urls‘);
源码是:
gulp.task(‘default‘, () =>
gulp.src(‘src/html/index.html‘,{base:‘.‘})
.pipe(gulpif(‘*.css‘, cleanCSS()))
.pipe(gulpif(‘*.css‘,modifyCssUrls({
//把类似‘../images/test.png‘的路径修改为‘images/test.png‘,
//执行之前需要先做cleanCSS,执行后也需要做
modify: function(url, filePath){
if(url.indexOf(‘../‘) == 0 && url.lastIndexOf(‘../‘) > -1){
return url.slice(url.lastIndexOf(‘../‘)+1);
}
else{
return url;
}
}
})))
.pipe(gulpif(‘*.css‘, cleanCSS()))
.pipe(gulp.dest(‘dist‘))
);
很有必要用处很大。
美工在写页面的时候,一个class的background-url(images/test.png)
加1 ../images/test.png======》images/test.png
+3 ../../../images/test.png======>images/test.png
方法内容自定义,大致也就这个用途了。
压缩换cdn路径require(‘gulp-cdnify‘)
安装:npm install gulp-cdnify --save-dev
参数1:base
参数2:html
参数3:rewriter方法,url是htmlcss里面的路径,对特殊url进行特殊处理,自定义
Process是node参数
如:gulp cdnDist --prod,prod就是gulp的参数
process.argv[3];//0:node 1:gulp 2:cdnify 3:param
关于node获取gulp参数再查一下
var cdnify = require(‘gulp-cdnify‘);
rewriter: function(url, process) {
if (/eot]ttf|woff|woff2/.test(url)) {
return ‘http://myfontcdn.com/‘ + url;
} else if (/(png|jpg|gif)$/.test(url)) {
return ‘http://myimagecdn.com/‘ + url;
} else {
return process(url);
}
}
见实例:
function readCdnUrl(env){
if(env.indexOf(‘prod‘) > 0){
config.ol_investor_cdnUrl = ‘//cdn.chinaclear.cn/siteResource/online-investor/‘;
config.shared_web_components_cdnUrl = ‘//cdn.chinaclear.cn/siteResource/shared-web-components/‘;
}
else{
config.ol_investor_cdnUrl = ‘//wxportal3.test.chinaclear.cn/siteResource/online-investor/‘;
config.shared_web_components_cdnUrl = ‘//wxportal3.test.chinaclear.cn/siteResource/shared-web-components/‘;
}
}
//将html、css中引用资源路径全部替换成cdn路径
gulp.task(‘cdnify‘, function () {
readCdnUrl(process.argv[3]);//0:node 1:gulp 2:cdnify 3:param
return gulp.src([‘dist/**/*.{css,html}‘, ‘!dist/src/lib/**/*‘])
.pipe(cdnify({
base: config.ol_investor_cdnUrl,
html: {
‘link[rel="shortcut icon"]‘: ‘href‘,
},
rewriter: function(url, process){
if(/^\\//.test(url)){
if(url.indexOf(‘/pop-shared-web-components‘) == 0){
return config.shared_web_components_cdnUrl + url.slice(‘/pop-shared-web-components‘.length + 1);
}
//以/开头的绝对路径去掉/
return process(url.slice(1));
}else if(url.indexOf(‘../‘) == 0 ){
//以连续../开头的相对路径去掉开头所有../
return process(url.slice(url.lastIndexOf(‘../‘)+3));
}else{
return process(url);
}
}
}))
.pipe(gulp.dest(‘dist/‘))
});
相同代码,截图如:
Nodejs如何获取gulp参数
比如执行gulp test
如果需要获取test,使用命令process.argv即可
如果执行gulp test --module aaaa,这句话表示的意思执行gulp test,顺带参数module,并且module的值为aaaa,如果要想获取module的值,只需执行
gulp.env.module即可,但是使用evn时会报警告gulp.env has been deprecated
切换开发,测试,生产环境的地址信息,仁者见仁
https://segmentfault.com/a/1190000004138375?_ea=503865
加版本号的作用:
- 方便版本控制,比如1.1版本的样式表,可以升级为2.0版本的样式表
2.强制浏览器更新(因为http请求时,如果访问的路径不变,而客户端缓存中又有该文件时,浏览器会直接调用缓存中的文件,这样的话,即使服务端的css内容变化了,但是客户端仍然有可能显示的是旧文件,而加上新的版本号以后,浏览器会认为这是一个新的访问地址,会重新下载最新版本的文件)
附图片说明
1图写
1图结果,少了body
2图:
2图结果,正常
标签尽量不用<!-- /build -->,正常build 正常<!-- endbuild -->
例子:
<!-- build:js vendor.js -->
<!-- build:js dist-rjs/js/vendor.js -->
<script type="text/javascript" src="../js/index.js"></script>
<!-- /build -->
<!-- endbuild -->
次处,有可省略项。
疑惑的插件css没写进去,但是打包也到了根目录下
插件css
虽然没有路径直接指出要对次处的css进行压缩,但是在以下出现,
也可以说明:
原因是这个执行的html里面build了你找的css资源,主要是gulp-useref等等。
当对一个壳子html处理,gulp.src(壳子html),它.pipe(useref())或者.pipe(processhtml())
.pipe(inject(sources))
.pipe(useref())
的时候,能够通过html上的<!-- build:css css.css inline --> <!-- endbuild -->等等拿到cssjs等文件的流,所以在判断if的时候,js文件css文件是存在的是true,所以执行压缩。
当html<!-- build:css css.css -->
<link rel="stylesheet" type="text/css" href="../css/index-1.css">
<link rel="stylesheet" type="text/css" href="../css/index-2.css">
<link rel="stylesheet" type="text/css" href="../fonts/iconfont/iconfont.css">
<!-- endbuild -->执行.pipe(useref())这句话过的时候,就已经替换成了
<link rel="stylesheet" type="text/css" href="css.css">
不仅是html页面替换了,而且会生成一个css.css文件到指定的输出目录下面。
所以css存在。
同理,js替换了,而且生成一个目录/子目录/vendor.js的文件到输出目录。
Hack作用1
<!--浏览器版本过低提示-->
<!--[if lt IE 10]> <div class="browser-tip"><div class="browser-tip-content">
<i class="icon iconfont"></i>由于您的浏览器版本过低,可能无法在本网站获得最佳体验。建议您将浏览器升级至<a class="browser-link" href="https://www.microsoft.com/zh-cn/download/internet-explorer.aspx" target="_blank">IE10</a>以上版本,或使用<a class="browser-link" href="http://www.google.cn/chrome/browser/desktop/index.html" target="_blank">Chrome</a>、<a class="browser-link" href="http://www.firefox.com.cn" target="_blank">Firefox</a>的最新版本。<i class="icon iconfont browser-tip-close"></i></div></div> <![endif]-->
一句提示,仅仅当ie浏览器版本小于10的时候出现。
图片不要直接写路径到src html页面中,不然打包的时候麻烦。
虽然没这个说法,但是做的时候要考虑。
比如中登的banner图页,https://inv.chinaclear.cn/ 的三个li图,就是直接写在li的class里面,以背景图的方式出现。
但是jd的banner图是写在img src里面。
以上是关于gulp总结的主要内容,如果未能解决你的问题,请参考以下文章