前端工程化之gulp


前端工程化是依据业务特点,将前端开发的规范、流程、技术、工具、经验等形成规范并建立成一种标准的体系。

构建工具的主要功能就是实现自动化处理,例如对代码进行检查、预编译、合并、压缩;生成雪碧图、sourceMap、版本管理;运行单元测试、监控等,当然有的工具还提供模块化、组件化的开发流程功能。

今天我们就来熟悉一款相对简单的构建工具——gulp。

一、gulp介绍

gulp的前身是grunt,它们都是基于任务运行的构建工具。与grunt相比,gulp显得更为高效更为简单了:

  • 更为高效:gulp利用 Node.js流的威力,可以快速构建项目并减少频繁的IO操作;
  • 更为简单:通过代码优于配置的策略,Gulp让简单的任务简单,复杂的任务可管理;
  • 易于上手:通过最少的 API,掌握 Gulp毫不费力,构建工作尽在掌握:如同一系列流管道。

gulp比较简单,入门容易,适合小的工程项目的构建。

二、gulp的安装

我们使用任何软件的第一步就是安装。

第一步gulp是基于node,所以我们第一步进行node的监检测:

node -v

如果你没有安装node,请移步到windows系统下如何安装多版本node,先进行node的安装;

第二步:正确安装node后,全局安装gulp,并检测是否安装成功

npm install -g gulp
....
....
gulp -v

第三步:切换到项目目录,局部安装gulp

npm init -y
...
npm install gulp -D
...

第四步gulp初体验

// 执行gulp命令
gulp
No gulpfile found
...

然后我们在项目根目录创建一个配置文件:gulpfile.js

// 执行gulp命令
var gulp = require('gulp');

gulp.task('default', function() {
  // 将你的默认的任务代码放在这
  console.log('我是默认任务')
});

至此,项目目录结构如下:

├── project_dir(项目根目录)
  ├── gulpfile.js(gulp配置文件)
  ├── node_modules
  │ └── gulp
  └── package.json

gulp的安装就结束了,这里为什么要全局和局部分别安装一次gulp呢?有人说是为了版本灵活,其实这不是主要的原因:

  • 全局安装:作为命令行工具,作为启动器,执行gulpfile.js中的任务

  • 本地安装:作为gulp的核心库,提供各种功能api,在gulpfile.js中使用

三、gulp的api

gulp简单易学,入门容易的一个原因得益于它的api够简单。满打满算它的api就那么十一二个,常用的api也就4个:

  • gulp.task():创建任务;
  • gulp.src():根据参数选择要处理的文件,并返回一个可以被pipe接收的虚拟文件对象流;
  • gulp.dest():能够接收pipe传出的流,并把流中的内容写入到文件中;
  • gulp.watch():监测文件,文件修改后,执行相关的任务操作;

在前面提到,gulpgrunt更高效,其中它们一个重要的因素在任务执行的时候的媒介不同:grunt是以文件为媒介进行任务的,它每进行一步就会把结果存入到一个临时文件中,来作为下一步的输入;gulp是以流为媒介进行额任务,它匹配到要处理的文件之后,生成相应的虚拟文件对象流,这个"流"流入到下一步任务,处理完之后继续生成相应的"流",直到任务结束,然后再输出到文件。

1、gulp.src():输入文件

用来匹配要处理的文件,并根据参数生成相应的流,其语法如下:

gulp.src(globs[, options])
  • globs:用来配文要处理的文件路径,包含文件名,采用的是node-glob语法,或者直接输入文件路径,语法有些类似正则,又有别于正则。可以是stringarray
  • options:生成文件流时的可选配置,通常我们不需要关注

下面我们来看几个例子:

// 匹配src/js文件夹下的所有直接包含的js
gulp.src('src/js/*.js')

// 匹配src/js文件夹下的所有js,包含js后代目录中的js文件
gulp.src('src/js/**/*.js')

/**
 *匹配src/js文件夹下的所有js,包含js后代目录中的js文件,
 *以及lib/js下的直接包含的js
 */ 
gulp.src(['src/js/**/*.js','lib/js/*.js'])

更多相关信息,请阅读gulp官网api。

2、gulp.dest():输出文件

gulp.dest()方法是用来写文件的,其语法为:

gulp.dest(path[,options])
  • path:文件将被写入的路径(输出目录)。也可以传入一个函数,在函数中返回相应路径;
  • options:可选输出配置参数,通常不需要关注;

这里要注意:path是路径,不包含文件名哦,生成的最终文件名,由gulp.src匹配到的文件决定,或者通过gulp-rename修改

例如:

var gulp = require('gulp');
gulp.src('lib/js/jquery.js')
    .pipe(gulp.dest('dist/foo.js'));
//最终生成的文件路径为 dist/foo.js/js/jquery.js,而不是dist/foo.js

3、gulp.task()

我们说gulp是任务型的工程化工具,那么如何创建任务呢?

语法如下:

gulp.task(name[, deps], fn)
  • name:当前要定义的任务名称
  • deps:可选参数,当前任务所依赖的其他任务列表
  • fn:当前任务要执行的操作

在我们编译一个项目的过程中,我们可能创建了多个任务:buildbuild_jsbuild_cssbuild_lib等,它们直接可能存在依赖,也能不存在依赖。

build依赖其他任务时:

//定义一个有依赖的任务
gulp.task('build',['build_js','build_css','build_lib'],function(){ 
  // build任务内容
});

当我们所依赖的任务是个异步任务时,我们需要异步操作完成才进行下一步,该怎么操作呢?有三种方式:

  • 回调的方式:给被依赖任务传入回调函数cb,异步操作完成后,调用cb

    //被依赖任务:cb为任务函数提供的回调,用来通知任务已经
    gulp.task('one',function(cb){ 完成
      //one是一个异步执行的任务
      setTimeout(function(){
        console.log('one is done');
        cb();  //执行回调,表示这个异步任务已经完成
      },5000);
    });
    
    //这时two任务会在one任务中的异步操作完成后再执行
    gulp.task('two',['one'],function(){
      console.log('two is done');
    });
    
  • 返回一个流

    gulp.task('somename', function() {
      var stream = gulp.src('client/**/*.js')
        .pipe(minify())
        .pipe(gulp.dest('build'));
      return stream;
    });
    
  • 返回一个promise

    var Q = require('q');
    
    gulp.task('somename', function() {
      var deferred = Q.defer();
      // 执行异步的操作
      setTimeout(function() {
        deferred.resolve();
      }, 1);
    
      return deferred.promise;
    });
    

4、gulp.watch()

用来监视文件的变化,当文件发生变化后,我们可以利用它来执行相应的任务,例如文件压缩等。其语法为:

gulp.watch(glob[, opts], tasks)
  • glob:匹配待监测的文件,同gulp.src参数
  • opts:可选的配置参数
  • tasks:任务列表,当文件变化时,需要执行的任务

四、常用插件

终于到了插件部分,插件才是王道,去gulp的官网扫了一眼,它的插件多达3772个,能满足你各种姿势各种需求。好了,我们先来上一个清单(package.json):

{
  "name": "16",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.1.6",
    "@babel/preset-env": "^7.1.6",
    "gulp": "^3.9.1",
    "gulp-babel": "^8.0.0",
    "gulp-concat": "^2.6.1",
    "gulp-cssmin": "^0.2.0",
    "gulp-imagemin": "^5.0.3",
    "gulp-less": "^4.0.1",
    "gulp-livereload": "^4.0.0",
    "gulp-rename": "^1.4.0",
    "gulp-sourcemaps": "^2.6.4",
    "gulp-uglify": "^3.0.1"
  }
}

看到了吗,一部分金黄色的字,那就是我们常用的插件,它们清一色的以"gulp-"开头,并且各司其职。

1、JS压缩插件:gulp-uglify

安装:

npm install gulp-uglify -D

使用:

const gulp = require('gulp');
const uglify = require('gulp-uglify'); //js压缩
const rename = require('gulp-rename'); // 重命名

// JS压缩重命名
gulp.task('js/*.js',() => {
  return gulp.src(js_path)
  .pipe(uglify())
  .pipe(rename({suffix: '.min'}))
  .pipe(gulp.dest('./build/'))
});

压缩js目录下的js文件,并保存到build目录下。这里使用了gulp-rename插件,重命名了文件名(给压缩后的文件加了后缀.min),更多gulp-rename的使用请查阅官网

没使用es6语法?不可能的,所以当说使用了es6gulp-uglify就显得不够用了,就要需要babel转换了。

2、ES6语法转换:gulp-babel

安装:

npm i gulp-babel @babel/core @babel/preset-env -D

使用:

// 编译es6
gulp.task('es6/*.js',() => {
  return gulp.src(js_path)
  .pipe(babel({
    presets:['@babel/env']
  }))
  .pipe(uglify())
  .pipe(rename({suffix: '.min'}))
  .pipe(gulp.dest('./build/es6'))
});

插件gulp-uglifygulp-babel满足了我们对js的压缩,可是在开发的时候,如果js报错了就麻烦了,因为压缩后的代码谁也不认识,变得不可追溯了。怎么办,用gulp-sourcemaps

3、资源图:gulp-sourcemaps

安装:

npm i gulp-sourcemaps -D

使用:

// 编译es6并记录map可调式追溯
// 注意sourcemap的位置
gulp.task('es6map',() => {
  return gulp
  .src('es6/*.js')
  .pipe(sourcemaps.init())
  .pipe(babel({
    presets:['@babel/env']
  }))
  .pipe(uglify())
  .pipe(rename({suffix: '.min'}))
  .pipe(sourcemaps.write())
  .pipe(gulp.dest('./build/es6map'))
});

有兴趣的话,可以去看看生成的sourcemap位置,看看如何生成独立的sourcemap文件。

4、处理图片文件:gulp-imagemin

适用范围:只能处理三种文件jpg/png/gif

安装:

npm i gulp-imagemin -D

使用:

// 处理图片
gulp.task('image',()=>{
  return gulp
  .src(['./src/img/**/*.jpg', './src/img/**/*.png', './src/img/**/*.gif'])
  .pipe(imgmin([
    imgmin.gifsicle({interlacd:true}),
    imgmin.jpegtran({progressive:true}),
    imgmin.optipng({optimizationLevel:5})
  ]))
  .pipe(gulp.dest('./build/img'))
})

我这里src写的比较繁琐,大家可以尝试着用node-glob写法

5、压缩css:gulp-cssmin

安装:

npm i gulp-cssmin -D

使用:

// 处理css
gulp.task('style',() => {
  return gulp
  .src(['./src/css/**/*.css'])
  .pipe(concat('style.min.css'))
  .pipe(cssmin())
  .pipe(gulp.dest('./build/css'))
})

6、处理less:gulp-less

安装:

npm i gulp-less -D

使用:

gulp.task('less', ()=>{
  return gulp
    .src(['./src/less/**/*.less'])
    .pipe(sourcemaps.init())
    .pipe(concat('main.less.min.css'))
    .pipe(less())
    .pipe(cssmin())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('./build/css/'));
});

sass的处理与less类似,只是插件不同而已,有需要可以去看看gulp-sass的使用。

你会发现在处理less的时候,使用了sourcemap。其实像这类插件gulp-rename、gulp-concat、gulp-sourcemaps,在很多地方都可以使用,它们跟语言没有多大关系。

7、html文件压缩gulp-minify-html

安装:

npm i gulp-minify-html -D

使用:

gulp.task('minify-html',()=> {
  return gulp.src('src/page/*.html') 
  .pipe(minifyHtml()) //压缩
  .pipe(gulp.dest('build/page'));
});

当然gulp-minify-html有很多配置参数:

const htmlConfig = {
  removeComments: true, //清除HTML注释
  collapseWhitespace: true, //压缩HTML
  collapseBooleanAttributes: true, //省略布尔属性的值 <input checked="true"/> ==> <input />
  removeEmptyAttributes: true, //删除所有空格作属性值 <input id="" /> ==> <input />
  removeScriptTypeAttributes: true, //删除<script>的type="text/javascript"
  removeStyleLinkTypeAttributes: true, //删除<style>和<link>的type="text/css"
  minifyJS: false, //压缩页面JS
  minifyCSS: false //压缩页面CSS
};

以上是我以前使用过的,其他的大家去官网查阅

最后我们来上一个高大上的插件:自动刷新

8、自动刷新:gulp-livereload

这个插件是用来自动刷新的,代码修改保存后,浏览器自动刷新。当然该插件最好配合谷歌浏览器使用,需要安装一个浏览器端的插件:livereload_2_1_0_0.crx

安装:

npm i gulp-livereload -D

使用:

const js_path=['./src/js/**/*.js'];

gulp.task('js', ()=>{
  return gulp
    .src(js_path)
    .pipe(babel({
      presets: ['@babel/env']
    }))
    .pipe(concat('bundle.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./build/js'))
    .pipe(livereload());
});

gulp.task('watch', ()=>{
  //开启livereload的服务
  livereload.listen();

  //重新编译JS
  gulp.watch(js_path, ['js']);

  //监听html;标记文件修改
  gulp.watch([
    './1.html',
    ...js_path
  ], file=>{
    livereload.changed(file.path);
  });
});

gulp.task('default', ['js', 'watch']);

你会发现default任务里面先执行了一遍js任务,是因为watch任务只有在文件变化的时候,它才会执行。

别忘记了在浏览器里面安装插件,并开启相应功能哦。

到此为止,我们也就生成了开始时候的清单了。

五、兼容性

当你在执行gulp默认任务的时候:

gulp

有可能你会发现,没法执行,还报了错,别急,这是版本之间的兼容性导致的。

进入官方文档查看,官方的意思是,4.0.0版本的,“default”右边两个参数放在gulp.series()的参数中,否则会报错。所以自己去改改吧

以上是我几次gulp使用后的一些总结,有不对的地方,请斧正,欢迎关注同步公众号在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: JavaScript 前端工程化是一种使用工具和流程来提高前端开发效率和质量的方法。它可以帮助我们管理项目构建、模块化、测试、部署等流程,使前端开发更加高效和可维护。 一些常用的前端工程化工具包括: - 包管理器:如 npm 或 yarn,用于管理项目依赖的第三方库和工具。 - 构建工具:如 Webpack 或 Rollup,用于将源代码转换为浏览器可以运行的代码,并且可以做一些优化,如代码压缩、模块化、自动添加浏览器前缀等。 - 自动化测试工具:如 Jest、Mocha 或 Karma,用于自动执行单元测试和集成测试,保证代码的质量和稳定性。 - 部署工具:如 Git、Jenkins 等,用于将项目发布到线上环境。 前端工程化还可以通过使用规范和框架来提高代码质量和团队协作效率。例如,使用 lint 工具来检查代码规范,使用框架如 React、Vue 或 Angular 来组织代码结构。 总之,JavaScript 前端工程化是一种使用工具和流程来提高前端开发效率和质 ### 回答2: JavaScript 前端工程化是一种通过工具和实践来提高前端开发效率和质量的方法。它涉及到对代码、资源和工作流程的管理和优化,旨在满足在复杂的前端项目中面临的挑战。 首先,JavaScript 前端工程化通过模块化来组织和管理代码。使用模块化的方式可以将代码分割成独立的模块,各模块之间可以互相依赖和复用。这样可以提供更好的代码可维护性和复用性,同时也可以避免全局命名冲突和代码碎片化的问题。常用的模块化技术包括 ES6 的模块化语法和模块打包工具,如Webpack。 其次,JavaScript 前端工程化通过自动化构建工具来提高开发效率。通过使用构建工具,我们可以自动完成编译、压缩、合并等繁琐的操作,减少手动操作的时间和错误。常见的构建工具有Grunt、Gulp和Webpack,它们可以根据配置文件自动执行各种任务,并生成优化后的静态文件。 另外,JavaScript 前端工程化还涉及到代码规范和质量保证。通过使用代码规范工具如ESLint,并制定团队统一的代码规范,可以提高团队协作的效率,减少潜在的问题。同时,结合自动化测试工具如Jest、Mocha等,可以实现代码的自动化测试,确保代码质量和稳定性。 最后,JavaScript 前端工程化还可以提供更好的代码部署和发布机制。通过使用持续集成工具如Jenkins,可以自动部署代码到测试和生产环境,提高交付速度和稳定性。同时,还可以使用版本控制工具如Git,实现多人协作和代码版本管理。 总之,JavaScript 前端工程化通过模块化、自动化构建、代码规范和质量保证、代码部署等方式来提高前端开发效率和质量。在现代化的前端开发中,工程化已经成为不可或缺的组成部分,帮助开发者应对复杂的需求和挑战。 ### 回答3: JavaScript前端工程化是一种以提高开发效率、代码质量和项目可维护性为目标的开发方法。它借助工具和规范化的工作流程,帮助开发人员更好地组织、管理和部署JavaScript代码。 前端工程化的核心是模块化。通过使用模块化开发,前端代码可以按照功能进行划分,每个功能模块都拥有独立的代码和依赖关系,使得开发和维护变得更加容易。常用的模块化规范有CommonJS和ES6模块。 另一个关键概念是构建工具。构建工具可以帮助自动化完成一系列任务,如代码合并、压缩、转换、静态资源管理等。常用的构建工具有Webpack和Rollup。这些工具可以根据配置文件自动处理代码,减少手动操作,提高开发效率。 除此之外,前端工程化还包括自动化测试、性能优化和代码规范等方面。自动化测试可以帮助开发人员编写和运行测试用例,确保代码的正确性。性能优化可以通过压缩代码、懒加载和CDN加速等方式提高页面性能。代码规范则可以统一代码风格,提高代码的可读性和可维护性。 总的来说,JavaScript前端工程化是一种通过使用模块化、构建工具和自动化测试等方法,提高前端代码开发效率和质量的开发方法。它可以帮助开发人员更好地组织和管理代码,减少手动操作,提高开发效率和项目可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值