node gyp安装canvas原生模块编译node pregyp详解

 更新时间:2022年11月02日 14:23:11   作者:zhangjr0575  
这篇文章主要为大家介绍了Nodejs关于原生模块编译node-gyp + node-pre-gyp (以安装canvas为例)示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

关于node-gyp

node-gyp是一个用 Node.js 编写的跨平台命令行工具,用于为 Node.js 编译本机插件模块。它包含之前由 Chromium 团队使用的 gyp-next项目的供应副本,扩展以支持 Node.js 原生插件的开发。

node-gyp is a cross-platform command-line tool written in Node.js for compiling native addon modules for Node.js. It contains a vendored copy of the gyp-next project that was previously used by the Chromium team, extended to support the development of Node.js native addons.

node是跨平台的,那么对于任何的node模块理论也是应该是跨平台的。然而,有些node模块直接或间接使用原生C/C++代码,这些东西要跨平台,就需要使用源码根据实际的操作平台环境进行原生模块编译。通常我们开发环境为macOS或Windows,而生产环境为Linux的各种发行版,这将导致我们的开发工作变得沉重不堪。那我们是否可以跳过node-gyp的编译过程?

node-pre-gyp 

node-gyp的编译是让人难受的过程,所以社区出现了node-pre-gypprebuild-install,它们都会优先下载插件作者预编译的二进制文件,当二进制文件下载出现问题时,再使用node-gyp进行编译兜底。

但因为我们网络环境的特殊性,这些二进制文件我们大概率是不会下载成功的,接下来一起来看看在canvas的安装过程中node-pre-gyp干了什么事。

关于prebuild-install参考姊妹文【Nodejs】关于原生模块编译node-gyp + prebuild-install (以安装 better-sqlite3为例)

canvas安装过程追踪

canvas就使用了node-pre-gyp来优化构建过程

1. 安装canvas

关于install我们需要了解一点东西, 通常基于表象我们都会认为npm下载解压并释放到node_modules后就完成了安装过程,但实际上npm还会检查package中是否配置了install命令,存在就会立即执行,这也是原生模块在下载完成后会自动构建的基础。

npm install canvas

2. canvas的package的命令脚本

可以看到canvas配置了install命令,所以npm下载canvas后立即执行了

node-pre-gyp install --fallback-to-build --update-binary

{
    ...,
    "scripts": {
        "prebenchmark": "node-gyp build",
        "benchmark": "node benchmarks/run.js",
        "lint": "standard examples/*.js test/server.js test/public/*.js benchmarks/run.js lib/context2d.js util/has_lib.js browser.js index.js",
        "test": "mocha test/*.test.js",
        "pretest-server": "node-gyp build",
        "test-server": "node test/server.js",
        "generate-wpt": "node ./test/wpt/generate.js",
        "test-wpt": "mocha test/wpt/generated/*.js",
        "install": "node-pre-gyp install --fallback-to-build --update-binary",
        "dtslint": "dtslint types"
    }
}

3. node-pre-gyp install命令

node-pre-gyp命令最终链接到了@mapbox/node-pre-gyp/lib/main.js,根据参数install最终进入@mapbox/node-pre-gyp/lib/install.js执行

4. 下载预构建的二进制文件

可以看到node-pre-gyp先检查项目本地是否已经存在二进制构建文件,当不存在时进入用户本地查找,当用户本地也不存在时会执行http下载任何,接下来我们在看看http链接如何生成

existsAsync(binary_module, (found) => {
      if (!update_binary) {
        if (found) {
          console.log('[' + package_json.name + '] Success: "' + binary_module + '" already installed');
          console.log('Pass --update-binary to reinstall or --build-from-source to recompile');
          return callback();
        }
        log.info('check', 'checked for "' + binary_module + '" (not found)');
      }
      makeDir(to).then(() => {
        const fileName = from.startsWith('file://') && from.slice('file://'.length);
        if (fileName) {
          extract_from_local(fileName, to, after_place);
        } else {
          place_binary(from, to, opts, after_place);
        }
      }).catch((err) => {
        after_place(err);
      });
      function after_place(err) {
        if (err && should_do_fallback_build) {
          print_fallback_error(err, opts, package_json);
          return do_build(gyp, argv, callback);
        } else if (err) {
          return callback(err);
        } else {
          console.log('[' + package_json.name + '] Success: "' + binary_module + '" is installed via remote');
          return callback();
        }
      }
    });

其中from变量即预构件二进制文件地址,指向opts.hosted_tarball,源码只保留了核心部分,完整源码请查阅@mapbox/node-pre-gyp/lib/util/versioning.js

const host = process.env['npm_config_' + validModuleName + '_binary_host_mirror'] || package_json.binary.host;
opts.host = fix_slashes(eval_template(host, opts));
...
opts.remote_path = package_json.binary.remote_path ? drop_double_slashes(fix_slashes(eval_template(package_json.binary.remote_path, opts))) : default_remote_path;
...
opts.hosted_path = url.resolve(opts.host, opts.remote_path);
opts.hosted_tarball = url.resolve(opts.hosted_path, opts.package_name);

可以看到node-pre-gyp会读取配置文件中是否配置了{包名}_binary_host_mirror,否则读取待构建的插件package.json中的binary.host配置项,所以在prebuild-install中可以生效的{p包名}_binary_host在node-pre-gyp中是无效的,所以针对原生插件我们需要查看插件使用的node-pre-gyp还是prebuild-install来灵活调整.npmrc中的预构件二进制文件下载镜像源

让node-pre-gyp通过淘宝源下载预构建文件

npm提供了.npmrc配置文件并注入到进程的env环境变量中,从上面的源码可知,node-pre-gyp会优先读取npm_config_{包名}_binary_host_mirror(.npmrc中的变量均会被npm添加npm_config_前缀, 所以我们配置时无需添加npm_config_前缀),另外需要值得注意的是npm会将.npmrc中的键以下划线的方式组织且任何非数字和字母的字符将会被替换为_。所以以canvas举例来说,配置如下

canvas_binary_host_mirror=https://registry.npmmirror.com/-/binary/canvas

鉴于prebuild-install兼容性更好,针对原生模块我们在.npmrc中以{包名}_binary_host_mirror={mirror}的格式配置预构建文件下载镜像

以上就是node gyp安装canvas原生模块编译node pregyp详解的详细内容,更多关于node gyp安装canvas的资料请关注脚本之家其它相关文章!

相关文章

  • nodejs开发一个最简单的web服务器实例讲解

    nodejs开发一个最简单的web服务器实例讲解

    在本篇文章里小编给大家整理的是关于nodejs开发一个最简单的web服务器实例内容,有需要的朋友们可以参考下。
    2020-01-01
  • CentOS上安装Node.js和mongodb笔记

    CentOS上安装Node.js和mongodb笔记

    这篇文章主要介绍了CentOS上安装Node.js和mongodb笔记,本文讲解了Python安装、Node.js安装、npm安装、mongodb驱动安装、mongodb数据库操作测试代码等内容,需要的朋友可以参考下
    2015-04-04
  • 三种Node.js写文件的方式

    三种Node.js写文件的方式

    这篇文章主要为大家详细介绍了三种Node.js写文件的方式,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • Node.js 多线程实战小结

    Node.js 多线程实战小结

    在 Node.js 的世界中,多线程技术一直是一个受到广泛关注的领域,本文主要介绍了Node.js 多线程实战小结,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Node如何实现在浏览器预览项目的所有图片详解

    Node如何实现在浏览器预览项目的所有图片详解

    最近项目遇到了个需求,需要将存放图片进行预览,所以这篇文章主要给大家介绍了关于Node如何实现在浏览器预览项目的所有图片的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • NodeJS后端开发操作文件之读写文件

    NodeJS后端开发操作文件之读写文件

    这篇文章主要介绍了NodeJS后端开发操作文件之读写文件,操作文件是服务端一个基础的功能,也是做后端开发的必备能力之一,操作文件主要包括读和写。而这些功能NodeJS都已经提供了对应的方法
    2022-06-06
  • Nodejs中session的简单使用及通过session实现身份验证的方法

    Nodejs中session的简单使用及通过session实现身份验证的方法

    session的本质使用cookie来实现。本文给大家介绍Nodejs中session的简单使用及通过session实现身份验证的方法,对node.js session相关知识感兴趣的朋友一起学习吧
    2016-02-02
  • npm 常用命令详解(小结)

    npm 常用命令详解(小结)

    这篇文章主要介绍了npm 常用命令详解(小结),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • Node.js DES加密的简单实现

    Node.js DES加密的简单实现

    下面小编就为大家带来一篇Node.js DES加密的简单实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • nodejs安装与配置过程+初学实例解读

    nodejs安装与配置过程+初学实例解读

    这篇文章主要介绍了nodejs安装与配置过程+初学实例解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04

最新评论