您可以将多个本机模块打包到同一个NPM包中吗?

kmp*_*kmp 5 module node.js npm

我使用cmake,musl,加上一些抽象和精心放置的#ifdefsC中编写了一个跨平台的nodejs本机模块.

它内置于使用一个模块的cmake-JS和我有3个构建服务器:Windows,MacLinux做栋所以我有3个是在所有的平台上正常工作的本机模块.

我们有一个内部NPM存储库,我可以继续发布,以便公司内的其他团队可以简单npm install module地获取我的模块.

关键是,它是一种混乱的客户端将需要选择基于他们的(即我会从每一个构建服务器的部署的所有3个模块)平台上的模块,所以我宁愿通过某种方式部署单一模块将3个平台特定模块合并在一起.

这是可能的吗?我如何构建这种模块的内部结构?*

例如,绑定是否会找出平台并找到合适的.node文件?

*我不希望包含的代码,并在客户端编译为使(他们会期待能够写使用JavaScript一个简单的脚本,例如,用我的模块在客户端上一个相当大的负担 - 他们需要建立C构建链,担心他们的脚本运行的平台等等,这将是一个震撼.

Pio*_*ski 5

我想到的最简单的解决方案 - 如果您将代码打包到不同平台的模块中,那么您将获得如下包:

  • fancy-module-linux
  • fancy-module-windows
  • fancy-module-mac

您还可以提供一个通用模块,比如fancy-module.

在最基本的场景中:

fancy-module是一个空模块,只有一个README

installpackage.json

{
  ...
  "scripts": {
     "install": "node ./install_platform_dep.js"
  }
}
Run Code Online (Sandbox Code Playgroud)

然后安装时fancy-moduleinstall_platform_dep.js 脚本将被执行。在install_platform_dep.js你的地方:

// For Windows...
if(process.platform === 'win32') {
    // Trigger Windows module installation
    exec('npm install fancy-module-windows', (err, stdout, stderr) => {
         // Some error handling...
    }
} else if ... // Process other OS'es
Run Code Online (Sandbox Code Playgroud)

您甚至不必单独发布任何内容!或者,您可以将所有内容放入fancy-module

package.json
README.md
src
  |- Windows
  |  # Here you've got just copied contents of `fancy-module-windows`
  |- Linux
  |  # This folder have same contents as `fancy-module-linux`
  \- Mac
     # Same
Run Code Online (Sandbox Code Playgroud)

并且做 exec('npm install ./src/Windows' /* ... */)

您将获得一个不错的单一多平台捆绑包。

除了做我所描述的,没有其他方法可以实现多平台模块。

无论如何,提供类似安装程序的模块只是为了安装东西是相当丑陋的,但 afik 这是最直接的选择。

npm 上的许多包(围绕 Electron 和 paltform 依赖的东西构建)只是安装其他包的安装程序,所以这是一个很好的方法。

编辑:

对于 os 检测,您可以使用诸如:is-linuxis-windows等模块,而不必担心process.platform

阅读更多关于 is-linux
阅读更多关于 is-windows
阅读更多关于 process.paltform
阅读更多关于 package.json 中的安装钩子

编辑#2

或者,您可以使用已制作的包,node-pre-gyp如下所述:

使用 node-pre-gyp 的跨平台插件

这个包实际上对所描述的方法做了一些事情。