关于 webpack 你可能忽略的细节(附源码分析)

注:本篇不是入门教程,入门请直接查看官方文档。本篇的主要目标是经过实际问题来介绍 webpack 中容易被人忽略的细节, 以及源码分析(以最新发布的 release 版本1.14.0的源码为例), 而且提供几种解决方案。javascript

webpack from the official website

随着前端技术的火热发展,工程化,模块化和组件化的思想已逐步成为主流,与之相应的,就须要有一整套工具流能够支撑起它。前端

如今比较热门的前端资源模块化管理和打包工具应该非 Webpack 莫属了。java

Webpack 是什么

它能够将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还能够将按需加载的模块进行代码分隔,等到实际须要的时候再异步加载。经过 loader 的转换,任何形式的资源均可以视做模块,好比 CommonJs 模块、 AMD 模块、 ES6 模块、CSS、图片、 JSON、Coffeescript、 LESS 等。
--引自 Webpack 中文指南webpack

使用举例

咱们来看一下官方文档中的最小用例,新建并写入如下内容到这两个文件:git

cats.jsgithub

var cats = ['dave', 'henry', 'martha'];
module.exports = cats;

app.js (Entry Point)web

cats = require('./cats.js');
console.log(cats);

这个时候,就可使用 webpack 进行打包了:shell

webpack ./app.js app.bundle.js

咱们来看一下发生了什么, 目录下生成了一个打包后的文件 app.bundle.js ,这就是最基础的打包过程。npm

提出问题

如何判断打包是否成功?bash

通用方案

下面是咱们经常使用的两种判断任务是否执行成功的方案

经过 return code

经过命令执行后的 return code 来判断(在 shell 中使用 $? 得到)。 而且一般状况下 0 是执行成功, 非 0 是未成功。 咱们以上面的例子来测试一下:

webpack-demo.png

能够看到 $? 的值为 0 , 且打包后的文件运行正常。

那么咱们来修改一下 app.js 文件的内容, 将 require 引入的模块路径故意写错,来测试一下:

webpack-error.png

注意:箭头处 $? 的值仍然为 0, 且生成的打包后的文件运行出错。

这就说明,根据 return code 的值判断任务是否执行成功, 不可行!

经过标准错误输出

咱们也会经过标准错误输出stderr)来判断一个任务执行过程当中是否有错误输出。仍是使用上面的例子作示范:

webpack-stderr.png

根据这个例子,能够看到 webpack 并无标准错误输出!因此这个方法也不可行。

探究缘由及源码分析

这里以最新发布的 release 版本 1.14.0 的源码做为分析。 在 lib/Compilation.js 中咱们能够看到这样一段代码:

var errorAndCallback = function errorAndCallback(err) {
  err.dependencies = dependencies;
  err.origin = module;
  module.dependenciesErrors.push(err);
  _this.errors.push(err);
  if(bail) {
    callback(err);
  } else {
    callback();
  }
};

在源码中能够看到这个函数其实被调用的还比较多, 例如:在模块为可选的时候, 会判断只是抛出警告仍是处理错误, 而上面这段代码天然也没必要多数, 关键点在于 bail 的值, 而咱们继续找, 能够看到在 bin/config-optimist.js 中有对 bail 参数的解析, 这是一个布尔值。而由于没有太多描述, 因此这个参数就常常容易被忽略。

解决方案

1. 加 bail 参数

基于上面简要的分析, 咱们来尝试下 bail 参数的做用。 仍然使用上面的例子:

咱们使用 webpack --bail true app.js app.bundle.js 进行测试

webpack-bail.png

能够看到, 使用 bail 参数并传递 true 进去, 在遇到错误的时候,打包过程将会退出, return code1 且把错误信息打印到 stderr .

2. 使用 webpack-fail-plugin

webpack-fail-plugin 是专为解决这个问题而生的,它会在错误发生的时候 return 1. 使用方法也很简单:

安装:

npm install webpack-fail-plugin

使用:

var failPlugin = require('webpack-fail-plugin');
 
module.exports = {
    //config 
    plugins: [
        failPlugin
    ]
}

3.使用 done plugin

具体用法以下:

// ...
plugins: [ 
  // ... 
  function() { 
    this.plugin("done", function(stats) {
      if (stats.compilation.errors && stats.compilation.errors.length) {
        console.log(stats.compilation.errors); 
        process.exit(1); 
      }
      // ... 
    }); 
  }
// ...
],
// ...

4. 使用 webpack 2

不过 webpack 2 如今还在 beta 阶段,能够期待下。 (webpack 2 也仍然是使用 bail 参数)


能够经过下面二维码订阅个人文章
公众号【MoeLove】

公众号:MoeLove

相关文章
相关标签/搜索