Node.js 使用 ESM 规范如何导入 C++ Addons

使用 import 语法时:

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".node"

使用 require 语法时:

ReferenceError: require is not defined in ES module scope, you can use import instead

在使用ESM规范导入C++ Addons时,需要注意以下几点:

1、首先需要在Node.js中启用ESM模块,可以在命令行中使用--experimental-modules选项启用ESM模块,例如:

node --experimental-modules app.mjs

或者在package.json中添加"type": "module"字段,表示使用ESM模块,例如:

{
  "type": "module",
  "main": "app.mjs"
}

2、在ESM模块中,不能使用require语法导入C++ Addons,需要使用import语法导入。例如:

import addon from './addon.node';

这里的./addon.node是C++ Addons编译生成的二进制文件,需要注意路径是否正确。
3、如果在使用import语法时出现TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".node"错误,可以尝试在package.json中添加"exports"字段,指定.node文件的导入方式。例如:

{
  "type": "module",
  "main": "app.mjs",
  "exports": {
    ".": {
      "require": "./addon.node"
    }
  }
}

这里的"./addon.node"是C++ Addons编译生成的二进制文件路径,需要根据实际情况修改。

需要注意的是,ESM规范在Node.js中仍处于实验性阶段,可能存在一些不稳定性和兼容性问题,建议谨慎使用。

该回答引用ChatGPT4与博主@晓码自在合作编写:

在 Node.js 中使用 ESM(ECMAScript Modules) 规范导入 C++ addons 时,会出现两个错误:

  1. 使用 import 时报错 Unknown file extension ".node"
  2. 使用 require 时报错 require is not defined in ES module scope

这是因为 .node 文件是 C++ addons 的扩展名,ESM 默认只支持 .js 和 .mjs 后缀的文件,所以无法直接导入 .node 文件。而 require 又在 ESM 下不可用。

要解决这个问题,有两种方法:

  1. 使用 --es-module-specifier-resolution=node 运行 Node.js

使用这个 flag 运行 Node.js 程序,会让 ESM 支持导入 .node 文件:

bash
node --es-module-specifier-resolution=node your-app.mjs

然后你就可以在 ESM 中使用 import 导入 C++ addon 了:

js
import * as addon from './build/Release/addon.node';

  1. 创建 .js 或者 .mjs 文件作为中转,从这里导入 .node 模块

你可以创建一个 addon.js 或 addon.mjs 文件,内容如下:

js
import * as addon from './build/Release/addon.node';
export default addon; 

然后从其他 ESM 模块导入此文件:

js
import addon from './addon.mjs';

这种方式可以支持导入 .node 模块,且无需修改 Node.js 运行配置。

所以,要在 ECMAScript Modules 下使用 C++ addons,你可以:

  1. 运行 Node.js 时添加 --es-module-specifier-resolution=node flag

  2. 创建 .js 或 .mjs 文件作为中转,从这里导入 .node 模块

Node.js 支持 ESM 和 C++ addons 都是比较新 Features,各自使用方法有差异,需要熟悉才能在同一个项目中很好结合使用。希望这个解释可以帮你解决导入 C++ addons 的问题。