节点接口

Webpack 提供了一个 Node.js API,可以在 Node.js 运行时直接使用。

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

安装

要开始使用 webpack Node.js API,首先安装 webpack(如果您还没有安装)。

npm install --save-dev webpack

然后在你的 Node.js 脚本中引入 webpack 模块

const webpack = require('webpack');

或者如果你更喜欢 ES2015

import webpack from 'webpack';

webpack()

导入的 webpack 函数会接收一个 webpack 配置对象,并在提供回调函数的情况下运行 webpack 编译器

const webpack = require('webpack');

webpack({}, (err, stats) => {
  if (err || stats.hasErrors()) {
    // ...
  }
  // Done processing
});

编译器实例

如果你不向 webpack 运行器函数传递回调函数,它将返回一个 webpack Compiler 实例。此实例可用于手动触发 webpack 运行器或让它构建并监视更改,就像 CLI 一样。Compiler 实例提供以下方法

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

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

Compiler 实例上的 hooks 属性用于将插件注册到 Compiler 生命周期中的任何挂钩事件。webpack 使用 WebpackOptionsDefaulterWebpackOptionsApply 实用程序来使用所有内置插件配置其 Compiler 实例。

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

运行

Compiler 实例上调用 run 方法类似于上面提到的快速运行方法。

const webpack = require('webpack');

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

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

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

观察

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

watch(watchOptions, callback);
const webpack = require('webpack');

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

const watching = compiler.watch(
  {
    // Example
    aggregateTimeout: 300,
    poll: undefined,
  },
  (err, stats) => {
    // Print watch/build result here...
    console.log(stats);
  }
);

Watching 选项的详细介绍请参见 此处

关闭 Watching

watch 方法返回一个 Watching 实例,该实例公开 .close(callback) 方法。调用此方法将结束观察。

watching.close((closeErr) => {
  console.log('Watching Ended.');
});

使 Watching 失效

使用 watching.invalidate,您可以手动使当前编译轮次失效,而不会停止观察过程。

watching.invalidate();

统计信息对象

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

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

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

stats 对象公开以下方法

stats.hasErrors()

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

stats.hasWarnings()

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

stats.toJson(options)

将编译信息作为 JSON 对象返回。options 可以是字符串(预设)或对象,以实现更细粒度的控制。

stats.toJson('minimal');
stats.toJson({
  assets: false,
  hash: true,
});

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

这是一个 示例,展示了此函数的输出。

stats.toString(options)

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

选项与 stats.toJson(options) 相同,但多了一个选项。

stats.toString({
  // Add console colors
  colors: true,
});

这是一个 stats.toString() 使用示例。

const webpack = require('webpack');

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

    console.log(
      stats.toString({
        chunks: false, // Makes the build much quieter
        colors: true, // Shows colors in the console
      })
    );
  }
);

MultiCompiler

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

var webpack = require('webpack');

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

错误处理

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

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

这是一个包含所有这些内容的示例。

const webpack = require('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);
    }

    // Log result...
  }
);

自定义文件系统

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

const { createFsFromVolume, Volume } = require('memfs');
const webpack = require('webpack');

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

compiler.outputFileSystem = fs;
compiler.run((err, stats) => {
  // Read the output later:
  const content = fs.readFileSync('...');
  compiler.close((closeErr) => {
    // ...
  });
});

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

10 位贡献者

sallarbyzykwizardofhogwartsEugeneHlushkolukasgeitertoshihidetagamichenxsanjamesgeorge007textbook