使用require导入Node.js .node插件失败问题求助
Node.js Addon 加载失败问题排查与解决
问题详情
使用node-addon-api和node-gyp 9.3.1开发Node.js插件时,执行require导入出现以下错误:
Uncaught Error: The specified module could not be found. \\?\C:\Users\simon\Documents\draw2d\build\Release\canvas_sdl2.node at Module._extensions..node (node:internal/modules/cjs/loader:1353:18) at Module.load (node:internal/modules/cjs/loader:1125:32) at Module._load (node:internal/modules/cjs/loader:965:12) at Module.require (node:internal/modules/cjs/loader:1149:19) at require (node:internal/modules/helpers:121:18) { code: 'ERR_DLOPEN_FAILED' }
使用的Node.js版本为v20.0.0,也曾尝试v18.16.0。
插件代码
#include <napi.h> #include <SDL.h> #include <string> Napi::Value sdl_init_n(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); Uint32 flags = info[0].As<Napi::Number>().Uint32Value(); return Napi::Number::New(env, SDL_Init(flags)); } Napi::Object Init(Napi::Env env, Napi::Object exports) { exports.Set(Napi::String::New(env, "init"), Napi::Function::New<sdl_init_n>(env)); //exports.Set(Napi::String::New(env, "createWindow"), Napi::Function::New<sdl_create_window>(env)); return exports; } NODE_API_MODULE(addon, Init);
binding.gyp配置
{ 'targets': [ { 'target_name': 'canvas_sdl2', 'sources': ['src\\sdl2node.cpp'], 'include_dirs': [ "C:\\SDL\\SDL2-2.26.5\\include", "C:\\SDL_Image\\SDL2_image-2.6.3\\include", "<!@(node -p \"require('node-addon-api').include\")" ], 'dependencies': [ "<!(node -p \"require('node-addon-api').gyp\")" ], 'libraries': [ "C:\\SDL\\SDL2-2.26.5\\lib\\x64\\SDL2.lib", "C:\\SDL_Image\\SDL2_image-2.6.3\\lib\\x64\\SDL2_image.lib" ], 'cflags!': ['-fno-exceptions'], 'cflags_cc!': ['-fno-exceptions'], 'xcode_settings': { 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES', 'CLANG_CXX_LIBRARY': 'libc++', 'MACOSX_DEPLOYMENT_TARGET': '10.7' }, 'msvs_settings': { 'VCCLCompilerTool': {'ExceptionHandling': 1}, } } ] }
已尝试的操作
- 将
NODE_API_MODULE(addon, Init)修改为NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init) - 移除
require语句中的.node扩展名
解决思路与方案
1. 补充SDL运行时动态库
Windows平台下,编译时链接的SDL2.lib和SDL2_image.lib是导入库,运行时需要对应的动态链接库(.dll)才能加载插件:
- 从
C:\SDL\SDL2-2.26.5\lib\x64复制SDL2.dll - 从
C:\SDL_Image\SDL2_image-2.6.3\lib\x64复制SDL2_image.dll - 将上述文件粘贴到插件所在的
build/Release目录,或者添加所在路径到系统PATH环境变量
2. 确认架构匹配
确保Node.js版本与SDL库的编译架构一致:
- 执行
node -p process.arch查看Node.js架构(应为x64) - 确认使用的SDL库是x64版本(与binding.gyp中配置的路径一致)
- 重新执行
node-gyp clean rebuild,确保编译过程无架构不兼容报错
3. 验证模块名称一致性
使用NODE_API_MODULE(NODE_GYP_MODULE_NAME, Init)是正确的,该宏会自动匹配binding.gyp中target_name(即canvas_sdl2),确保编译生成的模块名称与导入时的名称一致。
4. 检查SDL_image的依赖库
SDL_image通常依赖第三方图像解码库(如libpng16-16.dll、jpeg62.dll等),如果使用预编译的SDL_image包,需将这些依赖的.dll文件一并复制到build/Release目录。
5. 重新编译并验证文件完整性
- 执行
node-gyp clean清理旧编译文件 - 执行
node-gyp configure --release和node-gyp build重新编译 - 确认
build/Release/canvas_sdl2.node文件存在且大小正常,无编译错误输出
内容的提问来源于stack exchange,提问作者Simone Ancona
相关产品推荐
相关产品推荐

