1. webpack 是什么?

1. 介绍 - 图1

先来说一下 webpack 是什么。

webpack 的官方对它是这样定义的:

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

中文的大概意思是说:

webpack 可以看做是模块打包机:它做的事情是,分析你的项目结构,找到 JavaScript 模块以及其它的一些浏览器不能直接运行的拓展语言(ScssTypeScript 等),并将其转换和打包为合适的格式供浏览器使用。

用大白话可以这样说:

webpack是一个前端模块化方案,更侧重模块打包,我们可以把开发中的所有资源(图片、js 文件、css 文件等)都看成模块,通过 loader(加载器)和 plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源。

如果这样还不明白的话,我们来说下前因后果。

在当今的社会,作为 web 开发,会越来越意识到前端的重要性,随着 HTML5CSS3ES6 各种技术的发展,前端的开发越来越宠大。甚至有些应用就是单页面应用(SPA),纯 JavaScript 开发,JavaScript 文件的管理也是一个问题。JavaScript 模块化编程,已经成为一个迫切的需求,这就出现了 JavaScript 的模块解决方案,以前是用 requirejsseajs,而现在则是用 webpack

举个例子,很多人开发了各种优秀的 JavaScript 模块或组件,我们不想重复发明轮子,而是想直接利用别人的模块,就是类似 requireinclude 这样的机制,把别人的模块引入进来,但是 JavaScript 又没有 这样的概念,那应该如何做呢?

如何去引入别人的模块?引入之后保证各种依赖关系不出错?这就是 webpack 要解决的问题。

模块化的概念我们理解了,那如何理解 打包 这个词呢?

其实,模块化的问题解决之后,webpack 就能把各种资源模块打包合并成一个文件输出给浏览器。在打包的过程中还能对这些资源进行处理,比如压缩减少体积,把 sass 编译成 css, coffee 编译成 js。所以它在某些程度上,跟 grunt/gulp 的功能有些相同。至于与 grunt/gulp 的不同之处,我们下面会讲到。

2. 与 grunt/gulp 的区别

grunt/gulp 的定义是 Task Runner。它有点像 rubyRakeThor,如果你不懂 ruby,那 c/cpp语言的 make,这应该总知道吧。它是一种写任务的工具,只是 grunt/gulp 是用 JavaScript 来写 task 而已。

grunt/gulp 强调的是前端开发的工作流程,我们可以通过配置一系列的 task,定义 task 处理的事务(例如文件压缩合并、雪碧图、启动 server、版本控制等),然后定义执行顺序,来让 grunt/gulp 执行这些 task,从而构建项目的整个前端开发流程。

  1. const gulp = require('gulp');
  2. const babel = require('gulp-babel');
  3. // gulp.src 会指定源文件,然后通过 pipe 函数把内容传给下个处理方法,最后 gulp.dest 是输出处理后的文件内容。
  4. gulp.task('default', () =>
  5. gulp.src('src/app.js')
  6. .pipe(babel({
  7. presets: ['es2015']
  8. }))
  9. .pipe(gulp.dest('dist'))
  10. );

打个比方,如果你的工程模块依赖很简单,不需要把 js 或各种资源打包,只需要简单的合并、压缩,那就不需要 webpack。grunt/gulp 就够用了。反过来,如果你的工程庞大,页面中使用了很多库(SPA很容易出现这种情况),那就可以选择使用 webpack,因为这样既能做到模块化管理,也能做到 grunt/gulp 的一些功能,比如压缩,转化 coffeescriptjs 等。

gulp 也能和 webpack 结合起来用,gulp 里面有个 webpack-stream 插件。就是让 webpack 专门去做 module dependency 的事情, 生成一个 bundle.js 文件,然后再用 gulp 去做一些其他杂七杂八 minify, uglify 的事情。 后来人们发现 webpack 有个 plugins 的选项, 可以用来进一步处理经过 loader 生成的 bundle.js,于是有人写了对应的插件, 所以 minify/uglify, 生成 hash 的工作也可以转移到 webpack 本身了,挤掉了 gulp 这部分的市场份额。 再后来大家有发现 npm/package.json 里面的 scripts 原来好好用啊,调用任务的时候就直接写一个简单的命令,因为 gulp 也不就是各种插件命令的组合呀,大部分情况下越来越不需要 gulp/grunt 之类的了。 所以你现在看到的很多新项目都是package.json 里面 scripts 写了一堆,外部只需要一个 webpack 就够了。(摘自网络 https://segmentfault.com/q/1010000008058766)

最后总结一下:

虽然都是前端自动化构建工具,但看他们的定位就知道不是对等的。

grunt/gulp 严格上讲,模块化不是他强调的东西,他旨在规范前端开发流程。

webpack 更是明显强调模块化开发,而那些文件压缩合并、预处理等功能,不过是他附带的功能。

3. 跟 Browserify 相比

webpack 与其和 grunt/gulp 相比较,还不如跟 Browserify 比较,因为它们两者更相近,不过好像 Browserify 应该被 webpack 代替了吧,我对 Browserify 了解也不多,在此就不细说了。

4. 优势

  1. webpack 不仅仅能处理 js, 也能处理 css, 也能处理 html,甚至是图片等各种前端资源。

  2. 它开发便捷,仅仅使用一个配置文件,就能替代部分 grunt/gulp 的工作,比如打包、压缩混淆、图片转 base64等。

  3. 扩展性强,插件机制完善。

5. 为什么要学习 webpack

现在最流行的 reactvueangular 等技术,你要学习和使用它们,难免会碰到 webpack,因为一般都会用 webpack 来构建前端的开发环境,这样,我们还有什么理由不学习呢?