5

node-pre-gyp 应用场景介绍及使用方法

 3 years ago
source link: https://www.mycode.net.cn/language/cpp/3023.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

node-pre-gyp 应用场景介绍及使用方法

Node.js 提供了使用 C++ addon 方案作为扩展的能力。我们可以编写 C++ 的代码来扩展 Node.js 或封装自己产品相关的能力接口为 Node.js 接口提供用户或者开发者使用。将编写好的源代码上传至 npm publish 平台,开发者通过 npm install 就可以使用你的扩展包了。但使用的前提是引入方必须要具备编译 C++ 代码的环境,比如在 Windows 下需要安装 MSVC 的编译工具链。而正常的前端开发者并不会将这些组件安装到系统里面,他们更关注的是前端业务逻辑。

由于 npm 平台不允许上传太大的文件或二进制文件,所以在用户执行 npm install 时自动下载已经预编译好的二进制文件包就映入我们的眼帘了。node-pre-gyp 就是来做这个用的。它包含了打包上传、根据版本自动下载等一系列流程。这些步骤只需要你对工程做一些简单的配置就可以实现。node-sqlite3 就是通过该插件来实现下载预编译的二进制包的:https://github.com/mapbox/node-sqlite3

针对一些不依赖三方 SDK 的 C++ 插件来说,只需导出一份 .node 文件即可让开发者导入使用。将二进制包打包为 .tar.gz,将打包后的压缩文件上传到外网可以访问的服务器中,接下来配置一下 node-pre-gyp 就可以了。首先安装 node-pre-gyp

npm install --save @mapbox/node-pre-gyp

创建一个新的 target action_after_build 用来在你主工程编译完成后自动拷贝 .node 文件到准备上传的目录:

{
    'target_name': 'action_after_build',
    'type': 'none',
    'dependencies': ['<(module_name)'],
    'copies': [
        {
            'conditions': [
                [
                    'OS=="win"',
                    {
                        'files': [
                            '<(PRODUCT_DIR)/<(module_name).node'
                        ],
                        'destination': '<(module_path)'
                    }
                ],
                [
                    'OS=="mac"',
                    {
                        'files': [
                            '<(PRODUCT_DIR)/<(module_name).node'
                        ],
                        'destination': '<(module_path)'
                    }
                ]
            ]
        }
    ]
}

配置 package.json,让 node-pre-gyp 知道编译后的包保存到什么位置,在 package.json 中新增如下字段:

"binary": {
    "module_name": "node_nim",
    "module_path": "./lib/binding/{node_abi}-{platform}-{arch}/",
    "remote_path": "./package/",
    "package_name": "{module_name}-v{version}-{node_abi}-{platform}-{arch}.tar.gz",
    "host": "https://your-download-host"
}

这里的 module_path 就是告诉 node-pre-gyp 编译后要保存到当前目录下的 ./lib/binding/{node_abi}-{platform}-{arch}/ 目录。目录名是根据当前环境来自动创建的。除了保存,上面的配置还告诉 node-pre-gyp 第三方程序引入这个包时,node-pre-gyp 会尝试从 ${host}/${remote_path}/${package_name} 去下载这个包。如果下载到了这个包,那么自动解压到 module_path 路径下,就不会再尝试编译了。

配置基本就绪,还差最重要的一步,替换默认的 npm install 流程:

"scripts": {
    "install": "node-pre-gyp install --fallback-to-build"
}

在你的 package.json 中,scripts 字段下添加 install 配置,让默认的 install 行为变为 node-pre-gyp install –fallback-to-build。这样在三方应用引入我们的包时会调用 node-pre-gyp install 首先到 package.json 中指定的 host 去尝试下载已经编译好的二进制包,如果没有下载到则调用本地的 node-gyp(注意这里不是 node-pre-gyp)根据外部传递的参数来从本地代码编译,这样也就串通了整个流程。

同时 node-pre-gyp 其实支持二进制包自动上传的能力,需要你单独配置 AWS3 的 token 等信息,由于国内访问 S3 资源很困难,这一步我们并没有做进一步验证,有兴趣的同学可以参考官方文档来尝试。

本条目发布于2021年7月14日。属于C/C++分类。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK