前端打包构建工具gulp快速入门
因为之前一直有人给我推荐gulp,说他这里好哪里好的。grunt熟悉以后实际上他的配置也不难,说到效率的话确实是个问题,尤其项目大了以后,目前位置遇到的项目都还可以忍受。不过不管怎么说,需要亲自用过gulp之后才能品评他和grunt之间的优劣。不废话,直接上实例。
本人自建了一个前端目录结构,后续的例子都是以这个目录结构为准。dest是我们打包压缩结果保存目录,现在是空的。以后每完成一个实例,我们就会清空一下dest目录,保证下一个实例的结果和实例代码对应。
1. 第一个简单的gulp打包
1)需要安装nodejs:http://www.cnblogs.com/chuaWeb/p/nodejs-npm.html
本人的nodejs工程目录为F:\chuaNodejs(后续所有相对路径都是相对于这个目录)
2) 创建package.json文件,可以使用npm init命令来创建。然后在其中的devDependencies中包含gulp相关的插件依赖。我的package.json是这样的
{
"name": "my-gulp",
"version": "1.0.0",
"description": "demo",
"dependencies": {
"express": "3.x"
},
"devDependencies": {
"gulp-clean": "^0.3.2",
"gulp": "^3.9.1",
"gulp-concat": "^2.6.0",
"gulp-mini-css": "^0.0.3",
"gulp-uglify": "^1.5.3",
"gulp-requirejs-optimize": "^0.3.2"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "chua",
"license": "ISC"
}
随着我们使用npm安装的插件添加,里面的内容随之更改。
命令行到nodejs目录(需要系统管理员权限,不然后续过程中会报错)安装gulp作为项目的开发依赖(devDependencies,当然也可以用其他方式安装):npm install --save-dev gulp
gulp有很多官方插件可以去查看安装:http://gulpjs.com/plugins/。
但是下面的几个插件基本上都要用到,可以先安装
gulp:这个是必须安装的,没有它,其它组件都用不了(注意watch组件直接集成在gulp中了,无需额外安装watch组件)
gulp-mini-css :压缩css使用的
gulp-uglify:压缩、混淆js文件用的
3) 在nodejs工程目录下建一个gulpfile.js,内容为
var gulp = require('gulp'),
mincss = require('gulp-mini-css'),
uglify = require('gulp-uglify'); var src_css = './src/css',
dest_css = './dest/css',
src_js = './src/js',
dest_js = './dest/js'; gulp.task('mincss', function () {
gulp.src(src_css+'/**/*.css')
.pipe(mincss())
.pipe(gulp.dest(dest_css));
}); gulp.task('minjs', function () {
gulp.src(src_js+'/**/*.js')
.pipe(uglify())
.pipe(gulp.dest(dest_js));
}); gulp.task('watch', function () {
gulp.watch(src_css+'/**/*.css',['mincss']);
gulp.watch(src_js+'/**/*.js',['minjs']);
}); gulp.task('default',function(){
gulp.run('minjs','mincss');
gulp.run('watch');
});
可以看到里面和nodejs代码写法类似。
4)命令行运行:gulp
执行结果
可以看到我们将src的js/css都压缩打包到了对应的dest文件夹下
注意:gulp命令和gulp default等价。而且这个时候监听任务是一直执行着的,每当有相应的文件改动那么就会执行相应的任务。
5)源码分析:
//注册一个叫做mincss的任务,命令行gulp mincss可以运行这个任务
//需要说明的是代码中”*”代表的是一层文件,而”**”代表要递归其子文件夹
gulp.task('mincss', function () {
gulp.src(src_css+'/**/*.css')//返回了src/css/下的全部(包含子文件夹里的).css文件流;gulp.src(str)返回了一个可读的stream
.pipe(mincss())//执行gulp-mini-css组件任务,压缩所有css文件流
.pipe(gulp.dest(dest_css));//将文件流写入到 COMPRESS/css 里的对应路径下;gulp.dest(str)返回一个可写的stream
});
//注册名为watch的任务
gulp.task('watch', function () {
gulp.watch(src_css+'/**/*.css',['mincss']);//监听src/css/下的全部.css文件,若有改动则执行名为'mincss'任务
gulp.watch(src_js+'/**/*.js',['minjs']);//监听src/css/下的全部.js文件,若有改动则执行名为'minjs'任务
});
//每个gulpfile.js里都应当有一个dafault任务,它是缺省任务入口,运行gulp的时候实际只是调用该任务(从而来调用其它的任务)
gulp.task('default',function(){
gulp.run('minjs','mincss');//立刻执行'minjs','mincss'这两个任务;gulp.run(tasks)表示运行对应的任务
gulp.run('watch');//立刻执行'watch'任务
});
比较grunt而言,确实更容易上手。
2. 合并压缩
有些时候为了减少请求需要合并多个文件,且需要压缩。使用uglify和concat即可做到这一点。所以还要下载concat插件:npm install gulp-concat --save-dev
gulpfile.js代码
var gulp = require('gulp'),
uglify = require('gulp-uglify'),
concat = require('gulp-concat'); var src_js = './src/js',
dest_js = './dest/js'; gulp.task('minjs', function () {
gulp.src(src_js+'/**/*.js')
.pipe(uglify())//压缩
.pipe(concat("all.min.js"))//合并
.pipe(gulp.dest(dest_js));
}); gulp.task('watch', function () {
gulp.watch(src_js+'/**/*.js',['minjs']);//监听src/css/下的全部.js文件,若有改动则执行名为'minjs'任务
}); gulp.task('default',['minjs','watch']);
这里文件会压缩的顺序按照字母顺序并层层深入的顺序压缩到all.min.js中。
这里我们看到gulp.task的用法有多种,gulp.task(name[, deps], fn),deps是一个包含任务列表的数组,这些任务会在你当前任务运行之前完成。详情参考:http://www.gulpjs.com.cn/docs/api/
如果要按照指定的顺序压缩的话,你需要为gulp.src执行文件列表才行,gulp会按照文件列表数组中元素的顺序压缩。
gulpfile.js源码
var gulp = require('gulp'),
uglify = require('gulp-uglify'),
concat = require('gulp-concat'); var src_js = './src/js',
dest_js = './dest/js'; gulp.task('minjs', function () {
gulp.src([src_js+'/bootstrap.min.js',src_js+'/jquery.js'])//先压缩bootstrap,然后再压缩jquery
.pipe(uglify())
.pipe(concat("all.min.js"))
.pipe(gulp.dest(dest_js));
}); gulp.task('watch', function () {
gulp.watch(src_js+'/**/*.js',['minjs']);//监听src/css/下的全部.js文件,若有改动则执行名为'minjs'任务
}); gulp.task('default',['minjs','watch']);
3. watch事件监听
watch组件包含在gulp中,不许另行下载。
我们在最开始的实例中已经用过了watch的基本用法:gulp.watch(glob,tasks)
现在来看一下另一种用法:gulp.watch(glob,callback)
gulpfile.js源码
var gulp = require('gulp'),
uglify = require('gulp-uglify'),
notify = require("gulp-notify"); gulp.task('minjs', function () {
gulp.src('src/main.js')
.pipe(uglify())
.pipe(gulp.dest("dest/"));
}); gulp.task('watch', function () {
gulp.watch('src/main.js',function(e){
//e有两个属性type/path
if(e.type == "changed"){//added, changed, or deleted
gulp.run("minjs");
console.log(e.type + ": " + e.path);
}
});
}); gulp.task('default',["minjs",'watch']);
可以看到函数的参数(事件)e有两个属性type和path。我们可以根据他们的值去做一些定制服务。
Gulp.watch()的另一个非常好的特性是返回watcher对象。利用watcher来监听额外的事件或者向watch中添加文件。
来看另一份gulpfile.js代码
var gulp = require('gulp'),
uglify = require('gulp-uglify'),
notify = require("gulp-notify"); gulp.task('minjs', function () {
gulp.src('src/main.js')
.pipe(uglify())
.pipe(gulp.dest("dest/"));
}); gulp.task('watch', function () {
var watcher = gulp.watch('src/main.js',["minjs"]);
watcher.on('change',function(e){
if(e.type == "changed"){
console.log(e.type + ": " + e.path);
}
});
}); gulp.task('default',["minjs",'watch']);
除了change事件,还可以监听很多其他的事件:
end 在watcher结束时触发(这意味着,在文件改变的时候,任务或者回调不会执行)
error 在出现error时触发
ready 在文件被找到并正被监听时触发
nomatch 在glob没有匹配到任何文件时触发
Watcher对象也包含了一些可以调用的方法:
watcher.end() 停止watcher(以便停止执行后面的任务或者回调函数)
watcher.files() 返回watcher监听的文件列表
watcher.add(glob) 将与指定glob相匹配的文件添加到watcher(也接受可选的回调当第二个参数)
watcher.remove(filepath) 从watcher中移除个别文件
4. 一些gulp重要的插件
gulp:这个是必须安装的,没有它,其它组件都用不了(注意watch组件直接集成在gulp中了,无需额外安装watch组件)
gulp-mini-css :压缩css使用的
gulp-uglify:压缩、混淆js文件用的
gulp-clean:清空文件夹
gulp.src(globs)
.pipe(clean());
gulp-clean-css:压缩css文件(原gulp-minify-css舍弃)
gulp.src('src/css/t1.css')
.pipe(cssmin())
.pipe(gulp.dest("dest/css/"));
gulp-less:将less文件编译成css
gulp.src('src/css/t.less')
.pipe(less())
.pipe(gulp.dest("dest/css/"))
gulp-notify:加控制台描述
gulp.src("./src/test.ext")
.pipe(notify("Found file: <%= file.relative %>!"));
gulp-autoprefixer:自动为css样式添加兼容浏览器的前缀
gulp.src('src/css/t1.css')
.pipe(autoprefixer({
browsers: ['last 2 versions', 'Android >= 4.0'],
cascade: true, //是否美化属性值 默认:true 像这样:
//-webkit-transform: rotate(45deg);
// transform: rotate(45deg);
remove:true //是否去掉不必要的前缀 默认:true
}))
.pipe(gulp.dest('dist/css'));
gulp-template://替换变量以及动态html
src/greeting.html
<h1>Hello <%= name %></h1>
gulpfile.js
处理
gulp.src('src/greeting.html')
.pipe(template({name: 'Sindre'}))
.pipe(gulp.dest('dist'))
gulp-rename: //更改名称
gulp.src('src/css/**/*.css')
.pipe(concat('all.css'))
.pipe(gulp.dest('dest/css/'))
.pipe(rename({ suffix: '.min' }))//添加后缀
.pipe(gulp.dest('dest/css'));
gulp-if: 逻辑判断
gulp.task('cssmin', function () {
gulp.src('src/css/**/*.css')
.pipe(concat('all.css'))
.pipe(cssmin())
.pipe(gulp.dest('dest/css'));
});
gulp.task('main', function () {
gulp.src('src/css/**/*.css')
.pipe(gif(true,cssmin()))
.pipe(gulp.dest('dest/css'));
});
del: 删除指定文件
del('dest/css/**/*.css')
gulp-htmlmin: 压缩html
gulp.src('src/html/*.html')
.pipe(htmlmin())
.pipe(gulp.dest('dist/html'));
gulp-jshint: 检查js
gulp.src('src/js/*.js')
.pipe(jshint());
browser-sync: 这个实际不算是gulp的一个插件,但是他实现了在发现文件被修改时会实时更新网页的功能,很有意思,有兴趣的童鞋可以研究一下
gulp-connect:在本地启动一个Web Server。一般来说写前端界面代码时想要调试都需要一个服务器,这个服务器解决了以往后端服务器的问题。
var gulp = require('gulp'),
connect = require('gulp-connect'); gulp.task('connect', function() {
connect.server();
}); gulp.task('default', ['connect']);
更多详情可以参考https://www.npmjs.com/package/gulp-connect
使用实例可以参考使用Gulp构建本地开发Web服务器
5. 总结
从速度来说:gulp比grunt要快,gulp不用重复读写文件。特别是对于项目很大的情况,使用gulp打包确实是更好的选择。
从使用简洁方面来说:grunt需要的配置文件,在一些时候配置文件会很多,而gulp是按任务分解的,所有的配置变成了一连串的任务,从代码上面来说可能会比grunt简洁一些。
从学习成本来说:别人说gulp学习成本比grunt低,但是就本人而言,实际上两者都很容易上手,基础的都很简单,更详细的需要查官网,所以应该是差不多的。
从成熟程度来说:grunt要比gulp成熟,grunt的插件虽然有些私人写的导致良莠不齐,但是数量和完备性要比gulp好,甚至很多怪癖的需求都能找到相关的插件。而且一般来说越是简洁的东西约不适合大型项目,gulp等待检验。所以对于大型项目建议使用成熟的grunt。
现在来说的话,gulp的功能也是比较完备的了,基本构建都不成问题,所以对于中小型项目,按照做程序员就一定用最好的工具的标准的话,比较推荐gulp。
gulp因为是基于流的构建,而且这个流是vinyl流,和buffer不兼容,参考这篇文章http://sentsin.com/web/210.html
gulp的一些技巧参考http://www.gulpjs.com.cn/docs/recipes/
============================================================
后记:
2019.12.20 现在项目主要都用webpack了,实际上webpack不应该和gulp对比,应该和fis3对比,两者都是一套模块化解决的方案。个人之前用fis3很顺手,文档稍微少了些,社区和维护团队都散的差不多了。不可否认,webpack上很多精华早在fis3上就已经有了,比如异步加载的依赖图,模块加载器等等,可惜了。webpack配置是很复杂的,特别是对于新手来说,以js为入口的打包会让人疑惑,需要花些时间,不过资料也多,问题基本都能上网解决。
如果觉得本文不错,请点击右下方【推荐】!
前端打包构建工具gulp快速入门的更多相关文章
- 前端打包构建工具grunt快速入门(大篇幅完整版)
打包的目的和意义就不用叙述了直接上干货 http://www.gruntjs.net/getting-started里面的教程也太简单了,需要下一番功夫去研究才行.本文将grunt打包的常用方法都用实 ...
- 前端自动化构建工具Gulp简单入门
昨天听同事分享了Gulp的一些简单使用,决定自己也试一试. 一.安装 gulp是基于nodejs的,所以要先下载安装node(直接搜node,在官网下载就好了) 1.全局安装gulp npm inst ...
- 前端自动化构建工具gulp的使用总结
前端自动化构建工具gulp的使用总结 博主最近偶的空闲,在此对gulp的使用做一个总结,让小伙伴知道如何合理的使用gulp以及gulp的使用技巧. 谈到gulp,有人可能就会想到另外一个构建工具gru ...
- 前端自动化构建工具 Gulp 使用
一个月没写博客了,今天有时间,就写个gulp的入门使用吧.. 简介:gulp是一个前端自动化构建工具,可以实现代码的检查.压缩.合并……等等,gulp是基于Node.js的自动任务运行器 一.安装No ...
- 前端自动化构建工具——gulp
gulp是基于流的前端自动化构建工具. 一.环境配置 gulp是基于nodejs的,所以没有 nodejs 环境的要先去安装好 然后给系统配上gulp环境 npm install -g gulp 再到 ...
- 前端开发构建工具gulp的安装使用
曾几何时还在使用grunt作为前端的构建工具,直到有一天同事向我推荐了gulp,在这里博主将不讨论gulp与grunt各自优势的比较,只为大家介绍gulp如何安装和使用. Gulp 是用 nodejs ...
- 前端自动化构建工具gulp记录
一.安装 1)安装nodejs 通过nodejs的npm安装gulp,插件也可以通过npm安装.windows系统是个.msi工具,只要一直下一步即可,软件会自动在写入环境变量中,这样就能在cmd命令 ...
- 前端自动化构建工具--Gulp&&Webpack
前端构建工具的作用可以认为是对源项目文件或资源进行文件级处理,将文件或资源处理成需要的最佳输出结构和形式. 在处理过程中,我们可以对文件进行模块化引入.依赖分析.资源合并.压缩优化.文件嵌入.路径替换 ...
- 前端自动化构建工具——gulp环境搭建教程
gulp是前端工程化的工具,它可以对html,css,js等代码和图片进行压缩,也可以对sass和less等预处理语言进行编译,代码部署.gulp学起来简单,用起来方便,大大提高我们工作效率. 这里可 ...
随机推荐
- JavaScript var关键字、变量的状态、异常处理、命名规范等介绍
本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...
- JavaScript Object对象
目录 1. 介绍:阐述 Object 对象. 2. 构造函数:介绍 Object 对象的构造函数. 3. 实例属性:介绍 Object 对象的实例属性:prototype.constructor等等. ...
- Android调用微信登陆、分享、支付
前言:用了微信sdk各种痛苦,感觉比qq sdk调用麻烦多了,回调过于麻烦,还必须要在指定包名下的actvity进行回调,所以我在这里写一篇博客,有这个需求的朋友可以借鉴一下,以后自己别的项目有用到也 ...
- node中子进程同步输出
管道 通过"child_process"模块fork出来的子进程都是返回一个ChildProcess对象实例,ChildProcess类比较特殊无法手动创建该对象实例,只能使用fo ...
- iOS架构一个中型普通App的一些经验总结
这一版比较完善的的App终于提交审核了.有时间写写自己的一些经验的总结了.自己主导的从0到比较成型的app到目前来说也只有两个,但是其中的很多东西都是大同小异.基本上是想到了什么就写什么,感觉写的不到 ...
- 让 asp.net 在 mac 上飞
.NET 不跨平台一直饱受争议,虽然微软前端时间放出些消息,要支持.NET跨平台的发展,但是微软一直坚持着不主动.不拒绝.不负责的三不态度,仍然用一种软件帝国的心态,折腾着一些毫无新意的东西.微软想要 ...
- 前端自学路线之js篇
上一篇我们讲了前端切图的学习路线,不知大家有没有收获.今天来聊聊前端工程师的核心技能之——JavaScript.js这门语言看似简单,但要做到入门.熟练以至于架构的程度,还是有一段路要走的,今天就来聊 ...
- 抛弃jQuery:Why?
原文链接:http://blog.garstasio.com/you-dont-need-jquery/ 我的Blog:http://cabbit.me/you-dont-need-jquery/wh ...
- CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总
CSharpGL(38)带初始数据创建Vertex Buffer Object的情形汇总 开始 总的来说,OpenGL应用开发者会遇到为如下三种数据创建Vertex Buffer Object的情形: ...
- 从scheduler is shutted down看程序员的英文水平
我有个windows服务程序,今天重点在测试系统逻辑.部署后,在看系统日志时,不经意看到一行:scheduler is shutted down. 2016-12-29 09:40:24.175 {& ...