Gulp 在金蝶云平台项目中的使用经验

自上次发表了 Grunt:初次使用及前端构建经验 后,前端同学 cobish 对笔者说,grunt 不太好用,现在我们项目中已经不用了,现在用 glup。什么?那你赶紧给笔者我介绍一下。cobish 抠着鼻屎对我说,你去看我的笔记就好啦!好吧,看完后,笔者又整理了一篇关于我们在项目中,使用 glup 的前端文章分享给大家。

gulp 初试用

在用了 Grunt 的一段时间内,越来越觉得自己离不开构建工具。但是,Grunt 的构建速度让我有点苦恼,即使是编译 sass 也需要花上一段时间。于是,我开始试用 gulp,结果意外地让我惊喜。

下面代码是使用 gulp 初次来编译 sass,由于一直都有点习惯了 Grunt 那编译速度单位为秒级别的速度,刚输入命令还没反应过来,就已经以毫秒级的速度编译完了。

var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');

// sass 编译
gulp.task('sass:dev', function() {
  return gulp.src('dev/sass/**/*.scss')
    .pipe(sourcemaps.init())
    .pipe(sass({outputStyle: 'expanded'}).on('error', sass.logError))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('dev/css'));
});

比较一下 Grunt 与 gulp 编译同一套 sass 代码下所花费的时间:

并不是说 Grunt 就比 gulp 不好,也有 gulp 办不到 Grunt 办得到的事情。但是就运行速度相比,gulp 的速度确实是完胜。

gulp 打包 requirejs

目前我的项目是一个页面一个 js 入口,比如登录页面的入口是 login.js,而主页面的入口是 home.js,它们都是在同一个目录下。

├─ src/
    ├─ js/
        ├─ lib
            ├─ require.min.js
            └─ jquery-1.11.1.min.js
        ├─ mod
            ├─ home.js
            └─ login.js
        └─ config.js
├─ gulpfile.js
└─ package.js

html 每个页面的引入是这样子的:

<script type="text/javascript" src="__JSPATH__/config.js"></script>
<script type="text/javascript" src="__JSPATH__/lib/requirejs.min.js" data-main="__JSPATH__/mod/login.js"></script>

requirejs 的 config 文件如下:

var requirejs = {
  paths: {
    jquery: '../lib/jquery-1.11.1.min',
    widget: '../widget'
  }
};

接下来就是使用 gulp 对 js 文件进行打包,用到的是「gulp-requirejs-optimize」,由于项目是多入口文件,所以需要批量打包,打包的代码如下:

var gulp = require('gulp');
var requirejsOptimize = require('gulp-requirejs-optimize');

gulp.task('rjs', function () {
  return gulp.src('src/js/mod/*.js')
    .pipe(requirejsOptimize({
      mainConfigFile: 'src/js/config.js',
      exclude: [
        'jquery'
      ]
    }))
    .pipe(gulp.dest('dist/js/mod'));
});

运行相应命令,即可完成打包:

$ gulp rjs

gulp 自动刷新浏览器

项目本地后端开发语言是是基于 apache 的 php,域名为 cloud.xxx.com。刚开始想实现浏览器 F5 自动刷新使用到的是 grunt 和 livereload 插件,gulp 也有对应的方法,参考 gulp 教程之 gulp-livereload。但是,它需要浏览器安装 livereload 插件才能使用,chrome 的插件需要翻墙下载,firefox 的插件不起作用,其它的浏览器也无法实现自动刷新。

后来,我发现了 Browsersync。简直就像是找到了宝藏一样,同样支持 grunt 和 gulp。以下代码是使用代理去实现:

var gulp = require('gulp');
var browserSync = require('browser-sync').create();

gulp.task('serve', function () {
    browserSync.init({
        proxy: "http://cloud.xxx.com"
    });

    gulp.watch('*.html').on('change', browserSync.reload);
});

运行命令,默认的浏览器会自动打开 127.0.0.1:3000 链接

gulp serve

如果想多个浏览器都可以自动刷新,只需要打开其它浏览器,把刚刚的链接输入即可。还有,由于项目原因,开发的时候不能使用到 127.0.0.1 ,想换成 php 配置的域名怎么做?直接把 127.0.0.1:3000 链接换成 cloud.xxx.com:3000 即可,Browsersync 实际就是监听 3000 端口来实现刷新浏览器。

基于 gulp 的前端构建

之前使用 Grunt 时总结了一篇「基于 Grunt 的前端构建」。在使用了 Grunt 的一段时间后,我发现了 gulp 的运行速度比 Grunt 快很多,于是便从 Grunt 转移阵地到了 gulp。以下的构建思路跟 Grunt 的构建很类似。如果你也使用过 Grunt,那我相信你一定能够很快地切换到 gulp。当然如果你没有接触过 Grunt,我相信你一定也能够很快上手 gulp。

目录结构

├─ gulp/                  # gulp 配置目录
    ├─ tasks              # 任务配置目录
        ├─ image.js       # 图片配置
        ├─ other.js       # 其它配置
        ├─ script.js      # 脚本配置
        ├─ style.js       # 样式配置
        └─ view.js        # 页面配置
    └─ config             # gulp 配置文件
├─ src/                   # 开发目录
    ├─ html/              # 存放 html 的目录
        ├─ app/           # 可提取复用的页面模块
        └─ page/          # 各页面入口文件
    ├─ images/            # 存放图片的目录
        ├─ single/        # 不需要合并的图片
        └─ sprite/        # 需要合并的图片
    ├─ js/                # 存放 js 的目录
        ├─ app/           # 可提取复用的脚步模块
        ├─ lib/           # 第三方 js 库
        ├─ page/          # 各页面入口脚本文件
        └─ config.js      # RequireJs 的配置文件
    └─ sass/              # 存放 sass 的目录
        ├─ app/           # 可提取复用的样式模块
        └─ page/          # 各页面入口样式文件
├─ .jshintrc              # jshint 参数配置文件
├─ gulpfile.js            # gulp 入口配置文件
└─ package.json           # npm 包管理文件

gulp 目录

参考: 前端 | 重构 gulpfile.js。其中专门创建一个 gulp 目录用来存放 gulp 代码,为了能够将任务更加细化,职责单一,方便日后的维护更新。

└─ gulp/                  # gulp 配置目录
    ├─ tasks              # 任务配置目录
        ├─ image.js       # 图片配置
        ├─ other.js       # 其它配置
        ├─ script.js      # 脚本配置
        ├─ style.js       # 样式配置
        └─ view.js        # 页面配置
    └─ config             # gulp 配置文件

命令

$ gulp help # 说明帮助

$ gulp sass # sass 本地编译

$ gulp jshint # js 语法检测

$ gulp include # html 包含依赖编译

$ gulp dev # 开发监控,浏览器不自动刷新

$ gulp serve # 开发监控,浏览器自动刷新

$ gulp build # 打包上线

开发阶段

执行 gulp dev 命令,gulp 会进行一系列构建操作,最后在 dist 目录下生成可运行文件,并实时监听源文件,一旦源文件改动会执行相应的操作。

// 开发监控,浏览器不自动刷新
gulp.task('dev', function(cb) {
    runSequence(
        'clean:dist',
        'clean:tmp',
        ['copy:img', 'sass', 'jshint', 'copy:js', 'include'],
        'watch',
        cb
    );
});

执行 gulp serve 命令,gulp 会执行跟 gulp dev 一样的操作并监听源文件,唯一不同的是它在执行后会监听某个端口,一旦有文件改动它会帮你自动刷新浏览器,帮你省下了按 F5 的力气。当然在同时开上多个浏览器测试页面时它将会很有帮助。

// 开发监控,浏览器自动刷新
gulp.task('serve', function(cb) {
    runSequence(
        'clean:dist',
        'clean:tmp',
        ['copy:img', 'sass', 'jshint', 'copy:js', 'include'],
        'reload',
        cb
    );
});

上线打包阶段

参考:张云龙的 大公司里怎样开发和部署前端代码?。通过以下代码一个大体知道,上线打包主要是对图片样式脚本进行打包处理。所以接下来的工作就是职责分工,独立完成各自的构建工作。

gulp.task('build', function(cb) {
    runSequence(
        'clean:dist',
        'clean:tmp',
        'build:img',
        'build:css',
        'build:js',
        'build:html',
        'clean:tmp',
        cb
    );
});

第一个步骤主要是对图片进行处理,包括图片合并压缩 hash 戳等。其中对 css 代码处理是为了替换合并后的图片路径。

// 打包图片
gulp.task('build:img', function(cb) {
    runSequence(
        'sass:tmp',
        'copy:tmpImg',
        'autoSprite',
        'imagemin',
        'rev:img',
        cb
    )
});

第二个步骤主要是对 css 文件进行处理,其中还包括替换已经 hash 的图片资源,并生成 hash 戳。

// 打包 css 文件
gulp.task('build:css', function(cb) {
    runSequence(
        'usemin:css',
        'sass:dist',
        'rev:css',
        cb
    );
});

第三个步骤是 js 文件的打包,打包 RequireJs 代码可以根据依赖进行 js 文件的合并压缩,最终每个页面都打包一个 js 文件为单入口。

// 打包 js 文件
gulp.task('build:js', function(cb) {
    runSequence(
        'requirejs',
        'uglify:config',
        'rev:js',
        'copy:js',
        cb
    );
});

第四个步骤是 html 文件的打包,替换掉前面已经 hash 的静态资源即可。

// 打包 html 文件
gulp.task('build:html', function(cb) {
    runSequence(
        'include',
        'usemin:html',
        cb
    );
});

最终生成的代码依然在 dist 目录下,也就是说在开发阶段与上线打包阶段构建生成的代码都在同一个目录下,只不过在开发阶段代码是未进行合并压缩,上线打包阶段代码是经过合并压缩打上 hash 戳的。所以建议该目录下的代码不需要添加到版本控制中。

未解决的问题

开发阶段:对 RequireJs 的路径配置(config.js 与 gulp 中的配置)感到困惑迷糊,多创建一个目录就路径不匹配打包不成功。

上线打包阶段:RequireJS 若添加第三方库,需要手动修改 gulp 代码。

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java帮帮-微信公众号-技术文章全总结

Maven 核心原理解析(1)

Maven 是每一位Java工程师每天都会接触的工具, 但据我所知其实很多人对Maven理解的并不深, 只把它当做一个依赖管理工具(下载依赖、打包), Mave...

38210
来自专栏数据之美

15 个简单、有趣而实用的 单行 HTTP Server

不少语言或服务开发框架都内置了简单的 Web Server 供我们方便的调试使用。比如有时候我们需要调试单个 PHP 页面而不想搭建一套完整的 PHP 环境,亦...

20310
来自专栏大数据和云计算技术

MongoDB系列11:Munin监控MongoDB

Munin是一个网络资源监控工具,可以帮助分析资源趋势。默认提供了大量的分析图形。以下讲述如何设置MongoDB的Munin监控插件。

893
来自专栏前端知识分享

Angular中sweetalert弹框的使用详解

最近太忙了,项目中使用的弹框老板嫌太丑,让我们优化一下,我在网上找了一下,找到了sweetalert弹框,算是比较好看的弹框了。所以我就想办法将sweetale...

834
来自专栏伪君子的梦呓

用 selenium 和 scrapy 模拟知乎登录

这个是看一个视频学来的,视频给出的教程部分失效,因为知乎的登录页面改了。我进行一点修改就可以登录了,本文主要是记录

1013
来自专栏python学习之旅

Python Django框架笔记(一):安装及创建项目

#推荐一本书《Python核心编程》(适合有一定基础的),美国人Wesley Chun编写的,京东、淘宝应该都有。我是觉得写的很好,详细、简洁、满满的干货,不...

3116
来自专栏有趣的Python

8- Flask构建弹幕微电影网站-后台页面搭建后台页面搭建

已上线演示地址: http://movie.mtianyan.cn 项目源码地址:https://github.com/mtianyan/movie_proj...

3073
来自专栏IMWeb前端团队

Nativescript跨终端应用程序开发方案研究

1.环境准备 安装nodejs 安装nativescript $npm install -g nativescript 或者下载github上项目代码进行构建(...

2215
来自专栏大数据架构师专家

新的技术资料来了

我分享资料有一个特点,从来不要求大家转发,大家按需下载学习,如果资源有失效的,请第一时间告知

1123
来自专栏Gaussic

使用IntelliJ IDEA开发SpringMVC网站(一)开发环境 顶

访问GitHub下载最新源码:https://github.com/gaussic/SpringMVCDemo

881

扫码关注云+社区