Javascript五十问——从源头细说Webpack与Gulp

前言:Webpack 与 gulp是目前圈子内比较活跃的前端构建工具。网上有很多二者比较的文章,面试中也会经常遇到gulp,Webpack的区别这样的问题。对于初学者来说,对这二者往往容易认识不清,今天,就从事件的源头,说清楚Webpack与gulp。

Gulp

那是2014年,虽然JQuery风光多年,但是前端却暗流涌动;MVVM刚刚提出不久,Angular快速成长,而React和Vue也刚刚开源不到一年,尚属于冷门小语种。那个时候,前端工作者面临的主要矛盾在于日益增长的业务复杂化的需求落后低效率的前端部署。开发工作者为了发布一个网站,往往会重复的进行一些与开发无关的工作,手动完成这些工作会带来很大的挫败感。这个时候,自动化构建工具及应运而生,gulp就是在大浪淘沙中的胜利者。

Gulp是基于流的前端构建工具,nodejs的stream操作来读取和操作数据;可以实现文件的转换,压缩,合并,监听,自动部署等功能。gulp拥有强大的插件库,基本上满足开发需求,而且开发人员也可以根据自己的需求开发自定义插件。难得是,gulp只有五个api,容易上手。

const gulp = require('gulp');
const sass = require("gulp-sass")

gulp.task("sassStyle",function() {
    gulp.src("style/*.scss")
        .pipe(sass())
        .pipe(gulp.dest("style"))
})

上面就是一个基本的gulpfile配置文件,实现了scss文件到css文件的转换;在终端输入gulp sassStyle就能够进行文件处理了。
对于gulp而言,会有一个task,这个task只会做一件事,比如将sass格式的文档转换成css文件;对于一个task而言,会有一个入口文件,即gulp.src,最会有一个目标文件,即gulp.dest;一入一出,可以将gulp理解为 一元函数,输入一个x,根据funcion产出一个y

Gulp简单,快速,自动化的构建方案,收获了很多开发者的喜爱。但是怎样的机遇,让webpack占据了前端工程化的半壁江山呢?

Webpack

解决方案永远是紧跟需求的脚步的。随着React与Vue份额越来越大,spa开发模式应用在越来越多的领域中,而ES6 Module语法的提出与大规模应用,模块化开发方式越来越受人们的青睐。致使前端文件之间的依赖性越来越高,这时候就需要一个工具能够解析这些依赖,并且将它们有条理的打包起来,优化请求,最好顺便能够解析成浏览器可以识别的语言——这正是webpack所承担的工作;而很多开发者,也是从react或者vue的项目入手webpack的。

Javascript五十问——从源头细说Webpack与Gulp
图片来源于互联网,侵删

Webpack 是前端资源模块化 管理打包工具。它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分割,等到实际需要的时候再异步加载——来自Webpack官方网站。
所以Webpack只完成两件事:按需加载,打包。

module.exports = {
  // 入口文件,是模块构建的起点,同时每一个入口文件对应最后生成的一个 chunk。
  entry: {
    bundle: [
      'webpack/hot/dev-server',
      'webpack-dev-server/client?http://localhost:8080',
      path.resolve(__dirname, 'app/app.js')
    ]
  },
  // 文件路径指向(可加快打包过程)。
  resolve: {
    alias: {
      'react': pathToReact
    }
  },
  // 生成文件,是模块构建的终点,包括输出文件与输出路径。
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: '[name].js'
  },
  // 这里配置了处理各模块的 loader ,包括 css 预处理 loader ,es6 编译 loader,图片处理 loader。
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel',
        query: {
          presets: ['es2015', 'react']
        }
      }
    ],
    noParse: [pathToReact]
  },
  // webpack 各插件对象,在 webpack 的事件流中执行对应的方法。
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ]
};

上面是比较简单的webpack配置文件 webpack.config.js,如果说gulp是一个一元函数,那么,webpack就是一个多元函数或者是加工厂;webpack从入口文件开始,递归找出所有依赖的代码块,再将代码块按照loader解析成新内容,而在webpack会在各个特定的时期广播对应事件,插件会监听这些事件,在某个事件中进行特定的操作。通俗一点来说,webpack本身来递归找到各个文件之间的依赖关系,在这个过程中,使用loaders对文件进行解析,最后,在各个不同的事件阶段,插件可以对文件进行一个统一的处理。

webpack.config文件会包括以下几部分:

1.entry:入口,webpack问此文件入手迭代。
2.output: 打包后形成的文件出口。
3.module: 模块,在webpack中一个模块对应一个文件。webpack会从entry开始,递归找出所有依赖的模块
4.loaders:文件解析的各种转换器
5.plugin:拓展插件

webpack的配置文件和构建方式比较复杂,这里不再赘述,感兴趣的同学可以参考我列出来的参考文献第三篇文章,或者可以关注我的专栏,后期我会出一篇关于webpack的学习笔记。

比较

所以,我们可以看出来,虽然Webpack与gulp都是前端工程化的管理工具,但是二者的侧重点不同——gulp更加关注的是自动化的构建工具,你把代码写好了,gulp会帮你编译、压缩、解析。而Webpack关注的是在模块化背景下的打包工作;它侧重的还是如何将依赖的文件合理的组织起来,并且实现按需加载。

总结

总的来说,虽然webpack以打包起家,但是gulp能够实现的功能,Webpack也能做;那么,是不是我们以后都要唯webpack马首是瞻呢?非也,非也!webpack功能强大,但是它的缺点也来自于此;webpack并非一个轻量级的工具,学习曲线也非gulp那般平缓。曾经,gulp为了弥补js打包方面的不足,也有gulp-webpack插件的出现;但是webpack强大如斯,如果仅仅只是解析es6文件,未免有大马拉小车之感。
根据我的项目实践经验,如果你要构建一个复杂的项目,项目使用vue或者react,模块化引领,那么请选择Webpack,Webpack天生模块化,更加适合于SPA的应用场景,而gulp在SPA下明显后力不足。如果你只是开发一个工具,请选择gulp,至于js打包这种工作,有更加专一的rollup。毕竟,如果只是写一个年会抽奖工具活跃气氛,就不需要webpack火种送碳了。

总结下来:gulp与Webapck是各有所长,并不存在东风压倒西风,而在前端工程化的大旗下,并非只有Webpack与gulp,我们还能看到rollupbrowserify的一席之地。因此,在真正的工作中,还是要结合项目本身特点,切忌人云亦云

参考文献

1、JavaScript开发者的工具箱 非常实用
2、Gulp官网
3、超级详细的Webpack解读—五星推荐
4、端构建工具之争——Webpack vs Gulp 谁会被拍死在沙滩上—五星推荐

相关推荐