Compiler

webpack 的 Compiler 模块是主引擎,它通过 webpack CLI 或 webpack API 或 webpack 配置文件传递的所有选项,创建出一个 compilation 实例。

它通过 webpack API 下 webpack.Compiler 的导出。

webpack 使用它来实例化 compiler,然后调用 run 方法。下面是一个可以使用 Compiler 简单示例。事实上,这与 webpack 自身是如何调用它非常接近。

compiler-example

// 可以从 webpack package 中 import 导入
import {Compiler} from 'webpack';

// 创建一个新的 compiler 实例
const compiler = new Compiler();

// 填充所有必备的 options 选项
compiler.options = {...};

// 创建一个插件
class LogPlugin {
  apply (compiler) {
    compiler.plugin('should-emit', compilation => {
      console.log('should I emit?');
      return true;
    })
  }
}

// 将 compiler 应用到插件中
new LogPlugin().apply(compiler);

/* 添加其他支持插件 */

// 运行结束后执行回调
const callback = (err, stats) => {
  console.log('Compiler 已经完成执行。');
  // 显示 stats……
};

// compiler 的 run 调用,并传入 callback
compiler.run(callback);

Compiler 也是我们所说的 Tapable 实例。通过这种实现机制,我们可以理解为,它混合(mix)了 Tapable 类,来使实例也具备注册和调用插件功能。大多数面向用户的插件,要首先在 Compiler 上注册。Compiler 运行机制可以被提取为以下要点

  • 通常有一个 Compiler 的主实例。可以创建子 compilers 来委托特定任务。
  • 创建 compiler 的多数复杂度,在于为它填充所有相关的 options 选项。
  • webpack 通过 WebpackOptionsDefaulterWebpackOptionsApply,来专门为 Compiler 提供所需的所有初始数据。
  • Compiler 是一个执行最简功能,来保证生命周期运行的函数。它把所有的加载(loading)/打包(bundling)/写入(writing)工作委托给各种插件。
  • new LogPlugin(args).apply(compiler) 将插件注册到 Compiler 生命周期中的任何特定钩子事件。
  • Compiler 暴露 run 方法,它启动了 webpack 所有编译工作。在执行完成后,会调用传递给它的 callback 函数。记录 stats 和 errors 的所有末端工作,都在此回调函数中完成。

监听文件变化并重新编译(watching)

Compiler 支持“观察模式(watch mode)”,可以监控文件系统并在文件更改时重新编译。在观察模式下,compiler 将触发额外的 "watch-run", "watch-close" 和 "invalid" 事件。这通常用于开发环境中,并且一般在 webpack-dev-server 等工具的底层触发,以使开发人员无须每次手动重新编译。

关于观察模式的更多细节,请查看 Node.js API 文档CLI 的 watch 选项

MultiCompiler

MultiCompiler 模块允许 webpack 在单个 compiler 中运行多个配置。 如果 webpack 的 NodeJS API 中的 options 参数,是一个由 options 构成的数组,则 webpack 会对其应用单个 compiler,并在所有 compiler 执行结束时,调用 callback 方法。

var webpack = require('webpack');

var config1 = {
  entry: './index1.js',
  output: {filename: 'bundle1.js'}
}
var config2 = {
  entry: './index2.js',
  output: {filename:'bundle2.js'}
}

webpack([config1, config2], (err, stats) => {
  process.stdout.write(stats.toString() + "\n");
})

事件钩子

一个参考指南,列出 Compiler 暴露的所有事件钩子。

事件名称
内容说明
参数
类型
事件名称
entry-option
内容说明
-
参数
-
类型
bailResult
事件名称
after-plugins
内容说明
设置完一组初始化插件之后
参数
compiler
类型
sync
事件名称
after-resolvers
内容说明
设置完 resolvers 之后
参数
compiler
类型
sync
事件名称
environment
内容说明
-
参数
-
类型
sync
事件名称
after-environment
内容说明
环境设置完成
参数
-
类型
sync
事件名称
before-run
内容说明
compiler.run() 开始
参数
compiler
类型
async
事件名称
run
内容说明
在读取记录之前
参数
compiler
类型
async
事件名称
watch-run
内容说明
在开始编译之前,watch 之后
参数
compiler
类型
async
事件名称
normal-module-factory
内容说明
创建出一个 NormalModuleFactory 之后
参数
normalModuleFactory
类型
sync
事件名称
context-module-factory
内容说明
创建出一个 ContextModuleFactory 之后
参数
contextModuleFactory
类型
sync
事件名称
before-compile
内容说明
compilation 的参数已创建
参数
compilationParams
类型
async
事件名称
compile
内容说明
在创建新 compilation 之前
参数
compilationParams
类型
sync
事件名称
this-compilation
内容说明
在触发 compilation 事件之前
参数
compilation
类型
sync
事件名称
compilation
内容说明
compilation 创建完成
参数
compilation
类型
sync
事件名称
make
内容说明
-
参数
compilation
类型
parallel
事件名称
after-compile
内容说明
-
参数
compilation
类型
async
事件名称
should-emit
内容说明
此时可以返回 true/false
参数
compilation
类型
bailResult
事件名称
need-additional-pass
内容说明
-
参数
-
类型
bailResult
事件名称
emit
内容说明
在生成资源并输出到目录之前
参数
compilation
类型
async
事件名称
after-emit
内容说明
在生成资源并输出到目录之后
参数
compilation
类型
async
事件名称
done
内容说明
完成编译
参数
stats
类型
sync
事件名称
failed
内容说明
Failure of compile
参数
error
类型
sync
事件名称
invalid
内容说明
在无效的 watch 编译之后
参数
fileName, changeTime
类型
sync
事件名称
watch-close
内容说明
在停止 watch 编译之后
参数
-
类型
sync

用法

下面是一个异步的 emit 事件处理函数的示例:

compiler.plugin("emit", function(compilation, callback) {
  // 执行一些异步……
  setTimeout(function() {
    console.log("异步运行完成……");
    callback();
  }, 1000);
});

原文:https://webpack.js.org/api/compiler/


贡献人员