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

时间:2017-12-29 08:06:23

标签: node.js npm module

我使用nodejsCcmake中编写了一个跨平台的musl原生模块,加上一些抽象并仔细放置#ifdefs }。

它使用cmake-js构建到一个模块中,我有3个构建服务器:WindowsMacLinux进行构建,因此我有3个本机模块可以工作在所有平台上都很好。

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

问题是,客户端需要根据他们所依赖的平台选择一个模块(即我会从每个构建服务器部署所有3个模块),所以很麻烦我宁愿通过某种方式将3个平台特定模块合并在一起来部署单个模块。

这是可能的,我如何构建这样一个模块的内部结构?*

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

*我不想包含代码并让客户端编译它,因为这给客户端带来了相当大的负担(他们希望能够使用Javascript编写一个简单的脚本,例如,并使用我的模块 - 他们需要设置C构建链,担心其脚本运行的平台等等,这将是一个震撼。)

1 个答案:

答案 0 :(得分:3)

我想到的最简单的解决方案 - 如果您将代码打包到不同平台的模块中,那么您就有了这样的包:

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

你也可以提供一个公共模块让我们说fancy-module

在最基本的情况中:

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

您在install

中提供自定义package.json脚本
{
  ...
  "scripts": {
     "install": "node ./install_platform_dep.js"
  }
}

然后在安装fancy-module时,将执行install_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

您甚至不必单独发布任何内容!或者,您可以将所有内容放入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

exec('npm install ./src/Windows' /* ... */)

你得到一个不错的单个多平台包。

没有其他方法可以实现多平台模块而不是我所描述的。

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

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

修改

对于操作系统检测,您可以使用以下模块:is-linuxis-windows等,而不必担心process.platform

Read more about is-linux
Read more about is-windows
Read more about process.paltform
Read more about install hook in package.json

编辑#2

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

Cross platform addon using node-pre-gyp

这个包实际上与所描述的方法有关。