在日常开发中,手动去做一些代码压缩,做一些流程化的动作其实很繁琐,现在我们可以通过 gulp 来改进我们的工作流,让我们的开发体验得到提升,并且可以直接使用 less、sass 等预编译样式语法,在工作流中做编译转换。

安装

  • 安装淘宝 npm 镜像:

    sudo npm install -g cnpm --registry=https://registry.npm.taobao.org

    之后可将npm修改为cnpm

  • 首先我们要全局安装一遍:

    sudo npm install gulp -g

    • sudo 是以管理员身份执行命令,一般会要求输入电脑密码
    • npm 是安装 node 模块的工具,执行 install 命令
    • -g 表示在全局环境安装,以便任何项目都能使用它
    • 最后,gulp 是将要安装的 node 模块的名字

  • 验证是否正确安装

    输入gulp -v验证 gulp 正确安装。

  • 到项目目录下安装一遍

    命令行输入cd 当前项目路径,到达当前项目目录后,

    执行npm install gulp --save-dev

    使用—-save-dev来更新 package.json 文件,更新 devDependencies 值,以表明项目需要依赖 gulp。

安装 gulp 插件

我们将要使用 Gulp 插件来完成我们以下任务:

插件名称 插件说明
gulp-htmlmin 压缩 html
gulp-ruby-sass sass 的编译
gulp-autoprefixer 添加 CSS 前缀
gulp-clean-css 压缩 css
gulp-concat 合并文件
gulp-uglify 压缩 js
gulp-imagemin 压缩图片
gulp-ng-annotate 添加 angular 依赖注入
gulp-strip-debug 去掉控制器 log 等语句
gulp-ngmin 压缩 angularJs
gulp-rename 重命名文件
gulp-livereload 自动刷新页面
gulp-cache 图片缓存
gulp-notify 更改提醒
del 清除文件

安装以上所有插件需要运行如下命令:

npm install gulp-htmlmin gulp-ruby-sass gulp-autoprefixer gulp-clean-css  gulp-concat gulp-uglify gulp-imagemin gulp-ng-annotate gulp-strip-debug gulp-ngmin gulp-rename gulp-livereload  gulp-cache gulp-notify  del  --save-dev

加载插件

接着在项目目录下创建一个 gulpfile.js 文件,用于配置加载插件:

引入插件:

var gulp = require("gulp"),
  htmlmin = require("gulp-htmlmin"),
  sass = require("gulp-ruby-sass"),
  autoprefixer = require("gulp-autoprefixer"),
  minifycss = require("gulp-clean-css"),
  jshint = require("gulp-jshint"),
  uglify = require("gulp-uglify"),
  imagemin = require("gulp-imagemin"),
  rename = require("gulp-rename"),
  concat = require("gulp-concat"),
  notify = require("gulp-notify"),
  cache = require("gulp-cache"),
  livereload = require("gulp-livereload"),
  del = require("del"),
  ngAnnotate = require("gulp-ng-annotate"),
  stripDebug = require("gulp-strip-debug"),
  ngmin = require("gulp-ngmin");

建立任务

  • 编译 sass、自动添加 css 前缀和压缩

以下代码的主要目的:首先我们编译 sass,添加前缀,保存到我们指定的目录下面,还没结束,我们还要压缩,给文件添加.min 后缀再输出压缩文件到指定目录,最后提醒任务完成了。

gulp.task("styles", function () {
  return gulp
    .src("src/www/main.scss")
    .pipe(sass({ style: "expanded" })) //将sass文件编译为css
    .pipe(
      autoprefixer(
        "last 2 version",
        "safari 5",
        "ie 8",
        "ie 9",
        "opera 12.1",
        "ios 6",
        "android 4"
      )
    ) //添加css前缀
    .pipe(gulp.dest("dist/assets/css")) //保存到指定文件夹
    .pipe(rename({ suffix: ".min" })) //重命名文件,添加.min
    .pipe(minifycss()) //压缩css
    .pipe(gulp.dest("dist/assets/css"))
    .pipe(notify({ message: "Styles task complete" })); //提示
});

解释一下:

gulp.task('styles', function () {...});

gulp.task 这个 API 用来创建任务,在命令行下可以输入gulp styles来执行上面的任务。

return gulp.src('src/styles/main.scss')

gulp.src 这个 API 设置需要处理的文件的路径,可以是多个文件以数组的形式[main.scss, vender.scss],也可以是正则表达式/ _ / _ .scss。

.pipe(sass({ style: 'expanded' }))

我们使用.pipe()这个 API 将需要处理的文件导向 sass 插件,那些插件的用法可以在 github 上找到,为了方便大家查找我已经在上面列出来了。

.pipe(gulp.dest('dist/assets/css'));

gulp.dest()API 设置生成文件的路径,一个任务可以有多个生成路径,一个可以输出未压缩的版本,另一个可以输出压缩后的版本。

为了更好的了解Gulp API,强烈建议看一下 Gulp API 文档,其实 Gulp API 就这么几个。

样例

以下是我自己创建的任务,仅供参考:

  • 压缩 html
gulp.task("htmlmin", function () {
  //压缩html
  return gulp
    .src("src/www/index.html")
    .pipe(
      htmlmin({
        removeComments: true, //清除HTML注释
        collapseWhitespace: true, //压缩HTML
        minifyJS: true, //压缩页面JS
        minifyCSS: true, //压缩页面CSS
      })
    )
    .pipe(gulp.dest("dist/www/"))
    .pipe(notify({ message: "htmlmin task complete" }));
});
  • 压缩 js
gulp.task("minCom", function () {
  //压缩comm.js
  return gulp
    .src("src/www/app/comm.js")
    .pipe(rename({ suffix: ".min" })) //重命名
    .pipe(uglify()) //压缩js
    .pipe(gulp.dest("dist/www/js"))
    .pipe(notify({ message: "minCom task complete" }));
});
  • 压缩图片
gulp.task("img", function () {
  return gulp
    .src("src/www/img/*")
    .pipe(
      imagemin({
        optimizationLevel: 3,
        progressive: true,
        interlaced: true,
      })
    ) //压缩图片
    .pipe(gulp.dest("dist/www/img"))
    .pipe(notify({ message: "Images task complete" }));
});

这个任务使用 imagemin 插件把所有在 src/images/目录以及其子目录下的所有图片(文件)进行压缩,我们可以进一步优化,利用缓存保存已经压缩过的图片,使用之前装过的 gulp-cache 插件,不过要修改一下上面的代码,将这行代码:

.pipe(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true }))

修改成:

.pipe(cache(imagemin({ optimizationLevel: 5, progressive: true, interlaced: true })))

现在,只有新建或者修改过的图片才会被压缩了。

  • 清理数据

在任务执行前,最好先清除之前生成的文件:

gulp.task("clean", function (cb) {
  del(["dist/www/css", "dist/www/js"], cb);
});

在这里没有必要使用 Gulp 插件了,可以使用 NPM 提供的插件。我们用一个回调函数(cb)确保在退出前完成任务。

  • 压缩 angularJs

合并压缩 angularJs,保证依赖

gulp.task("Angularjs", function () {
  //合并压缩angular.js
  return gulp
    .src(["src/www/app/main.js", "src/www/app/map/init.js"])
    .pipe(ngAnnotate())
    .pipe(ngmin({ dynamic: false }))
    .pipe(stripDebug())
    .pipe(uglify({ outSourceMap: false }))
    .pipe(concat("all.min.js"))
    .pipe(gulp.dest("dist/www/js"));
});

设置默认任务(default)

我们在命令行下输入 gulp 执行的就是默认任务,现在我们为默认任务指定执行上面写好的三个任务:

gulp.task("default", ["clean"], function () {
  gulp.start("htmlmin", "styles", "minCom", "img");
});

在这个例子里面,clean 任务执行完成了才会去运行其他的任务,在 gulp.start()里的任务执行的顺序是不确定的,所以将要在它们之前执行的任务写在数组里面。

监听文件

为了监听文件的是否修改以便执行相应的任务,我们需要创建一个新的任务,然后利用 gulp.watch API 实现:

gulp.task("watch", function () {
  // Watch .scss files
  gulp.watch("src/styles/**/*.scss", ["styles"]);
  // Watch .js files
  gulp.watch("src/scripts/**/*.js", ["scripts"]);
  // Watch image files
  gulp.watch("src/images/**/*", ["images"]);
});

我们将不同类型的文件分开处理,执行对应的数组里的任务。现在我们可以在命令行输入gulp watch执行监听任务,当.sass、.js 和图片修改时将执行对应的任务。

  • 自动刷新页面

Gulp 也可以实现当文件修改时自动刷新页面,我们要修改 watch 任务,配置 LiveReload:

gulp.task("watch", function () {
  // Create LiveReload server  livereload.listen();
  // Watch any files in dist/, reload on change
  gulp.watch(["dist/**"]).on("change", livereload.changed);
});

要使这个能够工作,还需要在浏览器上安装 LiveReload 插件。

有关于 gulp 的使用,我还自己写了一个脚手架,平常开发一些小项目的时候,使用的比较方便。 github 地址:https://github.com/lion1ou/gulp_generator