Gulp 自动化你的前端

Gulp

Gulp 自动化你的前端

“1. 我为什么使用grunt; 2. 我为何放弃grunt转投gulp; 3. 我为何放弃gulp与grunt,转投npm scripts; 4. 我为何放弃前端” —— 司徒正美

前端(段子)界的发展突飞猛进,总感觉随时会跟不上技术潮流(其实我已经被甩开了一条街,so sad

选择在这样一个时机发布一篇 gulp 教程并不是我的初衷,第一次用 gulp 是在一年前,而这篇帖子在草稿箱里躺了一个多月,再不发出来说不定就过时了。

当我在用 gulp 时我用它做什么?

  1. 编译 sass
  2. 合并优化压缩 css
  3. 校验压缩 js
  4. 优化图片
  5. 添加文件指纹(md5)
  6. 组件化头部底部(include html)
  7. 实时自动刷新…

总之,gulp是前端开发过程中对代码进行自动化构建的利器。它不仅能对资源进行优化,而且在开发过程中能够通过配置自动完成很多重复的任务,让我们可以专注于代码,提高工作效率。

然而由于众所周知的原因,国内到 npm 服务器的连接很不稳定,如果你有V了个PN大可不必担心,也可通过设置 npm 代理服务器的方式访问:

设置与删除 npm 代理
1
2
3
4
// 设置代理
npm config set proxy="http://127.0.0.1:1080"
// 删除代理
npm config delete proxy

推荐一个简单的方案:使用淘宝 npm 镜像 

“这是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。” —— 淘宝团队点赞

更换 npm 为淘宝源
1
2
npm config set registry="https://registry.npm.taobao.org"
npm config set disturl https://npm.taobao.org/dist

 

接下来开始 gulp 教程:

准备工作: 安装 node.js (推荐 TLS 版),并重启系统。

1. 全局安装 gulp
全局安装gulp
1
npm install gulp -g
2. 目录结构:

└── src/            源码目录

├── build/   .html 组件
├── sass/     .scss .sass 文件
├── css/       .css 文件
├── js/         .js 文件
└── img/     图片

└── dist/        输出目录
└── package.json
└── gulpfile.js

3. 关于 package.json

可以在项目上使用 npm init 配置,推荐直接新建并写入初始内容:

package.json
1
2
3
4
5
6
{
   "name" : "gulp-build" ,
   "version" : "1.0.0" ,
   "description" : "Gulp.js" ,
   "private" : true
}

对于完整的 package.json (比如别人的开源项目), 只需对整个项目执行 npm install 即可安装 package.json 文件中声明的所有插件模块。

4. 给项目目录安装 gulp
给项目目录安装gulp
1
npm install gulp --save-dev

—save-dev 这个参数会将插件信息自动更新到 package.json 里,其中的 devDependencies 属性会随插件依赖的安装卸载而改变。

PS. Windows 7及以上,按住 Shift 再右键,选择在此处打开命令窗口。免去 cd 命令定位目录的烦恼。

5. 给项目目录安装常用的插件

PS.可与上一步同时进行

给项目目录安装插件
1
npm install gulp gulp-ruby-sass gulp-cached gulp-uglify gulp-rename gulp-concat gulp-notify gulp-filter gulp-jshint gulp-rev-append gulp-cssnano gulp-imagemin browser-sync gulp-file-include gulp-autoprefixer del --save-dev

插件将在配置文件里介绍,更多用法请参见相应的 GitHub 主页,或者直接戳这里: https://www.npmjs.com/package/

以上两个安装操作将会在项目目录下生成 node_modules 文件夹,相应的插件都在这里。

Windows 用户请注意,此文件夹可能 无法删除 无法复制 无法移动,会出现诸如“包含名称过长且无法放入回收站”,“源文件名长度大于文件系统支持的长度。请尝试将其移动到具有较短路径名称的位置” 等等问题。使用一个简单的方式即可删除,使用 WinRAR “添加到压缩文件”,勾选压缩选项里的 “压缩后删除源文件” ,确定之后即可删除。

6. API

别看我,看它:http://www.gulpjs.com.cn/docs/api/

7. 代码示例
src/build/header.html
1
2
3
4
5
6
7
8
9
10
<! DOCTYPE html>
< html >
< head >
< meta charset = "utf-8" />
< title >嘿嘿嘿</ title >
< link href = "css/m.base.css?rev=@@hash" rel = "stylesheet" type = "text/css" />
< link href = "css/jquery.fullPage.css?rev=@@hash" rel = "stylesheet" type = "text/css" />
< link href = "css/mobile.css?rev=@@hash" rel = "stylesheet" type = "text/css" />
</ head >
< body >
src/build/footer.html
1
2
3
4
5
<!-- common js -->
< script type = "text/javascript" src = "js/jquery-2.1.4.min.js" ></ script >
< script type = "text/javascript" src = "js/main.js?rev=@@hash" ></ script >
</ body >
</ html >
src/index.html
1
2
3
4
5
@@include('build/header.html')
 
< div class = "wrap" >内容</ div >
 
@@include('build/footer.html')

代码中, ?rev=@@hash  是 gulp-rev-append 插件的指纹标识
@@include(‘build/header.html’) 可以插入 html 文件,还可以配合参数生成独立的头部。

8. 我的 gulpfile.js,配置及说明
gulpfile.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*!
  * gulp
  * $ npm install gulp gulp-ruby-sass gulp-cached gulp-uglify gulp-rename gulp-concat gulp-notify gulp-filter gulp-jshint gulp-rev-append gulp-cssnano gulp-imagemin browser-sync gulp-file-include gulp-autoprefixer del --save-dev
  */
 
// Load plugins
var gulp = require( 'gulp' ), // 必须先引入gulp插件
     del = require( 'del' ),  // 文件删除
     sass = require( 'gulp-ruby-sass' ), // sass 编译
     cached = require( 'gulp-cached' ), // 缓存当前任务中的文件,只让已修改的文件通过管道
     uglify = require( 'gulp-uglify' ), // js 压缩
     rename = require( 'gulp-rename' ), // 重命名
     concat = require( 'gulp-concat' ), // 合并文件
     notify = require( 'gulp-notify' ), // 相当于 console.log()
     filter = require( 'gulp-filter' ), // 过滤筛选指定文件
     jshint = require( 'gulp-jshint' ), // js 语法校验
     rev = require( 'gulp-rev-append' ), // 插入文件指纹(MD5)
     cssnano = require( 'gulp-cssnano' ), // CSS 压缩
     imagemin = require( 'gulp-imagemin' ), // 图片优化
     browserSync = require( 'browser-sync' ), // 保存自动刷新
     fileinclude = require( 'gulp-file-include' ), // 可以 include html 文件
     autoprefixer = require( 'gulp-autoprefixer' ); // 添加 CSS 浏览器前缀
 
// sass
gulp.task( 'sass' , function () {
   return sass( 'src/sass/**/*.scss' , {style: 'expanded' })  // 传入 sass 目录及子目录下的所有 .scss 文件生成文件流通过管道并设置输出格式
     .pipe(cached( 'sass' ))  // 缓存传入文件,只让已修改的文件通过管道(第一次执行是全部通过,因为还没有记录缓存)
     .pipe(autoprefixer( 'last 6 version' )) // 添加 CSS 浏览器前缀,兼容最新的5个版本
     .pipe(gulp.dest( 'dist/css' )) // 输出到 dist/css 目录下(不影响此时管道里的文件流)
     .pipe(rename({suffix: '.min' })) // 对管道里的文件流添加 .min 的重命名
     .pipe(cssnano()) // 压缩 CSS
     .pipe(gulp.dest( 'dist/css' )) // 输出到 dist/css 目录下,此时每个文件都有压缩(*.min.css)和未压缩(*.css)两个版本
});
 
// css (拷贝 *.min.css,常规 CSS 则输出压缩与未压缩两个版本)
gulp.task( 'css' , function () {
   return gulp.src( 'src/css/**/*.css' )
     .pipe(cached( 'css' ))
     .pipe(gulp.dest( 'dist/css' )) // 把管道里的所有文件输出到 dist/css 目录
     .pipe(filter([ '**/*' , '!**/*.min.css' ])) // 筛选出管道中的非 *.min.css 文件
     .pipe(autoprefixer( 'last 6 version' ))
     .pipe(gulp.dest( 'dist/css' )) // 把处理过的 css 输出到 dist/css 目录
     .pipe(rename({suffix: '.min' }))
     .pipe(cssnano())
     .pipe(gulp.dest( 'dist/css' ))
});
 
// styleReload (结合 watch 任务,无刷新CSS注入)
gulp.task( 'styleReload' , [ 'sass' , 'css' ], function () {
   return gulp.src([ 'dist/css/**/*.css' ])
     .pipe(cached( 'style' ))
     .pipe(browserSync.reload({stream: true })); // 使用无刷新 browserSync 注入 CSS
});
 
// script (拷贝 *.min.js,常规 js 则输出压缩与未压缩两个版本)
gulp.task( 'script' , function () {
   return gulp.src([ 'src/js/**/*.js' ])
     .pipe(cached( 'script' ))
     .pipe(gulp.dest( 'dist/js' ))
     .pipe(filter([ '**/*' , '!**/*.min.js' ])) // 筛选出管道中的非 *.min.js 文件
     // .pipe(jshint('.jshintrc')) // js的校验与合并,根据需要开启
     // .pipe(jshint.reporter('default'))
     // .pipe(concat('main.js'))
     // .pipe(gulp.dest('dist/js'))
     .pipe(rename({suffix: '.min' }))
     .pipe(uglify())
     .pipe(gulp.dest( 'dist/js' ))
});
 
// image
gulp.task( 'image' , function () {
   return gulp.src( 'src/img/**/*.{jpg,jpeg,png,gif}' )
     .pipe(cached( 'image' ))
     .pipe(imagemin({optimizationLevel: 3, progressive: true , interlaced: true , multipass: true }))
     // 取值范围:0-7(优化等级),是否无损压缩jpg图片,是否隔行扫描gif进行渲染,是否多次优化svg直到完全优化
     .pipe(gulp.dest( 'dist/img' ))
});
 
// html 编译 html 文件并复制字体
gulp.task( 'html' , function () {
   return gulp.src( 'src/*.html' )
     .pipe(fileinclude()) // include html
     .pipe(rev()) // 生成并插入 MD5
     .pipe(gulp.dest( 'dist/' ))
});
 
// clean 清空 dist 目录
gulp.task( 'clean' , function () {
   return del( 'dist/**/*' );
});
 
// build,关连执行全部编译任务
gulp.task( 'build' , [ 'sass' , 'css' , 'script' , 'image' ], function () {
   gulp.start( 'html' );
});
 
// default 默认任务,依赖清空任务
gulp.task( 'default' , [ 'clean' ], function () {
   gulp.start( 'build' );
});
 
// watch 开启本地服务器并监听
gulp.task( 'watch' , function () {
   browserSync.init({
     server: {
       baseDir: 'dist' // 在 dist 目录下启动本地服务器环境,自动启动默认浏览器
     }
   });
 
   // 监控 SASS 文件,有变动则执行CSS注入
   gulp.watch( 'src/sass/**/*.scss' , [ 'styleReload' ]);
   // 监控 CSS 文件,有变动则执行CSS注入
   gulp.watch( 'src/css/**/*.css' , [ 'styleReload' ]);
   // 监控 js 文件,有变动则执行 script 任务
   gulp.watch( 'src/js/**/*.js' , [ 'script' ]);
   // 监控图片文件,有变动则执行 image 任务
   gulp.watch( 'src/img/**/*' , [ 'image' ]);
   // 监控 html 文件,有变动则执行 html 任务
   gulp.watch( 'src/**/*.html' , [ 'html' ]);
   // 监控 dist 目录下除 css 目录以外的变动(如js,图片等),则自动刷新页面
   gulp.watch([ 'dist/**/*' , '!dist/css/**/*' ]).on( 'change' , browserSync.reload);
 
});
9. 使用 gulp 的方法
执行gulp任务
1
gulp taskname // 如 gulp sass,不指定 taskname 则默认执行 default 任务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值