gulp的使用

本文将介绍gulp的基础使用和一次项目实践。

一、gulp的介绍

1.gulp是一个工具,用于在开发工作流程中自动执行我们需要执行的任务,比如修改代码后重新编译,构建环境等,gulp可以一行命令搞定这些重复琐碎的工作。

二、gulp的四个参数

  1. gulp.src (globs[,optons]) : 在src里传入我们需要处理的文件或者文件数组,将会被转化为能被插件处理的文件流。
  2. gulp.dest(path,[,options]):可以将pipe进来的数据写入文件,重新发送传递给它的所有数据,以便管道到多个文件夹。不存在的文件夹将被创建。(注意写此处的path是文件夹)
  3. gulp.task(name[,deps,fn]):定义任务,任务的名称不应该有空格,当前执行的任务如果依赖于或者需要其他任务先执行完,采用下图方式即可,mytask任务将在其他四个人任务执行完后执行。

    gulp.task('mytask', ['array', 'of', 'task', 'names'], function() {
      // Do stuff
    });

    也可以定义任务用于执行一系列的任务,例如构建开发环境,产品环境。

    gulp.task('build', ['array', 'of', 'task', 'names']);
  4. gulp.watch(glob,[opts],tasks): 监听文件或者文件数组的改变,执行相应的任务。

三、项目实践

项目要完成的任务是:
    
1. 将keppAcounts模块打包压缩并提供开发和产品两套环境的打包
2. 其他模块合并相应文件到一个目录供外壳项目引入
3. 整个项目新老框架两种打包方式(gulp、webpack)用一个命令完成构建
4. 监听所有文件的改变

1.本次项目所运用的插件

const concat = require("gulp-concat");                  //文件的合并
const uglify = require("gulp-uglify");                  //js文件压缩
const cleanCSS = require("gulp-clean-css");                 //css文件压缩
const template = require("gulp-template-compile");      //html模板文件转为js文件
const del = require("del");                                   //清空文件目录
const webpack = require("webpack-stream");                   //在gulp中执行webpack的打包
const rev = require("gulp-rev");                         //内容hash码附加到文件名

2.html模块转成js并合并

gulp.task("gulpKeepAccountsHtml", () => {
    gulp.src("keepAccounts/templates/**/*.html")
        .pipe(template({namespace: "keepAccountsTmpl"}))
        .pipe(concat("keepAccountsTmpl.js"))
        .pipe(gulp.dest(".tmp"))
})

因为项目里用的html文件只是一些纯模板文件,所以转换后放一个变量下引入即可,不需要采用html文件传统的去注释等处理。通过template插件将目录下的所有html文件通过template插件转成js模块,namespace可以指定转换后的模板文件放在windows下对应的变量名里。然后合并成keepAccountsTmpl.js文件,并输出到一个.tmp文件夹中。

3.js模块合并

//js模块=>html模块执行完之后执行
gulp.task("gulpKeepAccountsJS", ["gulpKeepAccountsHtml"], () => {
    gulp.src(["keepAccounts/scripts/**/*.js", ".tmp/keepAccountsTmpl.js"])
        .pipe(concat("app.js"))
        .pipe(gulp.dest("keepAccounts"))
})

因为这是一个独立的模块,html模板代码很少,所以我们和js模块都打入一个包里。那么打包js模块时,需要html模块先转化完js,所以这个任务需要先依赖于gulpKeepAccountsHtml任务完成,放在此任务的依赖任务中。然后引入对应的js,html转换好的js模块即完成js模块的合并。

4.js模块打包压缩

gulp.task("gulpKeepAccountsJSPro", ["gulpKeepAccountsHtml"]() => {
    gulp.src(["keepAccounts/scripts/**/*.js", ".tmp/keepAccountsTmpl.js"])
        .pipe(concat("app.js"))
        .pipe(gulp.dest("keepAccounts"))
        .pipe(uglify())
        .pipe(rev())
        .pipe(gulp.dest("../dist/financial/keepAccounts"));
})

在产品环境中,代码需要打包压缩加上内容哈希码,这样如果第二次上线这个模块的包没有更新,用户就不需要重新下载这个包。在开发环境合并(此模块合并给其他项目使用)的基础上,压缩加上内容哈希码后输入到产品环境包目录下。

js模块打包还应该注意的一个问题是,文件合并顺序问题。有些工具类文件、样式要合并在前面,在src里文件数组的顺序就是会打包的顺序。

5.新框架代码构建

//开发环境
gulp.task('runES6', function () {
    return gulp.src('scripts-es6/main.js')
        .pipe(webpack({config:require('./config/webpack.config.dev.js'),watch: true}))
        .pipe(gulp.dest("packagedFiles/es6"));
})

项目里有些模块代码是react写的,采用了webpack的打包方式。在产品模块构建时,为了方便统一构建,在gulp加入构建新框架的代码。不同的环境引入不同的webpack配置环境,开发引入的配置文件里开启了sorce-map,配置参数watch为true开启了webpack的监听。

6.开发环境监听文件的改变

//开发环境监听
gulp.task("watch", function () {
    livereload.listen();
    gulp.watch(jsFiles, ["gulpAppJS"]);
    gulp.watch(["views/**/*.html", "!views/MainView.html"],["gulpTemplate"]);
    gulp.watch(cssFiles, ["gulpAppCSS"]);
    gulp.watch(["data/*"], ["copyData"]);
    gulp.watch(["keepAccounts/templates/**/*.html", "keepAccounts/scripts/**/*.js"], ["gulpKeepAccountsJS"]);
    gulp.watch(["keepAccounts/styles/**/*.css"], ["gulpKeepAccountsCSS"]);
});

两个模块的文件分别监听,当文件发生改变时重新打包。因为最终运行的项目是一个外壳项目,需要把更新后的代码重新打包传过去。

7.开发产品环境构建

/*开发环境构建*/
//运行命令 gulp
gulp.task("default", ["copyData", "gulpTemplate", "gulpAppCSS", "gulpAppJS", "copyImage", "gulpKeepAccountsJS", "gulpKeepAccountsCSS","watch","runES6"]);

/*生产环境构建*/
//运行命令 gulp build
gulp.task("build", ["delFinancial", "copyData", "gulpTemplate", "gulpAppCSS", "gulpAppJS", "copyImage", "gulpKeepAccountsJSPro", "gulpKeepAccountsCSSPro","runES6Pro"]);

两个命令分别对应不同的环境,执行不同的任务。

四、遇到的问题

1.合并完文件后,运行项目请求能回来但是不能渲染上数据?

没有考虑model、collections、viewModels的合并顺序,原来是统一将js模块下的代码都合并。解决方案是按顺序将文件目录写进src的数组里,按顺序合并。这也说明了一个项目规划好目录的重要性。

2.样式显示错误?

有两个css文件打包顺序错误,导致后面一个文件的样式覆盖了上一个文件,这两个文件都是写分页组件相关的。解决方案为了不多引入插件,将应该后打入的文件名改为z开头,合并顺序是按文件名字母排列,也可以引入order插件解决。

3.引入webpack后执行文件报错?

(1)configuration.output.path: The provided value "./packagedFiles/es6" is not an absolute path!

-> The output directory as absolute path (required).

解决:产生错误的地方是webpack.config.js的配置文件的output中path路径,这个路径改了多次都没有生效,后来想到的是,用gulp.dist可以直接输出打包后的文件在正确的地址,用不着里面配置的output,去掉之后解决。

(2)Chunk.entry was removed. Use hasRuntime()

解决:产生的原因是引用的插件webpack-stream里面的webpack已经升级到3.4.1,而项目里的webpak版本还是1.13.2,升级版本后问题解决。

相关推荐