资讯专栏INFORMATION COLUMN

用gulp管理自己的前端开发任务及需要注意的坑

gplane / 3699人阅读

摘要:但是频繁的关闭服务与重启服务,这样就造成了很多时间浪费,所以我们需要利用来监视文件的改动,并将这些改动重新发布到生产目录,并重启服务非手动。三预处理器文件编译暂时没用到,后面用到再增加,可以参考其他人的

关于gulp,grunt,webpack,刚走前端模块化的我,真的是傻傻分不清楚,幸好有大神各种答疑解惑,使我略知一二,你也想知道的,也许还想知道点啥,资源罗列:
1、中文官方文档;
2、阮老师的gulp入门;
3、我的参考;
本次开发,受尤大神知乎上的回答提示,没有采用vue-cli直接入手vue框架,而是采用vue全家桶+requireJs+gulp着手自己的前端构建,gulp为自己第一次使用,所以写下此文,算是对自己成长的一次记录。关于gulp,首先你得知道npm,node这些常识,其次官方的API应该细度加实践一下,其四个基本操作:gulp.task、gulp.src、gulp.dest、gulp.watch四个基本方法,需用知道是干什么的,该怎么用。gulp有什么用?文章将基于以下4条逐一展开讲:
1、搭建web服务器
2、优化资源,比如压缩CSS、JavaScript、压缩图片;
3、使用预处理器LESS,jade,JSX需要编译发布;
4、文件保存时自动重载浏览器;

一:开启一个本地web服务

通常开发时,我们不可能一直写静态页面,我们需要在其他设备查看效果或者与后台的动态交互,使前端开发变得更有意义。所以与后端交付之前,你得有一个本地服务器来发布你的内容。直白点说,没有服务器,我们是通过这样的链接(file:///D:/vueProject/myblog/dist/index.html)访问我们的页面的,而有了服务器依赖,我们是通过这样的链接(http://localhost/)访问我们的页面的,应用上线的感觉,有没有?其实以前基于JavaWeb开发(tomcat)网页时,根本就没这档子事。闲话少扯,进入正题。利用gulp资源,开启一个服务器,你需要下载安装gulp-webserver这个插件,然后这样配置,源码:

</>复制代码

  1. var gulp = require("gulp");
  2. var webserver = require("gulp-webserver");
  3. gulp.task("Server",function(){
  4. gulp.src("dist") //你web资源的根目录
  5. .pipe(webserver({
  6. port:80,
  7. host:"127.0.0.1",
  8. liveload:true,
  9. directoryListing:{
  10. path:"index.html", //你web资源的起始页,在dist目录下
  11. enable:true
  12. }
  13. }))
  14. });

基于以上,然后在命令行中输入gulp Server就可以开启一个本地端口为80(也可以为其他)的本地服务器,很简单有木有,但上面的服务器有一个问题,只有本机能访问,局域网内其他设备无法访问该站点,别信网上那些啥开防火墙,开端口胡扯的,根本没关系,因为gulp的web-server就只有这点功能,想要服务器局域网都能访问,在gulp-webserver官方文档的FAQ给出了解决方案:Set 0.0.0.0 as host option.

二:优化资源

gulp的主要功能就是文件的合并,压缩,MD5,由于我的前端JS是基于requireJS构建的,为了在页面加载时提高响应速度,就需要减少文件请求数量并压缩文件的大小,为了做这些操作,需要下载gulp-requirejs-optimize(requireJS序列化工具),gulp-rename,gulp-concat,gulp-minify-css,gulp-rev,gulp-rev-collector,through2,gulp-clean,run-sequence等插件包。我要达到的目如下图所示,重新生成发布目录、CSS文件的合并压缩,JS文件的优化及压缩及重命名带上MD5序列号。上源码:

</>复制代码

  1. var gulp = require("gulp"),
  2. reqOptimize =require("gulp-requirejs-optimize"),
  3. rename = require("gulp-rename"),
  4. changed = require("gulp-changed"),
  5. contact =require("gulp-concat"),
  6. rev =require("gulp-rev"),
  7. through2 = require("through2"),
  8. revCollector = require("gulp-rev-collector"),
  9. clean = require("gulp-clean"),
  10. runSequence = require("run-sequence"),
  11. minifyCss = require("gulp-minify-css");
  12. /*将requireJs文件转移到发布目录*/
  13. gulp.task("revJs",function(){
  14. gulp.src("js/main/*.js")
  15. .pipe(gulp.dest("dist/js/main"))
  16. });
  17. /*将所有的图片转移到发布目录*/
  18. gulp.task("revImg",function(){
  19. gulp.src("img/**/*")
  20. .pipe(gulp.dest("dist/img"))
  21. });
  22. /*将css文件合并压缩转移到发布目录*/
  23. gulp.task("revCss",function(){
  24. gulp.src("css/*.css")
  25. .pipe(contact("index.css"))
  26. .pipe(minifyCss())//{compatibility: "ie8"}
  27. .pipe(gulp.dest("dist/css"))
  28. });
  29. /*将主文件依赖管理合并、压缩、重命名、并去掉.js操作,然后转移到发布目录,操作后文件名如app-1da68b69e1.js*/
  30. function modify(modifier) {
  31. return through2.obj(function(file, encoding, done) {
  32. var content = modifier(String(file.contents));
  33. file.contents = new Buffer(content);
  34. this.push(file);
  35. done();
  36. });
  37. }
  38. function replaceSuffix(data) {
  39. return data.replace(/.js/gmi, "");
  40. }
  41. gulp.task("optimizeJS", function (cb) {
  42. gulp.src("js/app.js")
  43. .pipe(reqOptimize({
  44. optimize:"none",
  45. paths:{
  46. vue:"lib/vue",
  47. vueRouter:"lib/vue-router",
  48. vueResource:"lib/vue-resource",
  49. temp:"component/template",
  50. resize:"component/resizeWindow"
  51. }
  52. }))
  53. .pipe(rev()) //- 文件名加MD5后缀
  54. .pipe(gulp.dest("dist/js")) //- 生成MD5后的文件
  55. .pipe(rev.manifest({merge:true})) //- 生成一个rev-manifest.json,记录版本映射
  56. .pipe(gulp.dest(""))
  57. .pipe(modify(replaceSuffix)) //- 对去掉rev-manifest问件中的文件去掉.js后缀,这主要是考虑requireJs的操作规范
  58. .pipe(gulp.dest(""))
  59. .on("end",cb);
  60. });
  61. /*由于对app.js重命名加入了md5序列号值,所以需要替换原始index.html中关于app.js的引用*/
  62. /*这里需要注意,revCollector()相当于一个全文件查找替换的过程,以我的为例*/
  63. /*我的rev-manifest.json文件中对应的映射是:"app": "app-1da68b69e1",所以这个函数在操作时,会对index.html全文模糊搜索‘app’这三个关键字,然后替换为app-1da68b69e1,*/
  64. /*这其中容易出错就在于他是模糊搜索,所以如果你的文件中有个css的class名或自定义的标签名会内容带有app三个字母,它都会进行替换,所以,在转换过程中,要避开这个坑*/
  65. gulp.task("updateHtml",function (cb) {
  66. gulp.src(["rev-manifest.json", "index.html"])
  67. .pipe(revCollector()) //- 替换为MD5后的文件名
  68. .pipe(rename("index.html"))
  69. .pipe(gulp.dest("dist"))
  70. .on("end", cb);
  71. });

基于以上源码,在命令行中依次输入gulp revJs,gulp revImg,gulp revCss, gulp optimizeJS,gulp updateHtml,就可以达到上述目的,这样是不是有点繁琐,能不能一步到位?当然可以,我们可以帮上述任务写到一个命令中,当然你也可以写到default任务中,然后执行gulp alltask

</>复制代码

  1. gulp.task("alltask",["revJs","revImg","revCss","optimizeJS","updateHtml"])

上述代码有一个问题,特别是针对我的项目,因为我的updateHtml是基于optimizeJS执行完后生成的rev-manifest.json执行的,但gulp.task中的任务组,默认是并行执行的,但我希望的是前三个转移并行执行,后面两个串行执行,经过资料查找得知,在gulp 4之前,需要依赖run-sequence来管理任务的执行顺序,而gulp 4引入了连个新的API:gulp.series(串行)和gulp.parallel(并行)来保证任务按指定的顺序执行。在这里我采用了run-sequence的解决方案:

</>复制代码

  1. gulp.task("default", function(callback) {
  2. runSequence(
  3. "clean", //- 上一次构建的结果清空
  4. "revImg",
  5. "revCss",
  6. "revJs",
  7. "optimizeJS", //- - 文件合并与md5并去.js后缀
  8. "updateHtml", //- 首页路径替换为md5后的路径
  9. "Server", //- 服务器开启
  10. callback);
  11. });

下一步重点研究,怎样将生成后的JS及CSS文件带上如browser-sync-client.js?v=2.18.12版本号的形式。

四:文件更改保存时浏览器的自动重载(先跳过三)

在我们的开发过程中,我们经常会修改html,CSS,js文件,由于我们的生产目录与开发目录不一致,所以需要执行GULP命令来发布文件到生产目录。但是频繁的关闭服务与重启服务,这样就造成了很多时间浪费,所以我们需要利用gulp.watch来监视文件的改动,并将这些改动重新发布到生产目录,并重启服务(非手动)。由于个人觉得gulp-webServer与gulp-livereload的局限性,所以讲服务采用browser-sync来代替gulp-webServer,后者自身支持热更新,无需在浏览器安装任何插件(gulp-livereload需要安装livereload插件),直接上源码:

</>复制代码

  1. var browserSync = require("browser-sync").create(); //引入模块
  2. /*每次发布生产文件前,先将dist目录下的文件情况*/
  3. gulp.task("clean",function () {
  4. return gulp.src([
  5. "rev-manifest.json",
  6. "dist/js/*.js",
  7. "dist/index.html"
  8. ]).pipe(clean());
  9. });
  10. /*每次app.js变动时,需要清除rev-manifest.json文件中的映射,使其保证只有唯一的一个映射*/
  11. gulp.task("JSreload",function(){
  12. return gulp.src(["rev-manifest.json", "dist/js/*.js","dist/index.html"]).pipe(clean());
  13. })
  14. /*每次任务发起前,先清空温江,然后再依次发布文件,启动服务器,监听变动*/
  15. gulp.task("server", ["clean"], function() {
  16. runSequence(
  17. "revImg",
  18. "revCss",
  19. "revJs",
  20. "optimizeJS", //- - 文件合并与md5并去.js后缀
  21. "updateHtml" //- 首页路径替换为md5后的路径
  22. );
  23. browserSync.init({
  24. port: 80,
  25. server: {
  26. baseDir: ["dist"]
  27. }
  28. });
  29. //监控文件变化,自动更新
  30. gulp.watch("js/app.js", function(){
  31. runSequence(
  32. "JSreload",
  33. "optimizeJS",
  34. "updateHtml",
  35. browserSync.reload
  36. );
  37. });
  38. gulp.watch("css/*.css", function(){
  39. runSequence(
  40. "revCss",
  41. browserSync.reload
  42. );
  43. });
  44. gulp.watch("index.html", function(){
  45. runSequence(
  46. "updateHtml",
  47. browserSync.reload
  48. );
  49. });
  50. });

/将server事务,注册为默认任务/
gulp.task("default",["server"]);
基于以上操作,命令行运行gulp ,我们就开启了一个基于browserSync的本地服务器如下图所示,并且局域网内的设备都可以通过主机IP+port访问应用。

三:预处理器文件编译

暂时没用到,后面用到再增加,可以参考其他人的

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/83799.html

相关文章

  • 基于 Gulp 简易前端自动化工程搭建

    摘要:生成的文件如下由于给文件添加了哈希值,所以每次编译出来的和都是不一样的,这会导致有很多冗余文件,所以我们可以每次在生成文件之前,先将原来的文件全部清空。中也有做这个工作的插件,因此我们可以在编译压缩添加哈希值之前先将原文将清空。 原文链接:http://mrzhang123.github.io/2016/09/07/gulpUse/项目链接:https://github.com/MrZ...

    Blackjun 评论0 收藏0
  • 浅析git

    摘要:浅析笔者在此整理了常见的命令,的重要性无需多言,与其再百度海中搜索命令,不妨尝试收藏笔者的此篇作品。旨在快速高效地处理无论规模大小的任何软件工程。其最大特色就是分支及合并操作非常快速简便。 浅析git 笔者在此整理了常见的git命令,git的重要性无需多言,与其再百度海中搜索git命令,不妨尝试收藏笔者的此篇作品。希望对你的学习有所帮助。 版本控制系统之git Git: (一)简介:G...

    explorer_ddf 评论0 收藏0
  • 浅析git

    摘要:浅析笔者在此整理了常见的命令,的重要性无需多言,与其再百度海中搜索命令,不妨尝试收藏笔者的此篇作品。旨在快速高效地处理无论规模大小的任何软件工程。其最大特色就是分支及合并操作非常快速简便。 浅析git 笔者在此整理了常见的git命令,git的重要性无需多言,与其再百度海中搜索git命令,不妨尝试收藏笔者的此篇作品。希望对你的学习有所帮助。 版本控制系统之git Git: (一)简介:G...

    Neilyo 评论0 收藏0
  • 浅析git

    摘要:浅析笔者在此整理了常见的命令,的重要性无需多言,与其再百度海中搜索命令,不妨尝试收藏笔者的此篇作品。旨在快速高效地处理无论规模大小的任何软件工程。其最大特色就是分支及合并操作非常快速简便。 浅析git 笔者在此整理了常见的git命令,git的重要性无需多言,与其再百度海中搜索git命令,不妨尝试收藏笔者的此篇作品。希望对你的学习有所帮助。 版本控制系统之git Git: (一)简介:G...

    Big_fat_cat 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<