gulp的使用
本文将介绍gulp的基础使用和一次项目实践。
一、gulp的介绍
1.gulp是一个工具,用于在开发工作流程中自动执行我们需要执行的任务,比如修改代码后重新编译,构建环境等,gulp可以一行命令搞定这些重复琐碎的工作。
二、gulp的四个参数
- gulp.src (globs[,optons]) : 在src里传入我们需要处理的文件或者文件数组,将会被转化为能被插件处理的文件流。
- gulp.dest(path,[,options]):可以将pipe进来的数据写入文件,重新发送传递给它的所有数据,以便管道到多个文件夹。不存在的文件夹将被创建。(注意写此处的path是文件夹)
gulp.task(name[,deps,fn]):定义任务,任务的名称不应该有空格,当前执行的任务如果依赖于或者需要其他任务先执行完,采用下图方式即可,mytask任务将在其他四个人任务执行完后执行。
gulp.task('mytask', ['array', 'of', 'task', 'names'], function() { // Do stuff });
也可以定义任务用于执行一系列的任务,例如构建开发环境,产品环境。
gulp.task('build', ['array', 'of', 'task', 'names']);
- 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,升级版本后问题解决。