前端工具篇:带你走进Gulp

工欲善其事,必先利其器

Gulp是一款前端自动化构建工具。通俗的来说,就是你本来需要很多条指令才可以完成的事情,通过Gulp你可能只需要一条指令。

Gulp是什么鬼

首先,我很确定它不是鬼。对于之前接触过Webpack的人来说,很大的一个疑惑可能就是:这两者有什么区别?因为Webpack几乎能做全部我们需要做的事情,Gulp存在的意义是什么?我只能说:存在即合理。

Gulp貌似是一款取代Grunt的工具,我没有去了解过Grunt,可能是因为没时间,而且好像也不是很有必要。Gulp的核心功能是自动化任务流程,简化操作。比如你需要做打包、编译、压缩、合并等一些乱七八糟的事情,不用Gulp,你可能需要一步一步的“自己”来,而有了Gulp,你预先将这些乱七八糟的事情定义好交给Gulp,然后在特定时刻,Gulp自动将这些事情全都做了。

Webpack的核心功能应该是集中在模块管理上,不过它同样可以通过各种插件,做很多事情。过于纠结这两者的区别也没什么必要。Gulp简单,学起来也就一两天的事。Webpack相对要复杂很多,而且对于新手也有很多坑,但不可忽略它确实很强大。这里的建议是,都学一下,毕竟这是现在最火的两款开发工具。

很重要的几个概念

Gulp不算复杂,去官网也就那么一丁点儿的介绍,所以学习之前有必要先知道一些概念。

配置文件(gulpfile.js)

Gulp既然是一款工具,就得做一些事情,具体要做些什么,还得由我们来指定。在哪里指定,就是在它的配置文件gulpfile.js中,该文件位于项目的根目录下。以后所有Gulp相关的配置语句都是写在gulpfile.js文件中。

任务(Task)

Gulp把需要做的一些事情定义成一个个的任务,每一个任务都有一个名字,然后通过命令调用这个任务的名字,就可以执行该任务对应的代码。如下:

// gulpfile.js 文件中

var gulp = require('gulp');

// style 任务
gulp.task('style', function () {
    // 一些要做的事情
});

// build 任务
gulp.task('build', function () {
   // 要做的事情 
});

大概就是这么个意思,根据你自己的需要,可以定义很多任务(至于最多能定义多少,我也不知道,我想应该会很多很多)。

插件

前面定义的都是一些空任务,啥也不会做。因为Gulp本身不会做任何“事情”,它只负责把那些要做的事情准备(分类、串联)好。具体谁来做,那就是插件

Gulp有很多插件,几乎能满足你的各种需求。我想对于初学者来说有个疑问:我怎么知道我需要的插件叫什么?那么,我在这里先列出一些插件。我也不知道这些是不是常用的插件,不过看起来好像比较常用。

  • gulp-connect:可以跑一个本地服务器,貌似现在应该不会有人直接将index.html拖到浏览器来调试吧;
  • gulp-concat:看清了,这是concat,用来合并文件的;
  • gulp-clean:删除文件用的;
  • gulp-rename:重命名文件;
  • gulp-minify-html:压缩html用的;
  • gulp-inject:可以将css样式和js脚本文件插入到html文件中;
  • gulp-minify-css:压缩css;
  • gulp-uglify:压缩js;
  • gulp-imagemin:压缩图片;
  • gulp-postcss:自动添加css中的前缀,很实用的家伙。

就这些吧,看清楚长啥样就好了。正如你看到的那样,Gulp所有的插件都是以gulp-开头。对于那些有点经验的人来说,要什么插件可能一般都是直接去npmgithub上搜索。对于不知道怎么搜的(一般都是不知道关键词),就老老实实百度吧。

一个很好的习惯就是平时多记录和总结,因为很多插件在不同的工具和平台中,叫法基本上都是一样的。另外,这里还给一个官方收录的插件列表

具体使用方法

Gulp的安装就不说了,需要的直接看看这里

先举一个栗子(玩玩):

// 引入gulp,无需解释
var gulp = require('gulp');
// 引入插件
var connect = require('gulp-connect'),
    sass = require('gulp-sass'),
    uglify = require('gulp-uglify');
    
// 定义任务
gulp.task('server', function () {
    // 使用 connect 插件创建一个服务器
    connect.server({
        // 这里是传入的一些配置项
        root: 'dist',
        livereload: true
    })
});

gulp.task('style', function () {
    // 匹配资源文件
    gulp.src('./src/**/*.scss')
    // 对匹配到的 文件 传到一个插件中
    .pipe(sass({    // 用sass插件处理 匹配到的文件
        // 插件的配置项
        outputStyle: 'compressed'
        // 插件的功能 打印错误信息
    }).on('error', sass.logError))
    // 串联 将sass处理后的文件 传送到下一个插件中
    // 将文件 输出到指定目录下
    .pipe(gulp.dest('dist'))
    // 重新加载 服务器
    .pipe(connect.reload());
});

gulp.task('script', function () {
    gulp.src('./src/**/*.js')
    .pipe(uglify())
    .pipe(gulp.dest('dist'))
    .pipe(connect.reload());
});

// 默认任务 要等到数组中的任务执行完之后 才执行
gulp.task('default', ['style', 'script', 'server'], function () {
    // 监听 匹配到的文件是否改变
    // 一旦变化就执行 数组 中的任务
    gulp.watch('./src/js/*.js', ['script']);
    gulp.watch('./src/css/*.scss', ['style']);
});

Gulp的基本使用大概就这些,gulpfile.js文件大概就是这个样子的。对于该配置文件,命令行只需执行一条语句:

gulp

没错,就这样!该指令会自动执行默认的任务。如果要指定具体的任务,后面直接跟上任务名即可,比如:

gulp server

如何使用插件

不管你通过什么途径找到一款插件,你应该首先去GitHubnpm上去搜索对应的插件,然后通过官方的介绍来了解如何使用它。不过对于跟我一样英语很烂的人来说,可能会直接去百度找相关的用法。不过还是更建议你去阅读官方的介绍,因为那肯定是最新的用法,百度出来的很多都是乱七八糟,需要自己学会筛选。

一般典型的用法就是直接将插件传入.pipe函数中,插件的配置项通过一个对象传入插件中:

.pipe(uglify())

一般若没有特殊要求,可以省略配置项。gulp.src().pipe()都会返回一个叫Vinyl filesstream(我也不知道是个什么鬼),所以这些方法是可以串联起来的。

谈几个API

这里列出一些比较常用的API接口,详细用法请参阅官方文档

  • gulp.src匹配文件用的;
  • gulp.dest输出文件到指定目录;
  • gulp.task:定义一个任务
  • gulp.watch监听文件,改动触发。

好像就这四个?我也是刚发现,还说列几个常用的。所以学起来还是很容易的,不过要全部学通,可能也要花一点时间。反正我是没有认真把官网的文档看完,尽管它一点也不长。我的想法是,掌握基本的使用方法和思想,有实际需求的时候再去参考官方文档。(关键是我现在没这反面的需求啊)

典型的懒人思想,可是也并不无道理,就问一句:哪个行业有Web前端更新的还要快?可能你今天绞尽脑汁学通学透了一个东西,明天就被更好地东西取代了。虽然夸张了一点,但学前端是真心的。所以学好JavaScript本身才最实在,无论前端的东西怎么变,也逃不出html+css+js这三大基础,起码短期内不会。

文件匹配原则

好像这家伙不是按照常规的正则去匹配的,官方给出了一个参考,有兴趣的自己看看,反正我没看。

直接举几个栗子吧:

  • *:能匹配abc.jsa.css,不能匹配a/bc.js
  • **:能匹配a.jsa/b/cd/d.css
  • *.*:能匹配aaa.jsb.css
  • a/**/*.js:能匹配a/b/c/d/ef.jsa/b/c.js

差不多就这样,基本上的一些需求够用了,更复杂的可以自行百度。

还要说明一点,语句gulp.dest('dist')中的dist表示在项目根目录下生成dist目录。输出的文件路径是*号匹配到的文件名(未被修改的情况下),上面例子中输出的目录结构是这样的:

// 假设原文件路径
- src
    - css
        - a.scss
    - js
        - b.js
        
// 输出的文件路径
- dist
    - css
        - a.css
    - js
        - b.js

默认情况下,dist只会替换*号之前的路径,当然也可以自己修改,具体自行参阅官方文档

后记

后面会再写一篇关于Webpack的文章,不过你也别期望能有多深入,我一般只讲究够用和实用,还有会使用(还挺押韵的)。

码字不易,原创更难,如果你喜欢,就请点个赞;如果你不喜欢,也请点个赞。

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

推荐阅读更多精彩内容