返回介绍

Node.js API

发布于 2019-05-27 04:54:16 字数 20703 浏览 1084 评论 0 收藏 0

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

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

安装(Installation)

开始使用 webpack 的 Node.js API 之前,首先你需要安装 webpack:

npm install --save-dev webpack

然后在 Node.js 脚本中 require webpack module:

const webpack = require("webpack");

// 或者如果你喜欢 ES2015:
import webpack from "webpack";

webpack()

导入的 webpack 函数需要传入一个 webpack 配置对象,当同时传入回调函数时就会执行 webpack compiler:

const webpack = require("webpack");

webpack({
  // [配置对象](/configuration/)
}, (err, [stats](#stats-object)) => {
  if (err || stats.hasErrors()) {
    // [在这里处理错误](#-error-handling-)
  }
  // 处理完成
});

T> 编译错误err 对象内,而是需要使用 stats.hasErrors() 单独处理,你可以在指南的 错误处理 部分查阅到更多细节。err 对象只会包含 webpack 相关的问题,比如配置错误等。

T> 你可以向 webpack 函数提供一个由配置选项对象构成的数组。更多详细信息,请查看 MultiCompiler 章节。

Compiler 实例(Compiler Instance)

如果你不向 webpack 执行函数传入回调函数,就会得到一个 webpack Compiler 实例。你可以通过它手动触发 webpack 执行器,或者是让它执行构建并监听变更。和 CLI API 很类似。Compiler 实例提供了以下方法:

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

通常情况下,虽然可以创建一些子 compiler 来代理到特定任务,然而只会创建一个主要 Compiler 示例。Compiler 基本上只是执行最低限度的功能,以维持生命周期运行的功能。它将所有的加载、打包和写入工作,都委托到注册过的插件上。

Compiler 实例上的 hooks 属性,用于将一个插件,注册到 Compiler 的生命周期中的所有钩子事件上。webpack 使用 [WebpackOptionsDefaulter] (https://github.com/webpack/webpack/blob/master/lib/WebpackOptionsDefaulter.js) 和 WebpackOptionsApply 这两个工具,通过所有内置插件,来配置 Compiler 实例。

run 方法用于触发所有编译时工作。完成之后,执行给定的 callback 函数。最终记录下来的概括信息(stats)和错误(errors),应该在这个 callback 函数中获取。

W> 这个 API 一次只支持一个并发编译。当使用 run 时,会等待它完成后,然后才能再次调用 runwatch。当使用 watch 时,调用 close,等待它完成后,然后才能再次调用 runwatch。多个并发编译会损坏输出文件。

执行(run)

调用 Compiler 实例的 run 方法跟上文提到的快速执行方法很相似:

const webpack = require("webpack");

const compiler = webpack({
  // [配置对象](/configuration/)
});

compiler.run((err, [stats](#stats-object)) => {
  // ...
});

监听(watching)

调用 watch 方法会触发 webpack 执行器,但之后会监听变更(很像 CLI 命令: webpack --watch),一旦 webpack 检测到文件变更,就会重新执行编译。该方法返回一个 Watching 实例。

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

const compiler = webpack({
  // [配置对象](/configuration/)
});

const watching = compiler.watch({
  // [watchOptions](/configuration/watch/#watchoptions) 示例
  aggregateTimeout: 300,
  poll: undefined
}, (err, [stats](#stats-object)) => {
  // 在这里打印 watch/build 结果...
  console.log(stats);
});

Watching 配置选项的细节可以在 这里 查阅。

W> 文件系统不正确的问题,可能会对单次修改触发多次构建。因此,在上面的示例中,一次修改可能会多次触发 console.log 语句。用户应该预知此行为,并且可能需要检查 stats.hash 来查看文件哈希是否确实变更。-

关闭 Watching(Close Watching)

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

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

T> 不允许在当前监听器已经关闭或失效前再次监听或执行。

作废 Watching(Invalidate Watching)

使用 watching.invalidate,你可以手动使当前编译循环(compiling round)无效,而不会停止监视进程:

watching.invalidate();

Stats 对象(Stats Object)

stats 对象会被作为 webpack() 回调函数的第二个参数传入,可以通过它获取到代码编译过程中的有用信息,包括:

  • 错误和警告(如果有的话)
  • 计时信息
  • module 和 chunk 信息

webpack CLI 正是基于这些信息在控制台展示友好的格式输出。

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

stats 对象暴露了以下方法:

stats.hasErrors()

可以用来检查编译期是否有错误,返回 truefalse

stats.hasWarnings()

可以用来检查编译期是否有警告,返回 truefalse

stats.toJson(options)

以 JSON 对象形式返回编译信息。options 可以是一个字符串(预设值)或是颗粒化控制的对象:

stats.toJson("minimal"); // [更多选项如: "verbose" 等](/configuration/stats).
stats.toJson({
  assets: false,
  hash: true
});

所有可用的配置选项和预设值都可查询 stats 文档

这里有一个该函数输出的 示例

stats.toString(options)

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

配置对象与 stats.toJson(options) 一致,除了额外增加的一个选项:

stats.toString({
  // 增加控制台颜色开关
  colors: true
});

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

const webpack = require("webpack");

webpack({
  // [配置对象](/configuration/)
}, (err, stats) => {
  if (err) {
    console.error(err);
    return;
  }

  console.log(stats.toString({
    chunks: false,  // 使构建过程更静默无输出
    colors: true    // 在控制台展示颜色
  }));
});

MultiCompiler

MultiCompiler 模块可以让 webpack 在单个 compiler 中执行多个配置。如果传给 webpack 的 Node.js API 的 options 参数,是一个由配置对象构成的数组,则 webpack 会应用单独 compiler,并且在每次 compiler 执行结束时,都会调用 callback 方法。

var webpack = require('webpack');

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

W> 多个配置对象在执行时,不会并行执行。每个配置都只会在前一个处理结束后,才进行处理。想要并行处理,你可以使用第三方解决方案,例如 parallel-webpack

错误处理(error handling)

完备的错误处理中需要考虑以下三种类型的错误:

  • 致命的 wepback 错误(配置出错等)
  • 编译错误(缺失的 module,语法错误等)
  • 编译警告

下面是一个覆盖这些场景的示例:

const webpack = require("webpack");

webpack({
  // [配置对象](/configuration/)
}, (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);
  }

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

自定义文件系统(Custom File Systems)

默认情况下,webpack 使用普通文件系统来读取文件并将文件写入磁盘。但是,还可以使用不同类型的文件系统(内存(memory), webDAV 等)来更改输入或输出行为。为了实现这一点,可以改变 inputFileSystemoutputFileSystem。例如,可以使用 memory-fs 替换默认的 outputFileSystem,以将文件写入到内存中,而不是写入到磁盘:

const MemoryFS = require("memory-fs");
const webpack = require("webpack");

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

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

值得一提的是,被 webpack-dev-server 及众多其他包依赖的 webpack-dev-middleware 就是通过这种方式,将你的文件神秘地隐藏起来,但却仍然可以用它们为浏览器提供服务!

T> 你指定的输出文件系统需要兼容 Node 自身的 fs 模块接口,接口需要提供 mkdirpjoin 工具方法。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文