盒子
盒子
文章目录󰁋
  1. 一、gulp 入门简介
    1. 1.1 规律
    2. 1.2 编写 gulp 代码
    3. 1.3 代码执行结果
  2. 二、安装 Node 和 gulp
    1. 2.1 命令行
    2. 2.2 终端(Mac)
    3. 2.3 查看 node 版本号
    4. 2.4 跳转目录
    5. 2.5 Windows
    6. 2.6 Mac
    7. 2.7 退出运行状态
    8. 2.8 npm 模块管理器
    9. 2.9 安装 gulp
  3. 三、使用 gulp 压缩 JS
    1. 3.1 新建一个 gulpfile.js 文件
    2. 3.2 在 gulpfile.js 中编写代码
    3. 3.3 获取 gulp-uglify 组件
    4. 3.4 创建压缩任务
    5. 3.5 跳转至 gulpfile.js 所在目录
    6. 3.6 使用命令行运行 script 任务
    7. 3.7 安装 gulp-uglify 模块
    8. 3.8 编写 js 文件
    9. 3.9 检测代码修改自动执行任务
    10. 3.10 使用 gulp.task(‘default’, fn) 定义默认任务
  4. 四、使用 gulp 压缩 CSS
    1. 4.1 安装 gulp-minify-css模块
    2. 4.2 参照 [使用 gulp 压缩 JS]创建 gulpfile.js 文件编写代码
    3. 4.3 创建 css 文件
    4. 4.4 运行 gulp 查看效果
  5. 五、使用 gulp 压缩图片
    1. 5.1 安装 gulp-imagemin 模块
    2. 5.2 创建 gulpfile.js 文件编写代码
    3. 5.3 在 images/ 目录下存放图片
    4. 5.4 运行 gulp 查看效果
  6. 使用 gulp 编译 LESS
  7. 安装
  8. 基本用法
  9. LESS 代码和编译后的CSS代码
  10. 六、使用 gulp 编译 Sass
    1. 6.1 gulp-sass
    2. 6.2 安装
    3. 6.3 基本用法
  11. 七、使用 gulp 构建一个项目
    1. 7.1 package.json
    2. 7.2 安装依赖
    3. 7.3 设计目录结构
    4. 7.4 让命令行输出的文字带颜色
    5. 7.5 配置 JS 任务
      1. 7.5.1 gulp-uglify
      2. 7.5.2gulp-watch-path
      3. 7.5.3 watchPath(event, search, replace, distExt)
      4. 7.5.4 stream-combiner2
      5. 7.5.5 gulp-sourcemaps
    6. 7.6 配置 CSS 任务
      1. 7.6.1 gulp-minify-css
      2. 7.6.2 gulp-autoprefixer
    7. 7.7 配置 Less 任务
    8. 7.8 配置 Sass 任务
    9. 7.9 配置 image 任务
    10. 7.10 配置文件复制任务

gulp学习总结篇

声明 本教程整理于互联网

一、gulp 入门简介


gulp 是基于 node 实现Web 前端自动化开发的工具,利用它能够极大的提高开发效率。

在 Web 前端开发工作中有很多“重复工作”,比如压缩CSS/JS文件。而这些工作都是有规律的。找到这些规律,并编写 gulp 配置代码,让 gulp 自动执行这些“重复工作”。

  • 将规律转换为 gulp 代码
  • 现有目录结构如下:
1
2
└── js/
└── a.js

1.1 规律


  • 找到 js/目录下的所有 .js 文件
  • 压缩这些 js 文件
  • 将压缩后的代码另存在 dist/js/ 目录下

1.2 编写 gulp 代码


1
2
3
4
5
6
7
8
9
// 压缩 JavaScript 文件
gulp.task('script', function() {
// 1. 找到
gulp.src('js/*.js')
// 2. 压缩
.pipe(uglify())
// 3. 另存
.pipe(gulp.dest('dist/js'));
});

1.3 代码执行结果


代码执行后文件结构

1
2
3
4
5
└── js/
│ └── a.js
└── dist/
└── js/
└── a.js

a.js 压缩前

1
2
3
4
5
function demo (msg) {
alert('--------\r\n' + msg + '\r\n--------')
}

demo('Hi')

a.js 压缩后

1
function demo(n){alert("--------\r\n"+n+"\r\n--------")}demo("Hi");

此时 dist/js 目录下的 .js 文件都是压缩后的版本。

你还可以监控 js/ 目录下的 js 文件,当某个文件被修改时,自动压缩修改文件。启动 gulp 后就可以让它帮助你自动构建 Web 项目。


gulp 还可以做很多事,例如:

  1. 压缩CSS
  2. 压缩图片
  3. 编译Sass/LESS
  4. 编译CoffeeScript
  5. markdown转换为 html

二、安装 Node 和 gulp


gulp 是基于 node 实现的,那么我们就需要先安装 node。

Node 是一个基于Chrome JavaScript V8引擎建立的一个平台,可以利用它实现 Web服务,做类似PHP的事。

打开 https://nodejs.org/ 点击绿色的 INSTALL 按钮下载安装 node。

2.1 命令行


Windows 中可按 <kbd>徽标键</kbd>(alt键左边)+ R 打开输入 cmd + Enter 打开命令行。

2.2 终端(Mac)


打开 Launchpad(像火箭一样的图标),在屏幕上方搜索框中输入 终端 + Enter 打开终端。

2.3 查看 node 版本号


在终端/命令行中输入 node -v 检测node是否安装成功,安装成功会显示出node 的版本号。

2.4 跳转目录


终端/命令行 中可使用 cd 目录名 跳转至指定目录,Mac 中还可以使用 ls 查看当前目录下的文件列表。

2.5 Windows


Windows 下可使用如下命令跳转至指定目录:

1
2
3
4
5
6
// 跳转至 C 盘根目录
cd c:\
// 跳转至当前目录的 demo 文件夹
cd demo
// 跳转至上一级
cd ..

2.6 Mac


Mac中建议只在 Documents目录下进行文件操作。

1
2
3
4
5
6
7
8
9
10
11
12
// 跳转至文档目录
cd /Users/你的用户名/Documents/
// 或第一次打开终端时直接输入
cd Documents
// 查看目录下文件列表
ls
// 创建文件夹
mkdir demo
// 跳转至当前目录下的 demo 文件夹
cd demo
// 跳转至上级目录
cd ..

2.7 退出运行状态


如果你在命令行中启动了一些一直运行的命令,你的命令行会进入“运行”状态,此时你不可以在命令行进行其他操作。可通过 Ctrl + C 停止 gulp。(Mac 中使用 control + C

后面的章节中如果代码中存在 gulp.watch 并在命令行运行了 gulp 则需要使用 Ctrl + C 退出任务。

2.8 npm 模块管理器


如果你了解 npm 则跳过此章节

若你不了解npm 请阅读 npm模块管理器

2.9 安装 gulp


npm 是 node 的包管理工具,可以利用它安装 gulp 所需的包。(在安装 node 时已经自动安装了 npm

在命令行输入

1
npm install -g gulp

若一直没安装成功,请使用 cnpm 安装(npm的国内加速镜像)

意思是:使用 npm 安装全局性的(-g) gulp 包。

如果你安装失败,请输入sudo npm install -g gulp使用管理员权限安装。(可能会要求输入密码)

安装时请注意命令行的提示信息,安装完成后可在命令行输入 gulp -v 以确认安装成功。

至此,我们完成了准备工作。接着让 gulp开始帮我们干活吧!

三、使用 gulp 压缩 JS


压缩js 代码可降低 js 文件大小,提高页面打开速度。在不利用 gulp 时我们需要通过各种工具手动完成压缩工作。

所有的 gulp 代码编写都可以看做是将规律转化为代码的过程。

  • 规律

找到 js/ 目录下的所有js 文件,压缩它们,将压缩后的文件存放在 dist/js/ 目录下。

  • gulp 代码

gulp 的所有配置代码都写在 gulpfile.js 文件。

3.1 新建一个 gulpfile.js 文件


1
2
chapter2
└── gulpfile.js

3.2 在 gulpfile.js 中编写代码


1
2
// 获取 gulp
var gulp = require('gulp')

require() 是 node (CommonJS)中获取模块的语法。

在 gulp 中你只需要理解 require() 可以获取模块。


3.3 获取 gulp-uglify 组件


1
2
// 获取 uglify 模块(用于压缩 JS)
var uglify = require('gulp-uglify')

3.4 创建压缩任务


1
2
3
4
5
6
7
8
9
10
// 压缩 js 文件
// 在命令行使用 gulp script 启动此任务
gulp.task('script', function() {
// 1. 找到文件
gulp.src('js/*.js')
// 2. 压缩文件
.pipe(uglify())
// 3. 另存压缩后的文件
.pipe(gulp.dest('dist/js'))
})
  • gulp.task(name, fn) - 定义任务,第一个参数是任务名,第二个参数是任务内容。
  • gulp.src(path) - 选择文件,传入参数是文件路径。
  • gulp.dest(path) - 输出文件
  • gulp.pipe() - 管道,你可以暂时将 pipe 理解为将操作加入执行队列

参考:gulp API文档


3.5 跳转至 gulpfile.js 所在目录


打开命令行使用 cd 命令跳转至 gulpfile.js 文件所在目录。

例如我的 gulpfile.js 文件保存在 C:\gulp-book\demo\chapter2\gulpfile.js

那么就需要在命令行输入

1
cd C:\gulp-book\demo\chapter2

Mac 用户可使用 cd Documents/gulp-book/demo/chapter2/ 跳转


3.6 使用命令行运行 script 任务


在控制台输入 gulp 任务名 可运行任务,此处我们输入 gulp script 回车。

注意:输入 gulp script 后命令行将会提示错误信息

1
2
3
4
5
6
// 在命令行输入
gulp script

Error: Cannot find module 'gulp-uglify'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)

Cannot find module 'gulp-uglify' 没有找到 gulp-uglify 模块。


3.7 安装 gulp-uglify 模块


因为我们并没有安装 gulp-uglify 模块到本地,所以找不到此模块。

使用 npm 安装 gulp-uglify 到本地

1
npm install gulp-uglify

安装成功后你会看到如下信息:

1
2
3
4
5
6
7
gulp-uglify@1.1.0 node_modules/gulp-uglify
├── deepmerge@0.2.7
├── uglify-js@2.4.16 (uglify-to-browserify@1.0.2, async@0.2.10, source-map@0.1.34, optimist@0.3.7)
├── vinyl-sourcemaps-apply@0.1.4 (source-map@0.1.43)
├── through2@0.6.3 (xtend@4.0.0, readable-stream@1.0.33)
└── gulp-util@3.0.4 (array-differ@1.0.0, beeper@1.0.0, array-uniq@1.0.2, object-assign@2.0.0, lodash._reinterpolate@3.0.0, lodash._reescape@3.0.0, lodash._reevaluate@3.0.0, replace-ext@0.0.1, minimist@1.1.1, chalk@1.0.0, lodash.template@3.3.2, vinyl@0.4.6, multipipe@0.1.2, dateformat@1.0.11)
chapter2 $

在你的文件夹中会新增一个 node_modules 文件夹,这里面存放着 npm 安装的模块。

目录结构:

1
2
3
├── gulpfile.js
└── node_modules
└── gulp-uglify

接着输入 gulp script 执行任务

1
2
3
4
gulp script
[13:34:57] Using gulpfile ~/Documents/code/gulp-book/demo/chapter2/gulpfile.js
[13:34:57] Starting 'script'...
[13:34:57] Finished 'script' after 6.13 ms

3.8 编写 js 文件


我们发现 gulp 没有进行任何压缩操作。因为没有js这个目录,也没有 js 目录下的 .js 后缀文件。

创建 a.js 文件,并编写如下内容

1
2
3
4
5
6
// a.js
function demo (msg) {
alert('--------\r\n' + msg + '\r\n--------')
}

demo('Hi')

目录结构:

1
2
3
4
5
├── gulpfile.js
├── js
│ └── a.js
└── node_modules
└── gulp-uglify

接着在命令行输入 gulp script 执行任务

gulp 会在命令行当前目录下创建 dist/js/ 文件夹,并创建压缩后的 a.js 文件。

目录结构:

1
2
3
4
5
6
7
8
├── gulpfile.js
├── js
│ └── a.js
├── dist
│ └── js
│ └── a.js
└── node_modules
└── gulp-uglify

dist/js/a.js

1
function demo(n){alert("--------\r\n"+n+"\r\n--------")}demo("Hi");


3.9 检测代码修改自动执行任务


js/a.js一旦有修改 就必须重新在命令行输入 gulp script ,这很麻烦。

可以使用 gulp.watch(src, fn) 检测指定目录下文件的修改后执行任务。

gulpfile.js 中编写如下代码:

1
2
// 监听文件修改,当文件被修改则执行 script 任务
gulp.watch('js/*.js', ['script']);

但是没有命令可以运行 gulp.watch(),需要将 gulp.watch() 包含在一个任务中。

1
2
3
4
5
// 在命令行使用 gulp auto 启动此任务
gulp.task('auto', function () {
// 监听文件修改,当文件被修改则执行 script 任务
gulp.watch('js/*.js', ['script'])
})

接着在命令行输入 gulp auto,自动监听 js/*.js 文件的修改后压缩js。

1
2
3
4
$gulp auto
[21:09:45] Using gulpfile ~/Documents/code/gulp-book/demo/chapter2/gulpfile.js
[21:09:45] Starting 'auto'...
[21:09:45] Finished 'auto' after 9.19 ms

此时修改 js/a.js 中的代码并保存。命令行将会出现提示,表示检测到文件修改并压缩文件。

1
2
[21:11:01] Starting 'script'...
[21:11:01] Finished 'script' after 2.85 ms

至此,我们完成了 gulp 压缩 js 文件的自动化代码编写。

注意:使用 gulp.watch 后你的命令行会进入“运行”状态,此时你不可以在命令行进行其他操作。可通过 Ctrl + C 停止 gulp。

Mac 下使用 control + C 停止 gulp

3.10 使用 gulp.task(‘default’, fn) 定义默认任务


增加如下代码

1
gulp.task('default', ['script', 'auto']);

此时你可以在命令行直接输入 gulp +回车,运行 scriptauto 任务。

最终代码如下:

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
// 获取 gulp
var gulp = require('gulp')

// 获取 uglify 模块(用于压缩 JS)
var uglify = require('gulp-uglify')

// 压缩 js 文件
// 在命令行使用 gulp script 启动此任务
gulp.task('script', function() {
// 1. 找到文件
gulp.src('js/*.js')
// 2. 压缩文件
.pipe(uglify())
// 3. 另存压缩后的文件
.pipe(gulp.dest('dist/js'))
})

// 在命令行使用 gulp auto 启动此任务
gulp.task('auto', function () {
// 监听文件修改,当文件被修改则执行 script 任务
gulp.watch('js/*.js', ['script'])
})


// 使用 gulp.task('default') 定义默认任务
// 在命令行使用 gulp 启动 script 任务和 auto 任务
gulp.task('default', ['script', 'auto'])

去除注释后,你会发现只需要 11 行代码就可以让 gulp 自动监听 js 文件的修改后压缩代码。但是还有还有一些性能问题和缺少容错性,将在后面的章节详细说明。

你可以访问 gulp-uglify 以查看更多用法。

四、使用 gulp 压缩 CSS


压缩 css 代码可降低 css 文件大小,提高页面打开速度。

我们接着将规律转换为 gulp 代码

  • 规律

找到 css/ 目录下的所有 css 文件,压缩它们,将压缩后的文件存放在 dist/css/ 目录下。

4.1 安装 gulp-minify-css模块


提示:你需要使用命令行的 cd 切换到对应目录后进行安装操作。

在命令行输入

1
npm install gulp-minify-css

安装成功后你会看到如下信息:(安装时间可能会比较长)

1
2
3
4
5
6
7
gulp-minify-css@1.0.0 node_modules/gulp-minify-css
├── object-assign@2.0.0
├── vinyl-sourcemaps-apply@0.1.4 (source-map@0.1.43)
├── clean-css@3.1.8 (commander@2.6.0, source-map@0.1.43)
├── through2@0.6.3 (xtend@4.0.0, readable-stream@1.0.33)
├── vinyl-bufferstream@1.0.1 (bufferstreams@1.0.1)
└── gulp-util@3.0.4 (array-differ@1.0.0, beeper@1.0.0, array-uniq@1.0.2, lodash._reescape@3.0.0, lodash._reinterpolate@3.0.0, lodash._reevaluate@3.0.0, replace-ext@0.0.1, minimist@1.1.1, multipipe@0.1.2, vinyl@0.4.6, chalk@1.0.0, lodash.template@3.3.2, dateformat@1.0.11)

4.2 参照 [使用 gulp 压缩 JS]创建 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
// 获取 gulp
var gulp = require('gulp')

// 获取 minify-css 模块(用于压缩 CSS)
var minifyCSS = require('gulp-minify-css')

// 压缩 css 文件
// 在命令行使用 gulp css 启动此任务
gulp.task('css', function () {
// 1. 找到文件
gulp.src('css/*.css')
// 2. 压缩文件
.pipe(minifyCSS())
// 3. 另存为压缩文件
.pipe(gulp.dest('dist/css'))
})

// 在命令行使用 gulp auto 启动此任务
gulp.task('auto', function () {
// 监听文件修改,当文件被修改则执行 css 任务
gulp.watch('css/*.css', ['css'])
});

// 使用 gulp.task('default') 定义默认任务
// 在命令行使用 gulp 启动 css 任务和 auto 任务
gulp.task('default', ['css', 'auto'])

你可以访问 gulp-minify-css 以查看更多用法。


4.3 创建 css 文件


gulpfile.js 对应目录创建 css 文件夹,并在 css/ 目录下创建 a.css 文件。

1
2
3
4
/* a.css */
body a{
color:pink;
}

4.4 运行 gulp 查看效果


在命令行输入 gulp +回车

你将看到命令行出现如下提示

1
2
3
4
5
6
7
8
gulp
[17:01:19] Using gulpfile ~/Documents/code/gulp-book/demo/chapter3/gulpfile.js
[17:01:19] Starting 'css'...
[17:01:19] Finished 'css' after 6.21 ms
[17:01:19] Starting 'auto'...
[17:01:19] Finished 'auto' after 5.42 ms
[17:01:19] Starting 'default'...
[17:01:19] Finished 'default' after 5.71 μs

gulp 会创建 dist/css 目录,并创建 a.css 文件,此文件存放压缩后的 css 代码。
dist/css/a.css

五、使用 gulp 压缩图片


压缩 图片文件可降低文件大小,提高图片加载速度。

找到规律转换为 gulp 代码

  • 规律

找到 images/ 目录下的所有文件,压缩它们,将压缩后的文件存放在 dist/images/ 目录下。

5.1 安装 gulp-imagemin 模块


提示:你需要使用命令行的 cd 切换至对应目录再进行安装操作和 gulp 启动操作。

在命令行输入

1
npm install gulp-imagemin

安装成功后你会看到如下信息:(安装时间可能会比较长)

1
2
3
4
5
6
7
gulp-imagemin@2.2.1 node_modules/gulp-imagemin
├── object-assign@2.0.0
├── pretty-bytes@1.0.3 (get-stdin@4.0.1)
├── chalk@1.0.0 (escape-string-regexp@1.0.3, ansi-styles@2.0.1, supports-color@1.3.1, has-ansi@1.0.3, strip-ansi@2.0.1)
├── through2-concurrent@0.3.1 (through2@0.6.3)
├── gulp-util@3.0.4 (array-differ@1.0.0, beeper@1.0.0, array-uniq@1.0.2, lodash._reevaluate@3.0.0, lodash._reescape@3.0.0, lodash._reinterpolate@3.0.0, replace-ext@0.0.1, minimist@1.1.1, vinyl@0.4.6, through2@0.6.3, multipipe@0.1.2, lodash.template@3.3.2, dateformat@1.0.11)
└── imagemin@3.1.0 (get-stdin@3.0.2, optional@0.1.3, vinyl@0.4.6, through2@0.6.3, stream-combiner@0.2.1, concat-stream@1.4.7, meow@2.1.0, vinyl-fs@0.3.13, imagemin-svgo@4.1.2, imagemin-optipng@4.2.0, imagemin-jpegtran@4.1.0, imagemin-pngquant@4.0.0, imagemin-gifsicle@4.1.0)

5.2 创建 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
// 获取 gulp
var gulp = require('gulp');

// 获取 gulp-imagemin 模块
var imagemin = require('gulp-imagemin')

// 压缩图片任务
// 在命令行输入 gulp images 启动此任务
gulp.task('images', function () {
// 1. 找到图片
gulp.src('images/*.*')
// 2. 压缩图片
.pipe(imagemin({
progressive: true
}))
// 3. 另存图片
.pipe(gulp.dest('dist/images'))
});

// 在命令行使用 gulp auto 启动此任务
gulp.task('auto', function () {
// 监听文件修改,当文件被修改则执行 images 任务
gulp.watch('images/*.*)', ['images'])
});

// 使用 gulp.task('default') 定义默认任务
// 在命令行使用 gulp 启动 images 任务和 auto 任务
gulp.task('default', ['images', 'auto'])

你可以访问 gulp-imagemin 以查看更多用法。


5.3 在 images/ 目录下存放图片


gulpfile.js 对应目录创建 images 文件夹,并在 images/ 目录下存放图片。

5.4 运行 gulp 查看效果


在命令行输入 gulp +回车

你将看到命令行出现如下提示

1
2
3
4
5
6
7
8
9
gulp
[18:10:42] Using gulpfile ~/Documents/code/gulp-book/demo/chapter4/gulpfile.js
[18:10:42] Starting 'images'...
[18:10:42] Finished 'images' after 5.72 ms
[18:10:42] Starting 'auto'...
[18:10:42] Finished 'auto' after 6.39 ms
[18:10:42] Starting 'default'...
[18:10:42] Finished 'default' after 5.91 μs
[18:10:42] gulp-imagemin: Minified 3 images (saved 25.83 kB - 5.2%)

使用 gulp 编译 LESS

Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量、混合(mixin)、函数等功能,让 CSS 更易维护。

安装

1
npm install gulp-less

基本用法

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
// 获取 gulp
var gulp = require('gulp')
// 获取 gulp-less 模块
var less = require('gulp-less')

// 编译less
// 在命令行输入 gulp less 启动此任务
gulp.task('less', function () {
// 1. 找到 less 文件
gulp.src('less/**.less')
// 2. 编译为css
.pipe(less())
// 3. 另存文件
.pipe(gulp.dest('dist/css'))
});

// 在命令行使用 gulp auto 启动此任务
gulp.task('auto', function () {
// 监听文件修改,当文件被修改则执行 less 任务
gulp.watch('less/**.less', ['less'])
})

// 使用 gulp.task('default') 定义默认任务
// 在命令行使用 gulp 启动 less 任务和 auto 任务
gulp.task('default', ['less', 'auto'])

你可以访问 gulp-less 以查看更多用法。

LESS 代码和编译后的CSS代码

less/a.less

1
2
3
4
5
.less{
a{
color:pink;
}
}

less/import.less

1
2
3
4
5
6
@import "a.less";
.import{
a{
color:red;
}
}

less/a.css

1
2
3
.less a {
color: pink;
}

less/import.css

1
2
3
4
5
6
.less a {
color: pink;
}
.import a{
color: red;
}

六、使用 gulp 编译 Sass


无论是 node-sass 还是 ruby-sass 使用 npm 安装都非常的慢,甚至会装不上。及其不利于团队协作。建议使用 less 作为 css 预处理器。
如果因为 less 不支持自定义函数选择用 sass 可以使用 less-plugin-functions 让 less 支持自定义函数。

6.1 gulp-sass


本章使用的是 ruby-sass 如果你不方便安装 ruby 或编译速度慢,建议使用 gulp-sass

Sass 是一种 CSS 的开发工具,提供了许多便利的写法,大大节省了开发者的时间,使得 CSS 的开发,变得简单和可维护。

本章使用 ruby-sass 编译 css,若你没有安装 ruby 和 sass 请移步 使用ruby.taobao安装 Sass

6.2 安装


1
npm install gulp-ruby-sass

6.3 基本用法


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
// 获取 gulp
var gulp = require('gulp')
// 获取 gulp-ruby-sass 模块
var sass = require('gulp-ruby-sass')

// 编译sass
// 在命令行输入 gulp sass 启动此任务
gulp.task('sass', function() {
return sass('sass/')
.on('error', function (err) {
console.error('Error!', err.message);
})
.pipe(gulp.dest('dist/css'))
});


// 在命令行使用 gulp auto 启动此任务
gulp.task('auto', function () {
// 监听文件修改,当文件被修改则执行 images 任务
gulp.watch('sass/**/*.scss', ['sass'])
});

// 使用 gulp.task('default') 定义默认任务
// 在命令行使用 gulp 启动 sass 任务和 auto 任务
gulp.task('default', ['sass', 'auto'])

Sass 代码和编译后的 CSS 代码

sass/a.scss

1
2
3
4
5
.sass{
a{
color:pink;
}
}

sass/import.scss

1
2
3
4
5
6
@import "a.scss";
.import{
a{
color:red;
}
}

sass/a.css

1
2
3
.sass a {
color: pink;
}

sass/import.css

1
2
3
4
5
6
.sass a {
color: pink;
}
.import a{
color: red;
}

七、使用 gulp 构建一个项目


本章将介绍

并将之前所有章节的内容组合起来编写一个前端项目所需的 gulp 代码。

若你不了解npm 请务必阅读 npm模块管理器

7.1 package.json


如果你熟悉 npm 则可以利用 package.json 保存所有 npm install --save-dev gulp-xxx 模块依赖和模块版本。

在命令行输入

1
npm init

会依次要求补全项目信息,不清楚的可以直接回车跳过

1
2
3
4
5
6
7
8
name: (gulp-demo) 
version: (1.0.0)
description:
entry point: (index.js)
test command:
...
...
Is this ok? (yes)

最终会在当前目录中创建 package.json 文件并生成类似如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"name": "gulp-demo",
"version": "0.0.0",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://github.com/nimojs/gulp-demo.git"
},
"keywords": [
"gulp",
],
"author": "nimojs <nimo.jser@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/nimojs/gulp-demo/issues"
},
"homepage": "https://github.com/nimojs/gulp-demo"
}

7.2 安装依赖


安装 gulp 到项目(防止全局 gulp 升级后与此项目 gulpfile.js 代码不兼容)

1
npm install gulp --save-dev

此时打开 package.json 会发现多了如下代码

1
2
3
"devDependencies": {
"gulp": "^3.8.11"
}

声明此项目的开发依赖 gulp

接着安装其他依赖:

安装模块较多,请耐心等待,若一直安装失败可使用npm.taobao.org

1
npm install gulp-uglify gulp-watch-path stream-combiner2 gulp-sourcemaps gulp-minify-css gulp-autoprefixer gulp-less gulp-ruby-sass gulp-imagemin gulp-util --save-dev

此时,package.json 将会更新

1
2
3
4
5
6
7
8
9
10
11
12
13
"devDependencies": {
"colors": "^1.0.3",
"gulp": "^3.8.11",
"gulp-autoprefixer": "^2.1.0",
"gulp-imagemin": "^2.2.1",
"gulp-less": "^3.0.2",
"gulp-minify-css": "^1.0.0",
"gulp-ruby-sass": "^1.0.1",
"gulp-sourcemaps": "^1.5.1",
"gulp-uglify": "^1.1.0",
"gulp-watch-path": "^0.0.7",
"stream-combiner2": "^1.0.2"
}

当你将这份 gulpfile.js 配置分享给你的朋友时,就不需要将 node_modules/ 发送给他,他只需在命令行输入

1
npm install

就可以检测 package.json 中的 devDependencies 并安装所有依赖。

7.3 设计目录结构


我们将文件分为2类,一类是源码,一类是编译压缩后的版本。文件夹分别为 srcdist。(注意区分 dist 和 ·dest 的区别)

1
2
3
└── src/

└── dist/

dist/ 目录下的文件都是根据 src/ 下所有源码文件构建而成。

src/ 下创建前端资源对应的的文件夹

1
2
3
4
5
6
7
8
└── src/
├── less/ *.less 文件
├── sass/ *.scss *.sass 文件
├── css/ *.css 文件
├── js/ *.js 文件
├── fonts/ 字体文件
└── images/ 图片
└── dist/

7.4 让命令行输出的文字带颜色


gulp 自带的输出都带时间和颜色,这样很容易识别。我们利用 gulp-util 实现同样的效果。

1
2
3
4
5
6
7
8
var gulp = require('gulp')
var gutil = require('gulp-util')

gulp.task('default', function () {
gutil.log('message')
gutil.log(gutil.colors.red('error'))
gutil.log(gutil.colors.green('message:') + "some")
})

使用 gulp 启动默认任务以测试
gulp-util

7.5 配置 JS 任务

7.5.1 gulp-uglify

检测src/js/目录下的 js 文件修改后,压缩 js/ 中所有 js 文件并输出到 dist/js/

1
2
3
4
5
6
7
8
9
10
11
var uglify = require('gulp-uglify')

gulp.task('uglifyjs', function () {
gulp.src('src/js/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('dist/js'))
})

gulp.task('default', function () {
gulp.watch('src/js/**/*.js', ['uglifyjs'])
})

src/js/**/*.js 是 glob 语法。百度百科:glob模式node-glob

在命令行输入 gulp 后会出现如下消息,表示已经启动。

1
2
3
[20:39:50] Using gulpfile ~/Documents/code/gulp-book/demo/chapter7/gulpfile.js
[20:39:50] Starting 'default'...
[20:39:50] Finished 'default' after 13 ms

此时编辑 src/js/log.js 文件并保存,命令行会出现如下消息,表示检测到 src/js/**/*.js 文件修改后重新编译所有 js。

1
2
[20:39:52] Starting 'js'...
[20:39:52] Finished 'js' after 14 ms

7.5.2gulp-watch-path


此配置有个性能问题,当 gulp.watch 检测到 src/js/ 目录下的js文件有修改时会将所有文件全部编译。实际上我们只需要重新编译被修改的文件。

简单介绍 gulp.watch 第二个参数为 function 时的用法。

1
2
3
4
5
6
7
8
9
10
11
12
gulp.watch('src/js/**/*.js', function (event) {
console.log(event);
/*
当修改 src/js/log.js 文件时
event {
// 发生改变的类型,不管是添加,改变或是删除
type: 'changed',
// 触发事件的文件路径
path: '/Users/nimojs/Documents/code/gulp-book/demo/chapter7/src/js/log.js'
}
*/
})

我们可以利用 event 给到的信息,检测到某个 js 文件被修改时,只编写当前修改的 js 文件。

可以利用 gulp-watch-path 配合 event 获取编译路径和输出路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var watchPath = require('gulp-watch-path')

gulp.task('watchjs', function () {
gulp.watch('src/js/**/*.js', function (event) {
var paths = watchPath(event, 'src/', 'dist/')
/*
paths
{ srcPath: 'src/js/log.js',
srcDir: 'src/js/',
distPath: 'dist/js/log.js',
distDir: 'dist/js/',
srcFilename: 'log.js',
distFilename: 'log.js' }
*/
gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath)
gutil.log('Dist ' + paths.distPath)

gulp.src(paths.srcPath)
.pipe(uglify())
.pipe(gulp.dest(paths.distDir))
})
})

gulp.task('default', ['watchjs'])

use-gulp-watch-path 完整代码

7.5.3 watchPath(event, search, replace, distExt)


参数 说明
event gulp.watch 回调函数的 event
search 需要被替换的起始字符串
replace 第三个参数是新的的字符串
distExt 扩展名(非必填)

此时编辑 src/js/log.js 文件并保存,命令行会出现消息,表示检测到 src/js/log.js 文件修改后只重新编译 log.js

1
2
[21:47:25] changed src/js/log.js
[21:47:25] Dist dist/js/log.js

你可以访问 gulp-watch-path 了解更多。

7.5.4 stream-combiner2


编辑 log.js 文件时,如果文件中有 js 语法错误时,gulp 会终止运行并报错。

当 log.js 缺少 )

1
log('gulp-book'

并保存文件时出现如下错误,但是错误信息不全面。而且还会让 gulp 停止运行。

1
2
3
4
5
6
7
8
9
10
events.js:85
throw er; // Unhandled 'error' event
^
Error
at new JS_Parse_Error (/Users/nimojs/Documents/code/gulp-book/demo/chapter7/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:189:18)
...
...
js_error (/Users/nimojs/Documents/code/gulp-book/demo/chapter7/node_modules/gulp-
-book/demo/chapter7/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:1165:20)
at maybe_unary (/Users/nimojs/Documents/code/gulp-book/demo/chapter7/node_modules/gulp-uglify/node_modules/uglify-js/lib/parse.js:1328:19)

应对这种情况,我们可以使用 Combining streams to handle errors 文档中推荐的 stream-combiner2 捕获错误信息。

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
var handleError = function (err) {
var colors = gutil.colors;
console.log('\n')
gutil.log(colors.red('Error!'))
gutil.log('fileName: ' + colors.red(err.fileName))
gutil.log('lineNumber: ' + colors.red(err.lineNumber))
gutil.log('message: ' + err.message)
gutil.log('plugin: ' + colors.yellow(err.plugin))
}
var combiner = require('stream-combiner2')

gulp.task('watchjs', function () {
gulp.watch('src/js/**/*.js', function (event) {
var paths = watchPath(event, 'src/', 'dist/')
/*
paths
{ srcPath: 'src/js/log.js',
srcDir: 'src/js/',
distPath: 'dist/js/log.js',
distDir: 'dist/js/',
srcFilename: 'log.js',
distFilename: 'log.js' }
*/
gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath)
gutil.log('Dist ' + paths.distPath)

var combined = combiner.obj([
gulp.src(paths.srcPath),
uglify(),
gulp.dest(paths.distDir)
])

combined.on('error', handleError)
})
})

此时当编译错误的语法时,命令行会出现错误提示。而且不会让 gulp 停止运行。

1
2
3
4
5
6
7
8
changed:src/js/log.js
dist:dist/js/log.js
--------------
Error!
fileName: /Users/nimojs/Documents/code/gulp-book/demo/chapter7/src/js/log.js
lineNumber: 7
message: /Users/nimojs/Documents/code/gulp-book/demo/chapter7/src/js/log.js: Unexpected token eof «undefined», expected punc «,»
plugin: gulp-uglify

7.5.5 gulp-sourcemaps


JS 压缩前和压缩后比较

1
2
3
4
5
6
7
8
9
10
11
// 压缩前
var log = function (msg) {
console.log('--------');
console.log(msg)
console.log('--------');
}
log({a:1})
log('gulp-book')

// 压缩后
var log=function(o){console.log("--------"),console.log(o),console.log("--------")};log({a:1}),log("gulp-book");

压缩后的代码不存在换行符和空白符,导致出错后很难调试,好在我们可以使用 sourcemap 帮助调试

1
2
3
4
5
6
7
8
9
10
var sourcemaps = require('gulp-sourcemaps')
// ...
var combined = combiner.obj([
gulp.src(paths.srcPath),
sourcemaps.init(),
uglify(),
sourcemaps.write('./'),
gulp.dest(paths.distDir)
])
// ...

此时 dist/js/ 中也会生成对应的 .map 文件,以便使用 Chrome 控制台调试代码 在线文件示例:src/js/


至此,我们完成了检测文件修改后压缩 JS 的 gulp 任务配置。

有时我们也需要一次编译所有 js 文件。可以配置 uglifyjs 任务。

1
2
3
4
5
6
7
8
9
10
gulp.task('uglifyjs', function () {
var combined = combiner.obj([
gulp.src('src/js/**/*.js'),
sourcemaps.init(),
uglify(),
sourcemaps.write('./'),
gulp.dest('dist/js/')
])
combined.on('error', handleError)
})

在命令行输入 gulp uglifyjs 以压缩 src/js/ 下的所有 js 文件。

7.6 配置 CSS 任务


有时我们不想使用 LESS 或 SASS而是直接编写 CSS,但我们需要压缩 CSS 以提高页面加载速度。

7.6.1 gulp-minify-css


按照本章中压缩 JS 的方式,先编写 watchcss 任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var minifycss = require('gulp-minify-css')

gulp.task('watchcss', function () {
gulp.watch('src/css/**/*.css', function (event) {
var paths = watchPath(event, 'src/', 'dist/')

gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath)
gutil.log('Dist ' + paths.distPath)

gulp.src(paths.srcPath)
.pipe(sourcemaps.init())
.pipe(minifycss())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(paths.distDir))
})
})

gulp.task('default', ['watchjs','watchcss'])

7.6.2 gulp-autoprefixer

autoprefixer 解析 CSS 文件并且添加浏览器前缀到CSS规则里。
通过示例帮助理解

autoprefixer 处理前:

1
2
3
.demo {
display:flex;
}

autoprefixer 处理后:

1
2
3
4
5
.demo {
display:-webkit-flex;
display:-ms-flexbox;
display:flex;
}

你只需要关心编写标准语法的 css,autoprefixer 会自动补全。

在 watchcss 任务中加入 autoprefixer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
gulp.task('watchcss', function () {
gulp.watch('src/css/**/*.css', function (event) {
var paths = watchPath(event, 'src/', 'dist/')

gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath)
gutil.log('Dist ' + paths.distPath)

gulp.src(paths.srcPath)
.pipe(sourcemaps.init())
.pipe(autoprefixer({
browsers: 'last 2 versions'
}))
.pipe(minifycss())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(paths.distDir))
})
})

更多 autoprefixer 参数请查看 gulp-autoprefixer

有时我们也需要一次编译所有 css 文件。可以配置 minifyss 任务。

1
2
3
4
5
6
7
8
9
10
gulp.task('minifycss', function () {
gulp.src('src/css/**/*.css')
.pipe(sourcemaps.init())
.pipe(autoprefixer({
browsers: 'last 2 versions'
}))
.pipe(minifycss())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('dist/css/'))
})

在命令行输入 gulp minifyss 以压缩 src/css/ 下的所有 .css 文件并复制到 dist/css 目录下

7.7 配置 Less 任务


  • 参考配置 JavaScript 任务的方式配置 less 任务
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
var less = require('gulp-less')

gulp.task('watchless', function () {
gulp.watch('src/less/**/*.less', function (event) {
var paths = watchPath(event, 'src/less/', 'dist/css/')

gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath)
gutil.log('Dist ' + paths.distPath)
var combined = combiner.obj([
gulp.src(paths.srcPath),
sourcemaps.init(),
autoprefixer({
browsers: 'last 2 versions'
}),
less(),
minifycss(),
sourcemaps.write('./'),
gulp.dest(paths.distDir)
])
combined.on('error', handleError)
})
})

gulp.task('lesscss', function () {
var combined = combiner.obj([
gulp.src('src/less/**/*.less'),
sourcemaps.init(),
autoprefixer({
browsers: 'last 2 versions'
}),
less(),
minifycss(),
sourcemaps.write('./'),
gulp.dest('dist/css/')
])
combined.on('error', handleError)
})

gulp.task('default', ['watchjs', 'watchcss', 'watchless'])

7.8 配置 Sass 任务


参考配置 JavaScript 任务的方式配置 Sass 任务

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
gulp.task('watchsass',function () {
gulp.watch('src/sass/**/*', function (event) {
var paths = watchPath(event, 'src/sass/', 'dist/css/')

gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath)
gutil.log('Dist ' + paths.distPath)
sass(paths.srcPath)
.on('error', function (err) {
console.error('Error!', err.message);
})
.pipe(sourcemaps.init())
.pipe(minifycss())
.pipe(autoprefixer({
browsers: 'last 2 versions'
}))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(paths.distDir))
})
})

gulp.task('sasscss', function () {
sass('src/sass/')
.on('error', function (err) {
console.error('Error!', err.message);
})
.pipe(sourcemaps.init())
.pipe(minifycss())
.pipe(autoprefixer({
browsers: 'last 2 versions'
}))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('dist/css'))
})

gulp.task('default', ['watchjs', 'watchcss', 'watchless', 'watchsass', 'watchsass'])

7.9 配置 image 任务


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var imagemin = require('gulp-imagemin')

gulp.task('watchimage', function () {
gulp.watch('src/images/**/*', function (event) {
var paths = watchPath(event,'src/','dist/')

gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath)
gutil.log('Dist ' + paths.distPath)

gulp.src(paths.srcPath)
.pipe(imagemin({
progressive: true
}))
.pipe(gulp.dest(paths.distDir))
})
})

gulp.task('image', function () {
gulp.src('src/images/**/*')
.pipe(imagemin({
progressive: true
}))
.pipe(gulp.dest('dist/images'))
})

7.10 配置文件复制任务


复制 src/fonts/ 文件到 dist/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
gulp.task('watchcopy', function () {
gulp.watch('src/fonts/**/*', function (event) {
var paths = watchPath(event)

gutil.log(gutil.colors.green(event.type) + ' ' + paths.srcPath)
gutil.log('Dist ' + paths.distPath)

gulp.src(paths.srcPath)
.pipe(gulp.dest(paths.distDir))
})
})

gulp.task('copy', function () {
gulp.src('src/fonts/**/*')
.pipe(gulp.dest('dist/fonts/'))
})

gulp.task('default', ['watchjs', 'watchcss', 'watchless', 'watchsass', 'watchimage', 'watchcopy'])
支持一下
扫一扫,支持poetries