使用节点启动应用程序有效,但不是yarn或npm

时间:2019-03-27 06:07:30

标签: node.js npm yarnpkg node-gyp

对于一个比我更熟悉NodeJS的人,可能会有一个明显的答案,那就是

运行使用node-gyp程序包的应用程序时,使用以下程序可以正常运行 node ./src/index.js

但是使用非常简单的package.json起始脚本来运行它:

"scripts": {
    "start": "node ./src/index.js"
  }

在npm中:

npm start

npm info it worked if it ends with ok
npm info using npm@6.9.0
npm info using node@v11.10.1
npm info lifecycle rosbag2@0.1.0~prestart: rosbag2@0.1.0
npm info lifecycle rosbag2@0.1.0~start: rosbag2@0.1.0

> rosbag2@0.1.0 start /Users/andreasklintberg/personal/xviz/examples/converters/rosbag2
> node ./src/index.js "./src/index.js"

internal/modules/cjs/loader.js:779
  return process.dlopen(module, path.toNamespacedPath(filename));
                 ^

Error: dlopen(/Users/andreasklintberg/personal/xviz/examples/converters/rosbag2/node_modules/rosbags2_nodejs/build/Release/rosbags2_nodejs.node, 1): Library not loaded: @rpath/librosidl_typesupport_cpp.dylib
  Referenced from: /Users/andreasklintberg/personal/xviz/examples/converters/rosbag2/node_modules/rosbags2_nodejs/build/Release/rosbags2_nodejs.node
  Reason: image not found

同样在纱线中 yarn start

yarn run v1.13.0
warning package.json: No license field
$ node ./src/index.js ./src/index.js -d ../../../data/rosbag2/rosbag2_2019_03_09-21_54_44 -o ../../xviz-data/rosbag2/rosbag2_2019_03_09-21_54_44/
internal/modules/cjs/loader.js:779
  return process.dlopen(module, path.toNamespacedPath(filename));
                 ^

Error: dlopen(/Users/andreasklintberg/personal/xviz/examples/converters/rosbag2/node_modules/rosbags2_nodejs/build/Release/rosbags2_nodejs.node, 1): Library not loaded: @rpath/librosidl_typesupport_cpp.dylib
  Referenced from: /Users/andreasklintberg/personal/xviz/examples/converters/rosbag2/node_modules/rosbags2_nodejs/build/Release/rosbags2_nodejs.node
  Reason: image not found

我知道错误是因为动态链接/ @ rpath被弄乱了,我想这是因为npm/yarn弄乱了env变量或其他东西,但是运行yarn env似乎一切都在正确。

所以我想我想知道是否有人知道在本机节点中运行它并使用npm/yarn脚本来包装开始内容有什么不同?以及为什么这种差异弄乱了@ rpath / dynamic链接?

编辑:

我的index.js文件非常简单,只需导入构建的node-gyp包:

let RosbagDeserializer = require('../build/Release/rosbags2_nodejs.node');


const deserializer = new RosbagDeserializer.Rosbag2Wrapper();

这是有问题的项目https://github.com/klintan/rosbag2_nodejs

1 个答案:

答案 0 :(得分:0)

我希望有一个更全面的答案,但至少我在许多出色的评论者的帮助下解决了该问题:

在Mac上未设置@rpath,但是使用DYLD_LIBRARY_PATH可以运行,因为它似乎是运行时搜索路径之一(https://superuser.com/questions/282450/where-do-i-set-dyld-library-path-on-mac-os-x-and-is-it-a-good-idea)。但是出于某种原因,NPM删除了此文件,我猜想它与Mac上的SIP有关,或者与删除此env变量的其他安全措施有关。

如果运行node index.js,则

DYLD_LIBRARY_PATH可用,但如果使用npm start(node index.js启动脚本)运行,则不能使用。

@Michal Kapracki和@Avik都在暗示这一点(第一次比较时我错过了缺少的env变量)

我解决该问题的方法类似于@Avik链接的dyld: Library not loaded ... Reason: Image not found问题,我必须添加一堆依赖于库(之前已自动解决)的库以及一个post_install.sh脚本,该脚本使用install_name_tool将@rpaths更改为正确的路径。

这是一个非常丑陋的解决方案https://github.com/klintan/rosbag2_nodejs/blob/master/post_install.sh,但它可以工作。 虽然仅适用于Mac,所以需要进行概括。

总而言之,我认为这是问题所在:

由于某些原因,NPM无法使用或删除环境变量DYLD_LIBRARY_PATH,该变量用于在运行时搜索动态链接的库。这使得必须使用Mac工具install_name_tool手动链接它们。