• 前端打包构建工具gulp快速入门


      因为之前一直有人给我推荐gulp,说他这里好哪里好的。grunt熟悉以后实际上他的配置也不难,说到效率的话确实是个问题,尤其项目大了以后,目前位置遇到的项目都还可以忍受。不过不管怎么说,需要亲自用过gulp之后才能品评他和grunt之间的优劣。不废话,直接上实例。

      本人自建了一个前端目录结构,后续的例子都是以这个目录结构为准。dest是我们打包压缩结果保存目录,现在是空的。以后每完成一个实例,我们就会清空一下dest目录,保证下一个实例的结果和实例代码对应。

      

    1. 第一个简单的gulp打包


      1)需要安装nodejshttp://www.cnblogs.com/chuaWeb/p/nodejs-npm.html

      本人的nodejs工程目录为F:chuaNodejs(后续所有相对路径都是相对于这个目录)

      2) 创建package.json文件,可以使用npm init命令来创建。然后在其中的devDependencies中包含gulp相关的插件依赖。我的package.json是这样的

     1 {
     2   "name": "my-gulp",
     3   "version": "1.0.0",
     4   "description": "demo",
     5   "dependencies": {
     6     "express": "3.x"
     7   },
     8   "devDependencies": {
     9     "gulp-clean": "^0.3.2",
    10     "gulp": "^3.9.1",
    11     "gulp-concat": "^2.6.0",
    12     "gulp-mini-css": "^0.0.3",
    13     "gulp-uglify": "^1.5.3",
    14     "gulp-requirejs-optimize": "^0.3.2"
    15   },
    16   "scripts": {
    17     "test": "echo "Error: no test specified" && exit 1"
    18   },
    19   "author": "chua",
    20   "license": "ISC"
    21 }

      随着我们使用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,内容为

     1 var gulp = require('gulp'),
     2     mincss = require('gulp-mini-css'),
     3     uglify = require('gulp-uglify');
     4 
     5 var src_css = './src/css',
     6     dest_css = './dest/css',
     7     src_js = './src/js',
     8     dest_js = './dest/js';
     9 
    10 gulp.task('mincss', function () {
    11     gulp.src(src_css+'/**/*.css')
    12         .pipe(mincss())
    13         .pipe(gulp.dest(dest_css));
    14 });
    15 
    16 gulp.task('minjs', function () {
    17     gulp.src(src_js+'/**/*.js')
    18         .pipe(uglify())
    19         .pipe(gulp.dest(dest_js));
    20 });
    21 
    22 gulp.task('watch', function () {
    23     gulp.watch(src_css+'/**/*.css',['mincss']);
    24     gulp.watch(src_js+'/**/*.js',['minjs']);
    25 });
    26 
    27 gulp.task('default',function(){
    28     gulp.run('minjs','mincss');
    29     gulp.run('watch');
    30 });

      可以看到里面和nodejs代码写法类似。

      4)命令行运行:gulp

      执行结果

      

      可以看到我们将src的js/css都压缩打包到了对应的dest文件夹下

      注意:gulp命令和gulp default等价。而且这个时候监听任务是一直执行着的,每当有相应的文件改动那么就会执行相应的任务。

      5)源码分析:

    1 //注册一个叫做mincss的任务,命令行gulp mincss可以运行这个任务
    2 //需要说明的是代码中”*”代表的是一层文件,而”**”代表要递归其子文件夹
    3 gulp.task('mincss', function () {
    4     gulp.src(src_css+'/**/*.css')//返回了src/css/下的全部(包含子文件夹里的).css文件流;gulp.src(str)返回了一个可读的stream
    5         .pipe(mincss())//执行gulp-mini-css组件任务,压缩所有css文件流
    6         .pipe(gulp.dest(dest_css));//将文件流写入到 COMPRESS/css 里的对应路径下;gulp.dest(str)返回一个可写的stream
    7 });
    1 //注册名为watch的任务
    2 gulp.task('watch', function () {
    3     gulp.watch(src_css+'/**/*.css',['mincss']);//监听src/css/下的全部.css文件,若有改动则执行名为'mincss'任务
    4     gulp.watch(src_js+'/**/*.js',['minjs']);//监听src/css/下的全部.js文件,若有改动则执行名为'minjs'任务
    5 });
    1 //每个gulpfile.js里都应当有一个dafault任务,它是缺省任务入口,运行gulp的时候实际只是调用该任务(从而来调用其它的任务)
    2 gulp.task('default',function(){
    3     gulp.run('minjs','mincss');//立刻执行'minjs','mincss'这两个任务;gulp.run(tasks)表示运行对应的任务
    4     gulp.run('watch');//立刻执行'watch'任务
    5 });

      比较grunt而言,确实更容易上手。

    2. 合并压缩


      有些时候为了减少请求需要合并多个文件,且需要压缩。使用uglifyconcat即可做到这一点。所以还要下载concat插件:npm install gulp-concat --save-dev

      gulpfile.js代码

     1 var gulp = require('gulp'),
     2     uglify = require('gulp-uglify'),
     3     concat = require('gulp-concat');
     4 
     5 var src_js = './src/js',
     6     dest_js = './dest/js';
     7 
     8 gulp.task('minjs', function () {
     9     gulp.src(src_js+'/**/*.js')
    10         .pipe(uglify())//压缩
    11         .pipe(concat("all.min.js"))//合并
    12         .pipe(gulp.dest(dest_js));
    13 });
    14 
    15 gulp.task('watch', function () {
    16     gulp.watch(src_js+'/**/*.js',['minjs']);//监听src/css/下的全部.js文件,若有改动则执行名为'minjs'任务
    17 });
    18 
    19 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源码

     1 var gulp = require('gulp'),
     2     uglify = require('gulp-uglify'),
     3     concat = require('gulp-concat');
     4 
     5 var src_js = './src/js',
     6     dest_js = './dest/js';
     7 
     8 gulp.task('minjs', function () {
     9     gulp.src([src_js+'/bootstrap.min.js',src_js+'/jquery.js'])//先压缩bootstrap,然后再压缩jquery
    10         .pipe(uglify())
    11         .pipe(concat("all.min.js"))
    12         .pipe(gulp.dest(dest_js));
    13 });
    14 
    15 gulp.task('watch', function () {
    16     gulp.watch(src_js+'/**/*.js',['minjs']);//监听src/css/下的全部.js文件,若有改动则执行名为'minjs'任务
    17 });
    18 
    19 gulp.task('default',['minjs','watch']); 

    3. watch事件监听


      watch组件包含在gulp中,不许另行下载。

      我们在最开始的实例中已经用过了watch的基本用法:gulp.watch(glob,tasks)

      现在来看一下另一种用法:gulp.watch(glob,callback)

      gulpfile.js源码

     1 var gulp = require('gulp'),
     2   uglify = require('gulp-uglify'),
     3   notify = require("gulp-notify");
     4 
     5 gulp.task('minjs', function () {
     6   gulp.src('src/main.js')
     7     .pipe(uglify())
     8     .pipe(gulp.dest("dest/"));
     9 });
    10 
    11 gulp.task('watch', function () {
    12   gulp.watch('src/main.js',function(e){
    13     //e有两个属性type/path
    14     if(e.type == "changed"){//added, changed, or deleted
    15       gulp.run("minjs");
    16       console.log(e.type + ": " + e.path);
    17     }
    18   });
    19 });
    20 
    21 gulp.task('default',["minjs",'watch']);

      可以看到函数的参数(事件)e有两个属性typepath。我们可以根据他们的值去做一些定制服务。

      

      Gulp.watch()的另一个非常好的特性是返回watcher对象。利用watcher来监听额外的事件或者向watch中添加文件。

      来看另一份gulpfile.js代码

     1 var gulp = require('gulp'),
     2   uglify = require('gulp-uglify'),
     3   notify = require("gulp-notify");
     4 
     5 gulp.task('minjs', function () {
     6   gulp.src('src/main.js')
     7     .pipe(uglify())
     8     .pipe(gulp.dest("dest/"));
     9 });
    10 
    11 gulp.task('watch', function () {
    12   var watcher = gulp.watch('src/main.js',["minjs"]);
    13   watcher.on('change',function(e){
    14     if(e.type == "changed"){
    15       console.log(e.type + ": " + e.path);
    16     }
    17   });
    18 });
    19 
    20 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:清空文件夹

    1 gulp.src(globs)
    2   .pipe(clean());

      gulp-clean-css:压缩css文件(原gulp-minify-css舍弃)

    1 gulp.src('src/css/t1.css')
    2   .pipe(cssmin())
    3   .pipe(gulp.dest("dest/css/"));

      gulp-less:将less文件编译成css

    1 gulp.src('src/css/t.less')
    2   .pipe(less())
    3   .pipe(gulp.dest("dest/css/"))

      gulp-notify:加控制台描述

    1 gulp.src("./src/test.ext")
    2   .pipe(notify("Found file: <%= file.relative %>!"));

      gulp-autoprefixer:自动为css样式添加兼容浏览器的前缀

    1 gulp.src('src/css/t1.css')
    2         .pipe(autoprefixer({
    3             browsers: ['last 2 versions', 'Android >= 4.0'],
    4             cascade: true, //是否美化属性值 默认:true 像这样:
    5             //-webkit-transform: rotate(45deg);
    6             //        transform: rotate(45deg);
    7             remove:true //是否去掉不必要的前缀 默认:true 
    8         }))
    9         .pipe(gulp.dest('dist/css'));

      gulp-template://替换变量以及动态html

      src/greeting.html

    <h1>Hello <%= name %></h1>

      gulpfile.js处理

    1 gulp.src('src/greeting.html')
    2   .pipe(template({name: 'Sindre'}))
    3   .pipe(gulp.dest('dist'))

      gulp-rename: //更改名称

    1 gulp.src('src/css/**/*.css')
    2   .pipe(concat('all.css'))
    3   .pipe(gulp.dest('dest/css/'))
    4   .pipe(rename({ suffix: '.min' }))//添加后缀
    5   .pipe(gulp.dest('dest/css'));

      gulp-if: 逻辑判断

     1 gulp.task('cssmin', function () {
     2   gulp.src('src/css/**/*.css')
     3     .pipe(concat('all.css'))
     4     .pipe(cssmin())
     5     .pipe(gulp.dest('dest/css'));
     6 });
     7 gulp.task('main', function () {
     8   gulp.src('src/css/**/*.css')
     9     .pipe(gif(true,cssmin()))
    10     .pipe(gulp.dest('dest/css'));
    11 });

      del: 删除指定文件

    del('dest/css/**/*.css')

      gulp-htmlmin: 压缩html

    1 gulp.src('src/html/*.html')
    2   .pipe(htmlmin())
    3   .pipe(gulp.dest('dist/html'));

      gulp-jshint : 检查js 

    1 gulp.src('src/js/*.js')
    2   .pipe(jshint());

      browser-sync: 这个实际不算是gulp的一个插件,但是他实现了在发现文件被修改时会实时更新网页的功能,很有意思,有兴趣的童鞋可以研究一下

      gulp-connect:在本地启动一个Web Server。一般来说写前端界面代码时想要调试都需要一个服务器,这个服务器解决了以往后端服务器的问题。

    1 var gulp = require('gulp'),
    2   connect = require('gulp-connect');
    3  
    4 gulp.task('connect', function() {
    5   connect.server();
    6 });
    7  
    8 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为入口的打包会让人疑惑,需要花些时间,不过资料也多,问题基本都能上网解决。

      如果觉得本文不错,请点击右下方【推荐】!

  • 相关阅读:
    快速排序
    ABP Error in roboto.css can't resolve '97uahxiqZRoncBaCEI3aWxJtnKITppOI_IvcXXDNrsc.woff2'
    .NET Core Log
    .NET Core的配置文件
    VirtualBox多网卡模式
    Maven 常见错误
    python压缩文件脚本
    Windows7 64bit 安装python3.3 & cx_Freeze-4.3.2
    Ubuntu Linux环境变量
    Ubuntu12.04 64bit 安装 Dropbox
  • 原文地址:https://www.cnblogs.com/chuaWeb/p/gulp.html
Copyright © 2020-2023  润新知