知海

Node API

webpackjsorg-mainAPI 参考

Node API

webpack 提供了可以在 Node.js 运行时中直接使用的 Node.js API。

当您需要自定义构建或开发流程时,Node.js API 非常有用,因为所有的报告和错误处理都必须手动完成,webpack 仅负责编译部分。因此,stats 配置选项在 webpack() 调用中不会产生任何效果。

安装

要开始使用 webpack Node.js API,请先安装 webpack(如果尚未安装):

bash 复制代码
npm install --save-dev webpack

然后在您的 Node.js 脚本中导入 webpack 模块:

js 复制代码
import webpack from "webpack";

webpack()

导入的 webpack 函数接收一个 webpack 配置对象,如果提供了回调函数,则会运行 webpack 编译器:

js 复制代码
import webpack from "webpack";

webpack({}, (err, stats) => {
  if (err || stats.hasErrors()) {
    // ...
  }
  // 处理完成
});

T> err 对象不会包含编译错误。这些错误必须使用 stats.hasErrors() 单独处理,这将在本指南的错误处理部分详细介绍。err 对象仅包含与 webpack 相关的问题,例如配置错误等。

T> 您可以为 webpack 函数提供一个配置数组。有关更多信息,请参阅下面的 MultiCompiler 部分。

Compiler 实例

如果您没有向 webpack 运行函数传递回调,它将返回一个 webpack Compiler 实例。该实例可用于手动触发 webpack 运行器,或让它构建并监听文件变化,这与 CLI 类似。Compiler 实例提供以下方法:

  • .run(callback)
  • .watch(watchOptions, handler)

通常,只会创建一个主 Compiler 实例,尽管可以创建子编译器来委派特定任务。Compiler 本质上是一个函数,它执行最基本的功能以维持生命周期运行。它将所有的加载、打包和写入工作委托给已注册的插件。

Compiler 实例上的 hooks 属性用于将插件注册到 Compiler 生命周期中的任何钩子事件。WebpackOptionsDefaulterWebpackOptionsApply 工具被 webpack 用来配置其 Compiler 实例及所有内置插件。

Compiler 实例上的 platform 属性描述了从 target 解析出的目标环境。它是一个只读的平台标志对象(webbrowserwebworkernodeelectronnwjsdenobununiversal),当平台保持中立时,每个标志为 truefalsenull。插件和 loader 可以读取它以适应构建目标。从 webpack 5.108.0 开始,对于 target: "universal" 及等效的 target: ["web", "node"]platform.universaltrue

然后使用 run 方法启动所有编译工作。完成后,将执行给定的 callback 函数。统计信息和错误的最终日志记录应在此 callback 函数中完成。

W> 该 API 一次仅支持单个并发编译。当使用 runwatch 时,请调用 close 并等待其完成,然后再调用 runwatch。并发编译会损坏输出文件。

Run

调用 Compiler 实例上的 run 方法与上述快速运行方法类似:

js 复制代码
import webpack from "webpack";

const compiler = webpack({
  // ...
});

compiler.run((err, stats) => {
  // ...

  compiler.close((closeErr) => {
    // ...
  });
});

W> 不要忘记关闭编译器,以便低优先级的工作(如持久化缓存)有机会完成。

Watching

调用 watch 方法会触发 webpack 运行器,但之后会监听文件变化(类似于 CLI:webpack --watch),一旦 webpack 检测到更改,就会再次运行。返回一个 Watching 实例。

js 复制代码
watch(watchOptions, callback);
js 复制代码
import webpack from "webpack";

const compiler = webpack({
  // ...
});

const watching = compiler.watch(
  {
    // 示例
    aggregateTimeout: 300,
    poll: undefined,
  },
  (err, stats) => {
    // 在这里打印监视/构建结果...
    console.log(stats);
  },
);

Watching 选项在此处有详细说明。

W> 文件系统的不精确性可能导致单个更改触发多次构建。在上面的示例中,console.log 语句可能因一次修改而触发多次。用户应预期到这种行为,并可以检查 stats.hash 以查看文件哈希是否实际发生了变化。

关闭 Watching

watch 方法返回一个 Watching 实例,该实例暴露了 .close(callback) 方法。调用此方法将结束监视:

js 复制代码
watching.close((closeErr) => {
  console.log("监视已结束。");
});

W> 在现有的 watcher 被关闭或失效之前,不允许再次进行 watch 或 run 操作。

使 Watching 失效

使用 watching.invalidate,您可以手动使当前编译轮次失效,而无需停止监视过程:

js 复制代码
watching.invalidate();

Stats 对象

作为 webpack() 回调的第二个参数传入的 stats 对象,是有关代码编译过程信息的良好来源。它包含:

  • 错误和警告(如果有)
  • 耗时
  • 模块和块信息

webpack CLI 使用此信息在控制台中显示格式良好的输出。

T> 当使用 MultiCompiler 时,会返回一个 MultiStats 实例,它满足与 stats 相同的接口,即下面描述的方法。

stats 对象暴露了以下方法:

stats.hasErrors()

可用于检查编译过程中是否出现错误。返回 truefalse

stats.hasWarnings()

可用于检查编译过程中是否出现警告。返回 truefalse

stats.toJson(options)

以 JSON 对象的形式返回编译信息。options 可以是一个字符串(预设),也可以是一个对象,以实现更细粒度的控制:

js 复制代码
stats.toJson("minimal");
js 复制代码
stats.toJson({
  assets: false,
  hash: true,
});

所有可用的选项和预设都在 stats 文档 中描述。

以下是此函数输出的一个示例

stats.toString(options)

返回编译信息的格式化字符串(类似于 CLI 输出)。

选项与 stats.toJson(options) 相同,但还有一个额外的选项:

js 复制代码
stats.toString({
  // 添加控制台颜色
  colors: true,
});

以下是 stats.toString() 用法示例:

js 复制代码
import webpack from "webpack";

webpack(
  {
    // ...
  },
  (err, stats) => {
    if (err) {
      console.error(err);
      return;
    }

    console.log(
      stats.toString({
        chunks: false, // 使构建输出更简洁
        colors: true, // 在控制台中显示颜色
      }),
    );
  },
);

MultiCompiler

MultiCompiler 模块允许 webpack 在不同的编译器中运行多个配置。如果 webpack Node.js API 中的 options 参数是一个选项数组,webpack 将应用独立的编译器,并在所有编译器执行完毕后调用 callback

js 复制代码
import webpack from "webpack";

webpack(
  [
    { entry: "./index1.js", output: { filename: "bundle1.js" } },
    { entry: "./index2.js", output: { filename: "bundle2.js" } },
  ],
  (err, stats) => {
    process.stdout.write(`${stats.toString()}`);
  },
);

W> 多个配置不会并行运行。每个配置必须在前一个配置处理完成后才会开始处理。

错误处理

为了进行良好的错误处理,您需要考虑以下三种类型的错误:

  • 致命的 webpack 错误(配置错误等)
  • 编译错误(模块缺失、语法错误等)
  • 编译警告

以下是一个处理所有这些错误的示例:

js 复制代码
import webpack from "webpack";

webpack(
  {
    // ...
  },
  (err, stats) => {
    if (err) {
      console.error(err.stack || err);
      if (err.details) {
        console.error(err.details);
      }
      return;
    }

    const info = stats.toJson();

    if (stats.hasErrors()) {
      console.error(info.errors);
    }

    if (stats.hasWarnings()) {
      console.warn(info.warnings);
    }

    // 记录结果...
  },
);

自定义文件系统

默认情况下,webpack 使用常规文件系统从磁盘读取文件并将文件写入磁盘。但是,可以使用不同类型的文件系统(内存、WebDAV 等)来更改输入或输出行为。为此,可以更改 inputFileSystemoutputFileSystem。例如,您可以将默认的 outputFileSystem 替换为 memfs,以便将文件写入内存而不是磁盘:

js 复制代码
import { Volume, createFsFromVolume } from "memfs";
import webpack from "webpack";

const fs = createFsFromVolume(new Volume());
const compiler = webpack({
  /* 选项 */
});

compiler.outputFileSystem = fs;
compiler.run((err, stats) => {
  // 稍后读取输出:
  const content = fs.readFileSync("...");
  compiler.close((closeErr) => {
    // ...
  });
});

请注意,这正是 webpack-dev-middleware(被 webpack-dev-server 和许多其他包使用)用来神奇地隐藏您的文件但继续将它们提供给浏览器的机制!

T> 您提供的输出文件系统需要兼容 Node 自身的 fs 接口,这需要 mkdirpjoin 辅助方法。

帮助我们改进文档

发现翻译问题或内容错误?请告诉我们。