使用gulp构建前端自动化的方法示例


Posted in Javascript onDecember 25, 2018

gulp是一个自动化构建工具,开发者可以用它来自动执行一些常见的任务。这里以我之前做的一个demo为例,简要介绍如何使用gulp实现前端工程自动化。

项目结构

使用gulp构建前端自动化的方法示例

其中src目录下表示的是项目的源代码,可以看到其中有less、js、html等,而dist目录则是保存的是gulp编译后生成的代码,相当于生产环境。最后也最重要的是gulpfile.js,这个文件用于设置gulp相关的配置,类似于webpack中的webpack.config.js。

安装

这里使用的gulp为v3.9.1,语法和最新的v4.x有所出入,想学习最新的gulp语法,可以参考gulp.js - The streaming build system 。

3.9.1 安装如下:

npm install --save-dev gulp

语法

  • gulp.task()用于定义一个gulp任务,在命令行中可以使用gulp [任务名]开启该任务。
  • gulp.src()会返回符合匹配的文件流,可以被pipe()到其他插件中。
  • gulp.dest():输出所有数据。
  • gulp.watch()用于监测文件的变动。

实践

在这个项目中,有一些常见的需求,这里使用gulp来实现自动化:

  • less转css
  • css压缩合并
  • js压缩合并
  • 图片压缩

在gulpfile.js中首先需要导入gulp和一些常用的插件,本次demo使用到的插件如下:

var gulp = require('gulp'),
  less = require('gulp-less'),          //less 转 css
  csso = require('gulp-csso'),          //css压缩
  concat = require('gulp-concat'),        //合并文件
  uglify = require('gulp-uglify'),        //js 压缩
  jshint = require('gulp-jshint'),        //js 检查
  clean = require('gulp-clean'),         //清除文件
  imagemin = require('gulp-imagemin'),      //图片压缩
  rev = require('gulp-rev'),           //添加版本号
  revReplace = require('gulp-rev-replace'),   //版本号替换
  useref = require('gulp-useref'),        //解析html资源定位
  gulpif = require('gulp-if'),          //if语句
  connect = require('gulp-connect');       //创建web服务器

图片压缩

获取到src下所有以.jpg或.png结尾的图片,将其压缩后输出到dist目录下。

gulp.task('dist:img', () => {
  gulp.src(['./src/**/*.jpg', './src/**/*.png'])
  .pipe(imagemin())
  .pipe(gulp.dest('dist/'))
})

less压缩合并为css

先清除已存在的css,然后将src下以.less结尾的文件通过less()转为css文件,再通过csso()以及concat()实现对css的压缩合并。

gulp.task('dist:css', () => {
  gulp.src('dist/css/*.css').pipe(clean());
  return gulp.src('./src/less/*.less')
  .pipe(less())
  .pipe(csso())
  .pipe(concat('public.css'))
  .pipe(gulp.dest('dist/css/'));
});

js压缩合并

js压缩合并的过程大同小异,增加了一个jshint()代码审查的过程,它会将不符合规范的错误代码输出到控制台。

gulp.task('dist:js', () => {
  gulp.src('dist/js/*.js').pipe(clean());
  return gulp.src('./src/js/*.js')
  .pipe(jshint())
  .pipe(jshint.reporter('default'))
  .pipe(uglify())
  .pipe(concat('public.js'))
  .pipe(gulp.dest('dist/js/'))
});

less=>css

在开发过程中,因为html不能直接引入.less文件,因此还需要生成开发环境的.css。

gulp.task('src:css', () => {
  gulp.src('src/css/*.css').pipe(clean());
  return gulp.src('./src/less/*.less')
  .pipe(less())
  .pipe(gulp.dest('src/css/'));
});

添加版本号

为了防止浏览器对文件进行缓存,需要对文件添加版本号,保证每次获取到的都是最新的代码。

gulp.task('revision', ['dist:css', 'dist:js'], () => {
  return gulp.src(["dist/css/*.css", "dist/js/*.js"])
  .pipe(rev())
  .pipe(gulpif('*.css', gulp.dest('dist/css'), gulp.dest('dist/js')))
  .pipe(rev.manifest())
  .pipe(gulp.dest('dist'))
})

gulp.task('build', ['dist:img'], () => {
  var manifest = gulp.src('dist/rev-manifest.json');
  return gulp.src('src/index.html')
  .pipe(revReplace({
    manifest: manifest
  }))
  .pipe(useref())
  .pipe(gulp.dest('dist/'))
})

在revision中,首先通过rev()对dist目录下的.css/.js生成一个文件名带版本号的文件,例如本例中public.css生成public-5c001c53f6.css,然后分别输出到不同的目录下,最后生成一个rev-manifest.json文件,存储了原文件和带版本号文件之间的映射关系,如下:

{
 "public.css": "public-5c001c53f6.css",
 "public.js": "public-93c275a836.js"
}

在build中,先获取到rev-manifest.json中的对象,然后利用revReplace()来替换版本号,再使用useref()来进行资源的解析定位,最后输出即可。

以引入js文件为例,源html文件中对文件的引入则要改写为以下形式,即以注释的形式写入构建后生成的文件路径,如下:

<!-- build:js ./js/public.js -->
<script src="./js/jquery-1.12.4.min.js"></script>
<script src="./js/myAlbum.js"></script>
<!-- endbuild -->

最后生成的html为:

<script src="./js/public-93c275a836.js"></script>

具体的语法规则可以参见gulp-useref。

创建本地服务器并实现自动刷新

使用connet.server()来创建一个本地服务器,利用gulp.watch()来对src下的文件进行监测,如果发生变化,则执行编译less为css和刷新页面的任务。

gulp.task('connect', () => {
  connect.server({
    root: 'src',
    livereload: true,
    port: 8888
  })
})

gulp.task('reload', () => {
  gulp.src('src/*.html')
  .pipe(connect.reload())
})

gulp.task('watch', () => {
  gulp.watch('src/**/*', ['src:css', 'reload'])
})

完整的代码可以参见github。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js文字滚动停顿效果代码
Jun 28 Javascript
JSQL 基于客户端的成绩统计实现方法
May 05 Javascript
JavaScript中的函数模式详解
Feb 11 Javascript
javascript中的深复制详解及实例分析
Dec 29 Javascript
EasyUI的DataGrid每行数据添加操作按钮的实现代码
Aug 22 Javascript
react-native DatePicker日期选择组件的实现代码
Sep 12 Javascript
在create-react-app中使用sass的方法示例
Oct 01 Javascript
ios中视频的最后一桢问题解决
May 14 Javascript
JavaScript变量作用域及内存问题实例分析
Jun 10 Javascript
JavaScript中Dom操作实例详解
Jul 08 Javascript
详解Vuex下Store的模块化拆分实践
Jul 31 Javascript
node.js实现简单的压缩/解压缩功能示例
Nov 05 Javascript
JavaScript实现的级联算法示例【省市二级联动功能】
Dec 25 #Javascript
详解vuex commit保存数据技巧
Dec 25 #Javascript
bootstrap table实现合并单元格效果
Dec 24 #Javascript
Electron autoUpdater实现Windows安装包自动更新的方法
Dec 24 #Javascript
Windows下支持自动更新的Electron应用脚手架的方法
Dec 24 #Javascript
如何使用electron-builder及electron-updater给项目配置自动更新
Dec 24 #Javascript
Vue.js组件高级特性实例详解
Dec 24 #Javascript
You might like
PHP文件读写操作之文件读取方法详解
2011/01/13 PHP
PHP FOR MYSQL 代码生成助手(根据Mysql里的字段自动生成类文件的)
2011/07/23 PHP
php中怎么搜索相关联数组键值及获取之
2013/10/17 PHP
Laravel 5.5基于内置的Auth模块实现前后台登陆详解
2017/12/21 PHP
js对象的比较
2011/02/26 Javascript
JavaScript高级程序设计(第3版)学习笔记4 js运算符和操作符
2012/10/11 Javascript
Textbox控件注册回车事件及触发按钮提交事件具体实现
2013/03/04 Javascript
jquery实现邮箱自动补全功能示例分享
2014/02/17 Javascript
jQuery中选择器小问题(新人难免遇到)
2014/03/31 Javascript
JS模拟实现Select效果代码
2015/09/24 Javascript
超详细的JS弹出窗口代码大全
2020/04/18 Javascript
jQuery实现的多张图无缝滚动效果【测试可用】
2016/09/12 Javascript
JQuery异步提交表单与文件上传功能示例
2017/01/12 Javascript
Angular.js 4.x中表单Template-Driven Forms详解
2017/04/25 Javascript
微信小程序 监听手势滑动切换页面实例详解
2017/06/15 Javascript
详解Angular 开发环境搭建
2017/06/22 Javascript
深入理解React中何时使用箭头函数
2017/08/23 Javascript
浅谈Express异步进化史
2017/09/09 Javascript
基于Vuejs的搜索匹配功能实现方法
2018/03/03 Javascript
微信小程序实现跑马灯效果
2020/10/21 Javascript
JavaScript中的事件与异常捕获详析
2019/02/24 Javascript
vue cli3.0 引入eslint 结合vscode使用
2019/05/27 Javascript
jQuery zTree插件快速实现目录树
2019/08/16 jQuery
[53:15]2018DOTA2亚洲邀请赛3月29日 小组赛A组 LGD VS TNC
2018/03/30 DOTA
[02:16]完美世界DOTA2联赛PWL S3 集锦第三期
2020/12/21 DOTA
Python3遍历目录树实现方法
2015/05/22 Python
Python实现统计文本文件字数的方法
2017/05/05 Python
磁盘垃圾文件清理器python代码实现
2020/08/24 Python
python selenium执行所有测试用例并生成报告的方法
2019/02/13 Python
python 默认参数相关知识详解
2019/09/18 Python
python中文分词库jieba使用方法详解
2020/02/11 Python
python字典和json.dumps()的遇到的坑分析
2020/03/11 Python
python实现图像全景拼接
2020/03/27 Python
Python SMTP配置参数并发送邮件
2020/06/16 Python
Python3如何使用多线程升程序运行速度
2020/08/11 Python
幼儿园中班开学寄语
2014/04/03 职场文书