构建


【Building】

一旦源代码编写完成,就必须将其编译成二进制 addon.node 文件。为此,在项目的顶层创建一个名为 binding.gyp 的文件,使用类似 JSON 的格式描述模块的构建配置。这个文件由 node-gyp 使用,这是一款专门用于编译 Node.js 插件的工具。

【Once the source code has been written, it must be compiled into the binary addon.node file. To do so, create a file called binding.gyp in the top-level of the project describing the build configuration of the module using a JSON-like format. This file is used by node-gyp, a tool written specifically to compile Node.js addons.】

{
  "targets": [
    {
      "target_name": "addon",
      "sources": [ "hello.cc" ]
    }
  ]
} 

node-gyp 工具的一个版本打包在 Node.js 中,并作为 npm 的一部分分发。此版本不会直接提供给开发者使用,仅用于支持使用 npm install 命令来编译和安装插件的功能。希望直接使用 node-gyp 的开发者可以通过命令 npm install -g node-gyp 来安装。有关更多信息,包括平台特定的要求,请参见 node-gyp 文档。

【A version of the node-gyp utility is bundled and distributed with Node.js as part of npm. This version is not made directly available for developers to use and is intended only to support the ability to use the npm install command to compile and install addons. Developers who wish to use node-gyp directly can install it using the command npm install -g node-gyp. See the node-gyp installation instructions for more information, including platform-specific requirements.】

一旦创建了 binding.gyp 文件,使用 node-gyp configure 来生成当前平台的适当项目构建文件。这将在 build/ 目录中生成一个 Makefile(在 Unix 平台上)或 vcxproj 文件(在 Windows 上)。

【Once the binding.gyp file has been created, use node-gyp configure to generate the appropriate project build files for the current platform. This will generate either a Makefile (on Unix platforms) or a vcxproj file (on Windows) in the build/ directory.】

接下来,执行 node-gyp build 命令来生成编译后的 addon.node 文件。该文件将被放置在 build/Release/ 目录下。

【Next, invoke the node-gyp build command to generate the compiled addon.node file. This will be put into the build/Release/ directory.】

在使用 npm install 安装 Node.js 插件时,npm 会使用其自带的 node-gyp 版本来执行同样的操作,根据用户的平台按需生成插件的编译版本。

【When using npm install to install a Node.js addon, npm uses its own bundled version of node-gyp to perform this same set of actions, generating a compiled version of the addon for the user's platform on demand.】

一旦构建完成,可以通过在 Node.js 中将 require() 指向已构建的 addon.node 模块来使用该二进制插件:

【Once built, the binary addon can be used from within Node.js by pointing require() to the built addon.node module:】

// hello.js
const addon = require('./build/Release/addon');

console.log(addon.hello());
// Prints: 'world' 

由于编译后的插件二进制文件的确切路径可能因编译方式不同而有所变化(例如,有时可能在 ./build/Debug/ 目录下),插件可以使用 绑定 包来加载已编译的模块。

【Because the exact path to the compiled addon binary can vary depending on how it is compiled (i.e. sometimes it may be in ./build/Debug/), addons can use the bindings package to load the compiled module.】

虽然 bindings 包的实现方式在定位插件模块方面更为复杂,但它本质上使用的是类似以下的 try…catch 模式:

【While the bindings package implementation is more sophisticated in how it locates addon modules, it is essentially using a try…catch pattern similar to:】

try {
  return require('./build/Release/addon.node');
} catch (err) {
  return require('./build/Debug/addon.node');
}