如何在节点 v10 的 Google 云函数中使用 ffi-napi

How to use ffi-napi in Google Cloud Functions at Node v10

我在 Google 云函数 (Node v10) 中遇到本机模块依赖项(特别是 IBM MQ for js)的问题,并且在任何地方都找不到我需要的信息,所以我打开了这个问题并自己回答,以便将来其他人找到它。

它在 Node v8 引擎中运行良好,但现在已弃用。将引擎升级到 v10 并修改一些包后(遵循所有关于我的依赖项的迁移指南),ffi-napi 包在 yarn install 期间抛出异常,如下所示:

ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: ...s status = napi_get_instance_data(env, &d);
                        ^~~~~~~~~~~~~~~~~~~~~~
../src/ffi.cc:11:24: note: suggested alternative: 'napi_new_instance'
   napi_status status = napi_get_instance_data(env, &d);
                        ^~~~~~~~~~~~~~~~~~~~~~
                        napi_new_instance
../src/ffi.cc: In function 'Napi::Object BindingHook(Napi::Env, Napi::Object)':
../src/ffi.cc:347:24: error: 'napi_set_instance_data' was not declared in this scope
   napi_status status = napi_set_instance_data(
                        ^~~~~~~~~~~~~~~~~~~~~~
../src/ffi.cc:347:24: note: suggested alternative: 'napi_new_instance'
   napi_status status = napi_set_instance_data(
                        ^~~~~~~~~~~~~~~~~~~~~~
                        napi_new_instance
In file included from ../src/ffi.cc:3:0:
../src/ffi.h: At global scope:
../src/ffi.h:148:19: warning: mangled name for 'Napi::TypedArray FFI::WrapPointer(Napi::Env, T*, size_t) [with T = char*() throw ()]' will change in C++17 because the exception specification is part of a function type [-Wnoexcept-type]
 inline TypedArray WrapPointer(Env env, T* ptr, size_t length = 0) {
                   ^~~~~~~~~~~
../src/ffi.h:148:19: warning: mangled name for 'Napi::TypedArray FFI::WrapPointer(Napi::Env, T*, size_t) [with T = void*(void*, const char*) throw ()]' will change in C++17 because the exception specification is part of a function type [-Wnoexcept-type]
../src/ffi.h:148:19: warning: mangled name for 'Napi::TypedArray FFI::WrapPointer(Napi::Env, T*, size_t) [with T = int(void*) throw ()]' will change in C++17 because the exception specification is part of a function type [-Wnoexcept-type]
../src/ffi.h:148:19: warning: mangled name for 'Napi::TypedArray FFI::WrapPointer(Napi::Env, T*, size_t) [with T = void*(const char*, int) throw ()]' will change in C++17 because the exception specification is part of a function type [-Wnoexcept-type]
make: *** [Release/obj.target/ffi_bindings/src/ffi.o] Error 1
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:191:23)
gyp ERR! stack     at ChildProcess.emit (events.js:198:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:248:12)
gyp ERR! System Linux 5.3.0-1020-gcp
gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /workspace/node_modules/ffi-napi
gyp ERR! node -v v10.19.0
gyp ERR! node-gyp -v v5.0.5
gyp ERR! not ok 
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! ffi-napi@3.0.1 install: `node-gyp-build`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the ffi-napi@3.0.1 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /builder/home/.npm/_logs/2020-06-12T17_47_25_766Z-debug.log; Error ID: c4475859

它在本地(OSX Catalina 节点 10.21)和 Docker(在基于 alpine 的节点 10 和 12 主要标签中测试)都工作正常。

TLDR:尚不支持。


我刚刚发现 Node v10.20napi_get_instance_data 在 v10.20.0 中添加)中引入了 IBM MQ 包依赖项(特别是 ffi-napi)所需的一些本机 API,但是 Google Cloud Functions 基于 Node v10.18.1.

到目前为止,我发现的唯一解决方法是使用 Yarn Resolutions 或自定义分支将 ffi-napi 降级为 v2.4.7。 Cloud Functions 引擎中没有关于 Node v10.20 预期版本的 public 信息。