gulp详解一

gulp简介

gulp,是基于nodejs的前端自动化构建工具,用于压缩项目文件,合并文件,部署等,简言之,就是解放生产力,提高开发效率。
现如今的前端全正处于飞速发展期,各种号称解放生产力的工具,框架喷涌而出,导致技术栈却是处于不稳定的状态,虽然技术层出不穷,但还是不要盲目的去推崇,还是结合项目本身找到合适的技术栈比较好。
现在大多数项目的技术栈中使用到的前端构建打包工具都是webpack或者webpack+gulp结合使用,本系列将讲解下gulp的使用。

使用前准备

  • nodejs安装
    说明: gulp是基于nodejs运行的前端自动化构建工具,所以必须要先安装nodejs,可前往nodejs官网下载nodejs包安装。

  • 使用命令行
    说明:window系统下可通过window + r 输入cmd回车启动命令行界面,或者安装git客户端。
    简单介绍下几个常用的命令
    1.node -v:查看安装的nodejs版本,出现版本号,说明刚刚已正确安装nodejs
    2.npm -v:查看npm的版本号
    3.cd:定位到目录,用法:cd + 路径
    4.dir:列出文件列表
    5.cls:清空命令提示符窗口内容

  • npm介绍
    说明:npm是nodejs的包管理器,用于node插件管理(包括安装、卸载、管理依赖等)
    1.安装插件:通过命令行 npm install <name> [g] [--save-dev] 安装
    注: <name>,插件名称,如:npm install gulp -g --save-dev。
    [g],全局安装插件,可以通过命令行在任何地方调用它,PS: 本地安装将安装在定位目录的node_modules文件夹下,通过require()调用。
    --save,将保存配置信息至package.json。
    -dev,保存至package.json的devDependencies节点,不指定-dev将保存至dependencies节点。
    2.卸载插件:通过命令行 npm uninstall <name> [-g] [--save-dev] 卸载
    3.更新插件:通过命令行 npm update <name> [-g] [--save-dev] 更新

  • cnpm的安装
    由于npm是从国外服务器下载插件,可能网络方面会比较的慢,影响下载,因此我们需要通过代理的方式来解决这个问题。cnmp是一个淘宝代理镜像,能够代替npm下载需要的插件。
    说明: 通过命令行 npm install cnpm -g --registry=https://registry.npm.taobao.org 安装cnpm镜像代理,安装好后可通过命令行 cnpm -v查看是否安装成功。
    注: cnpm跟npm用法完全一致,只是在执行命令时将npm改为cnpm(以下操作将以cnpm代替npm)。

gulp API

先来了解下gulp常用的一些API。

1. gulp.src()
需要处理的源文件路径,参数可以是字符串,也可以是字符串数组,参数可以是通配符类型。比如,需要将项目下js文件夹下所有js文件做处理,就可以这样写:gulp.src("js/.js")*

2. gulp.dest()
指定处理完后文件的输出路径,参数类型为String or Function
比如将项目下js文件夹下所有js文件处理完后,保存到同级的dist文件夹中,就可以这样写:gulp.dest("dist")

3. gulp.pipe()
该API可以链式调用,在输出和输入之间,可以用pipe指定任意的插件去处理你的文件。

4. gulp.task()
定制gulp任务,参数类型可以是字符串也可以是数组,比如定义第一个gulp执行任务,就可以这样写:gulp.task("firstGulp",function(){})

5. gulp.watch()
用于监听文件变化,任务gulp执行

具体的API参数详解,请参考这两篇关于gulp API的文章
http://www.gulpjs.com.cn/docs/api/
http://www.ydcss.com/archives/424

使用gulp压缩打包js文件

  • 安装gulp
    首先需要在全局下安装gulp,通过命令行 cnpm install gulp -g全局安装gulp。

新建一个gulp文件夹,目录结构如下,

---gulp源文件夹

---script文件夹

---a.js

---package.json文件

---gulpfile.js文件

在gulp文件夹根目录下,通过命令行 cnpm install gulp --save-dev,把gulp插件安装到本地项目的根目录中,至于为什么已经在全局安装了gulp还要在本地项目目录再安装gulp,这是为了防止版本冲突。
在a.js中写入一段代码,这是需要压缩的js文件

function gulpHello(){
    alert("this is gulp firstDemo: hello world!");
}

接着,在项目的根目录下创建一个名为gulpfile.js的文件,这个文件名是gulp固定的,不能修改的。在gulpfile.js中,写入如下代码:

//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模块,用于压缩js
var uglify = require("gulp-uglify");

//自定义任务,firstGulp为自定义任务名
gulp.task("firstGulp",function(){
    gulp.src("./script/a.js")
        .pipe(uglify())
        .pipe(gulp.dest("./dest"))
})

之后再通过命令行执行该任务,输入gulp firstGulp命令行,敲击回车,执行结果如下图

图片发自简书App

出现了报错情况,原因是因为上面引入了压缩js的gulp-uglify模块没有下载到本地,所以我们在引入模块之前,得在本地安装我们需要引入的模块,且引入的模块名与需要安装的模块名是一致的。
比如安装gulp-uglify模块,通过命令行 cnpm install gulp-uglify --save-dev 安装即可。
再来执行gulp下任务,会发现,gulp文件夹中多了一个dist文件夹,里面的a.js文件就是我们压缩过的js文件。

压缩后的a.js

虽然这样可以达到压缩文件的效果了,但是有一点不足的地方就是每次文件修改后都要通过命令行来执行任务,这样就并没有体现出gulp的自动化这样强大的功能。所以得完善gulpfile.js的代码,使其自动化,一旦文件有所改动,就自动执行gulp任务。
这里就可以使用gulp.watch()的API了,来监听文件的改动,从而执行相应的任务。
gulpfile.js文件代码修改如下:

//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模块,用于压缩js
var uglify = require("gulp-uglify");

//自定义任务,firstGulp为自定义任务名
gulp.task("firstGulp",function(){
    gulp.src("./script/a.js")
        .pipe(uglify())
        .pipe(gulp.dest("./dest"))
})

//新增一个auto的任务
gulp.task("auto",function(){
    //watch()监听a.js文件的变动,如果变动,就执行firstGulp任务
    //如果监听script下所有文件,只需把第一个参数改成script/*.js
    gulp.watch("./script/a.js",["firstGulp"]);
})

然后只需要执行命令行 gulp auto 就可以实行自动化压缩文件了,但是这样还是有点不完善,就是gulp.watch方法监听到script文件夹中的某个js代码发生改变时,gulp会将script下所有的js都压缩一遍,极大地影响性能。
为了完善这一点,我们需要引入gulp-watch-path模块,就可以达到修改了哪个文件就压缩哪个文件的目的,而不是盲目压缩。在script文件夹下新增b.js和c.js两个js文件,随便放入一些代码,监听script文件夹下所有文件,那么如何使用gulp-watch-path模块,代码如下:

//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模块,用于压缩js
var uglify = require("gulp-uglify");
//引入gulp-watch-path模块
var watchPath = require("gulp-watch-path");

//自定义任务,firstGulp为自定义任务名
gulp.task("firstGulp",function(){
    gulp.src("./script/a.js")
        .pipe(uglify())
        .pipe(gulp.dest("./dest"))
})

//新增一个auto的任务
gulp.task("auto",function(){
    //watch()监听a.js文件的变动,如果变动,就执行firstGulp任务
    //如果监听script下所有文件,只需把第一个参数改成script/*.js
    //gulp.watch("./script/a.js",["firstGulp"]);
    
    gulp.watch("./script/*.js", function(event){
    var paths = watchPath(event,"script","dist");
        gulp.src(paths.srcPath)
            .pipe(uglify())
            //paths.distDir为目录文件
            .pipe(gulp.dest(paths.distDir));
    })
})

然后再在项目中安装gulp-watch-path模块,执行命令行 gulp auto,再修改a.js

function gulpHello(){
    alert("this is gulp firstDemo: hello world!");
    alert("do something...");
}

然后在dist文件夹下,可以看到压缩后的a.js了,这样就实现了自动化压缩且不盲目压缩的效果了。

自动化压缩后的a.js

但是每次执行任务都需要输入gulp+任务名才行,为了更加的简洁完善,只需要输入gulp敲击回车就可以执行任务,那么完善gulpfile.js就这样实现:

//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模块,用于压缩js
var uglify = require("gulp-uglify");
//引入gulp-watch-path模块
var watchPath = require("gulp-watch-path");

//自定义任务,firstGulp为自定义任务名
gulp.task("firstGulp",function(){
    gulp.src("./script/a.js")
        .pipe(uglify())
        .pipe(gulp.dest("./dest"))
})

//新增一个auto的任务
gulp.task("auto",function(){
    //watch()监听a.js文件的变动,如果变动,就执行firstGulp任务
    //如果监听script下所有文件,只需把第一个参数改成script/*.js
    //gulp.watch("./script/a.js",["firstGulp"]);
    
    gulp.watch("./script/*.js", function(event){
    var paths = watchPath(event,"script","dist");
        gulp.src(paths.srcPath)
            .pipe(uglify())
            //paths.distDir为目录文件
            .pipe(gulp.dest(paths.distDir));
    })
})

//default为gulp默认任务
gulp.task("default",["auto"])

这样就只需要输入gulp敲击回车就可以执行任务了,这样就更加完善了一步。

但是我们发现,压缩后的文件与源文件的文件名是一样的,我们压缩的源文件名为a.js,在dist文件夹下压缩过后的文件名也是a.js。通常我们见到的被压缩过的文件都是会带有.min的后缀,为了完善这一效果,需要引入gulp-rename模块,用于重命名压缩后的文件。
gulpfile.js修改如下:

//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模块,用于压缩js
var uglify = require("gulp-uglify");
//引入gulp-watch-path模块
var watchPath = require("gulp-watch-path");
//引入gulp-rename模块,用于重命名压缩后的文件
var rename = require("gulp-rename");

//自定义任务,firstGulp为自定义任务名
gulp.task("firstGulp",function(){
    gulp.src("./script/a.js")
        .pipe(uglify())
        .pipe(gulp.dest("./dest"))
})

//新增一个auto的任务
gulp.task("auto",function(){
    //watch()监听a.js文件的变动,如果变动,就执行firstGulp任务
    //如果监听script下所有文件,只需把第一个参数改成script/*.js
    //gulp.watch("./script/a.js",["firstGulp"]);
    
    gulp.watch("./script/*.js", function(event){
    var paths = watchPath(event,"script","dist");
        gulp.src(paths.srcPath)
            .pipe(uglify())
            //给压缩后的文件添加.min后缀
            .pipe(rename({suffix: ".min"}))
            //paths.distDir为目录文件
            .pipe(gulp.dest(paths.distDir));
    })
})

//default为gulp默认任务
gulp.task("default",["auto"])

再来执行下gulp,会发现压缩后的文件名改变了

重命名后的文件

合并压缩js文件

如果是在实际项目当中,js文件的个数肯定是很多的,就算我们压缩小了所以文件的体积,把100kb大小的文件压缩成了3kb大小,但在页面还是需要那么多的script标签来引用这些文件,script标签或者link标签过多的话是会影响页面加载性能的。为了进一步优化页面的加载性能,我们需要把多个文件合并压缩成一个文件,然后在页面中引入这个压缩后的文件即可,这样就减少了引入标签的使用。当然在合并压缩的过程中还要考虑到模块文件之间的依赖关系。

首先a.js,b.js,c.js文件代码修改如下:

a.js

function gulpHello(s){
    alert("this is gulp firstDemo: hello world!");
    alert("do something...");
    alert(s);
}

b.js

gulpHello("这是b.js传入的参数");
function Person(name,age){
    this.name = name;
    this.age = age;
    this.sayName = function(){
        alert(this.name);
    }
}

c.js

var ps = new Person("z3", 30);
ps.sayName();

可以明显看出3个js文件中存在这依赖关系,b.js依赖于a.js,c.js依赖于b.js,那么我们需要引入gulp-concat模块来合并文件,在本地项目中安装该模块,gulpfile.js代码修改如下:

//引入gulp插件
var gulp = require("gulp");
//引入gulp-uglify模块,用于压缩js
var uglify = require("gulp-uglify");
//引入gulp-watch-path模块
var watchPath = require("gulp-watch-path");
//引入gulp-rename模块,用于重命名压缩后的文件
var rename = require("gulp-rename");
//引入gulp-concat模块
var concat = require("gulp-concat");
//文件之间的依赖关系
var pathFile = ["./script/a.js","./script/b.js","./script/c.js"];

//自定义任务,firstGulp为自定义任务名
gulp.task("firstGulp",function(){
    gulp.src("./script/a.js")
        .pipe(uglify())
        .pipe(gulp.dest("./dest"))
})

//新增一个auto的任务
gulp.task("auto",function(){
    //watch()监听a.js文件的变动,如果变动,就执行firstGulp任务
    //如果监听script下所有文件,只需把第一个参数改成script/*.js
    //gulp.watch("./script/a.js",["firstGulp"]);
    
    gulp.watch("./script/*.js", function(event){
        gulp.src(pathFile)
            .pipe(uglify())
            //合并压缩为common.js
            .pipe(concat("common.js"))
            //给压缩后的文件添加.min后缀
            .pipe(rename({suffix: ".min"}))
            .pipe(gulp.dest("./dist"));
    })
})

//default为gulp默认任务
gulp.task("default",["auto"])

压缩后的common.min.js如下:

common.min.js

可以看到,已经把3个文件的js代码合并压缩到了一个文件中了,说明已经实现了合并压缩js文件。

对于js文件的压缩差不多就ok了,后面的文章会继续讲解gulp对于css,less,html以及图片的处理,还有文件自动添加版本号的功能。

总结

  1. 安装nodejs
  2. 全局和本地安装gulp
  3. 安装gulp插件
  4. 新建gulpfile.js文件
  5. 通过命令提示符运行gulp任务
  6. gulp常用插件
插件名 作用
gulp-uglify 用于压缩js
gulp-watch-path 用于筛选改动的文件
gulp-rename 用于重命名压缩后的文件
gulp-concat 用于合并文件

此系列文章是对gulp前端自动构建工具的使用以及总结,文中如有不正之处,还望指正。

原创文章,站在前辈们的经验上的总结,文中如有不正之处,还望指正!

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

推荐阅读更多精彩内容

  • 在现在的前端开发中,前后端分离、模块化开发、版本控制、文件合并与压缩、mock数据等等一些原本后端的思想开始...
    Charlot阅读 5,424评论 1 32
  • gulpjs是一个前端构建工具,与gruntjs相比,gulpjs无需写一大堆繁杂的配置参数,API也非常简单,学...
    依依玖玥阅读 3,147评论 7 55
  • 1、gulp的安装 首先确保你已经正确安装了nodejs环境。然后以全局方式安装gulp: npm install...
    F_imok阅读 2,350评论 1 11
  • 什么是GULP? GULP 是前端开发过程中对代码进行构建的工具,是自动化项目的构建利器;她不仅能 对...
    碧玉含香阅读 643评论 0 0
  • 前言 众所周知目前比较火的工具就是gulp和webpack,但webpack和gulp却有所不同,本人两者的底层研...
    cduyzh阅读 1,354评论 0 13