关于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的资料请关注Devmax其它相关文章!

node gyp安装canvas原生模块编译node pregyp详解的更多相关文章

  1. 微信小程序canvas实现水平、垂直居中效果

    这篇文章主要介绍了小程序中canvas实现水平、垂直居中效果,本文图文实例代码相结合给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

  2. H5最强接口之canvas实现动态图形功能

    这篇文章主要介绍了H5最强接口之canvas实现动态图形功能,需要的朋友可以参考下

  3. Canvas高级路径操作之拖拽对象的实现

    这篇文章主要介绍了Canvas高级路径操作之拖拽对象的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  4. canvas像素点操作之视频绿幕抠图

    这篇文章主要介绍了canvas像素点操作之视频绿幕抠图的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. html5利用canvas实现颜色容差抠图功能

    这篇文章主要介绍了html5利用canvas实现颜色容差抠图功能,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  6. canvas绘制视频封面的方法

    这篇文章主要介绍了canvas绘制视频封面的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. HTML实现代码雨源码及效果示例

    这篇文章主要介绍了HTML实现代码雨源码及效果示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  8. 详解使用双缓存解决Canvas clearRect引起的闪屏问题

    这篇文章主要介绍了详解使用双缓存解决Canvas clearRect引起的闪屏问题的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. canvas实现按住鼠标移动绘制出轨迹的示例代码

    本篇文章主要介绍了canvas实现按住鼠标移动绘制出轨迹的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. 用canvas做一个DVD待机动画的实现代码

    这篇文章主要介绍了用canvas做一个DVD待机动画的实现代码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

随机推荐

  1. Error: Cannot find module ‘node:util‘问题解决

    控制台 安装 Vue-Cli 最后一步出现 Error: Cannot find module 'node:util' 问题解决方案1.问题C:\Windows\System32>cnpm install -g @vue/cli@4.0.3internal/modules/cjs/loader.js:638 throw err; &nbs

  2. yarn的安装和使用(全网最详细)

    一、yarn的简介:Yarn是facebook发布的一款取代npm的包管理工具。二、yarn的特点:速度超快。Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快。超级安全。在执行代码之前,Yarn 会通过算法校验每个安装包的完整性。超级可靠。使用详细、简洁的锁文件格式和明确的安装算法,Yarn 能够保证在不同系统上无差异的工作。三、y

  3. 前端环境 本机可切换node多版本 问题源头是node使用的高版本

    前言投降投降 重头再来 重装环境 也就分分钟的事 偏要折腾 这下好了1天了 还没折腾出来问题的源头是node 使用的高版本 方案那就用 本机可切换多版本最终问题是因为nodejs的版本太高,导致的node-sass不兼容问题,我的node是v16.14.0的版本,项目中用了"node-sass": "^4.7.2"版本,无法匹配当前的node版本根据文章的提

  4. nodejs模块学习之connect解析

    这篇文章主要介绍了nodejs模块学习之connect解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. nodejs npm package.json中文文档

    这篇文章主要介绍了nodejs npm package.json中文文档,本文档中描述的很多行为都受npm-config(7)的影响,需要的朋友可以参考下

  6. 详解koa2学习中使用 async 、await、promise解决异步的问题

    这篇文章主要介绍了详解koa2学习中使用 async 、await、promise解决异步的问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. Node.js编写爬虫的基本思路及抓取百度图片的实例分享

    这篇文章主要介绍了Node.js编写爬虫的基本思路及抓取百度图片的实例分享,其中作者提到了需要特别注意GBK转码的转码问题,需要的朋友可以参考下

  8. CentOS 8.2服务器上安装最新版Node.js的方法

    这篇文章主要介绍了CentOS 8.2服务器上安装最新版Node.js的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. node.js三个步骤实现一个服务器及Express包使用

    这篇文章主要介绍了node.js三个步骤实现一个服务器及Express包使用,文章通过新建一个文件展开全文内容,具有一定的参考价值,需要的小伙伴可以参考一下

  10. node下使用UglifyJS压缩合并JS文件的方法

    下面小编就为大家分享一篇node下使用UglifyJS压缩合并JS文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

返回
顶部