--{module_name}_binary_host_mirror--{module_name}_binary_site

demo

// .npmrc文件
sass_binary_site=https://npmmirror.com/mirrors/node-sass/
nodejieba_binary_host_mirror=https://npm.taobao.org/mirrors/nodejieba

gyp

gyp全称Generate Your Projects(构建你的项目)

node-gyp

抹平了不同平台之间的差异(比如mac和windows),将源代码编译为可执行的二进制文件。由于某些npm包底层是使用C++/C这种依赖平台的代码,比如node-sass。所以就不能直接像其他普通包一样从npm中直接下载文件到本地,而是需要将源代码拉下来使用node-gyp将源代码编译为可执行的二进制文件。

node-pre-gyp

每次安装包都需要使用node-gyp本地构建,这样很麻烦。库开发者将编译好的各种平台的二进制包发布到node-pre-gyp中,用户进行install时会首先根据本地的环境看远端是否有编译好的二进制文件,如果有就直接使用编译好的二进制文件。如果没有则本地使用node-gyp编译生成本地的可执行二进制文件。

如何指定二进制包的位置

使用package.json文件的binary字段指定。

binary: {
...
}

指定的位置网络被墙,比如github。使用--{module_name}_binary_host_mirror

// .npmrc文件
nodejieba_binary_host_mirror=https://npm.taobao.org/mirrors/nodejieba

什么时候使用--{module_name}_binary_host_mirror

使用node-pre-gyp包的就需要使用binary_host_mirror,因为node-pre-gyp内部在install时会优先读取npm config中配置的binary_host_mirror。并且module_name的值为包的package.json中配置的"binary.module_name"的值。

sqlite3举例:

sqlite3package.json文件

{
"binary": {
"module_name": "node_sqlite3",
"module_path": "./lib/binding/napi-v{napi_build_version}-{platform}-{libc}-{arch}",
"host": "https://github.com/TryGhost/node-sqlite3/releases/download/",
"remote_path": "v{version}",
"package_name": "napi-v{napi_build_version}-{platform}-{libc}-{arch}.tar.gz",
"napi_versions": [
3,
6
]
},
"scripts": {
// ....
"install": "node-pre-gyp install --fallback-to-build",
//...
},
}

执行npm i sqlite3时会首先从npm中下载sqlite3的源代码,下载完后检测到源码的package.json中的script标签中有install指令,就会执行install,执行node-pre-gyp install --fallback-to-buildnode-pre-gypnode_modules/.bin/node-pre-gyp中,执行node-pre-gyplib/main.js文件。

这里的install命令在js中可以使用process.argv[2]process.argv[3]分别读取到install--fallback-to-buildprocess.argv[0]的值为nodejs可执行文件所在的位置,process.argv[1]的值为当前执行的 JavaScript 文件所在的路径。从2开始都是命令行参数了。

node-pre-gyp中下载预编译二进制文件的代码

const opts = {
// ...
module_name: package_json.binary.module_name,
}
const validModuleName = opts.module_name.replace('-', '_');
const host = process.env['npm_config_' + validModuleName + '_binary_host_mirror'] || package_json.binary.host;

可以通过process.env读取npm的config,比如读取registryprocess.env.npm_config_registry

所以这里的host优先从npm config里面去读binary_host_mirror,其中的module_name的值为包的package.json文件中的"binary.module_name"字段。

什么时候使用--{module_name}_binary_site

node-sasspackage.json文件:

{
"nodeSassConfig": {
"binarySite": "https://github.com/sass/node-sass/releases/download"
},
"scripts": {
// ...
"install": "node scripts/install.js",
// ...
},
}

使用npm i node-sass安装node-sass时会先从npm中下载node-sass的源码。源码下载完成后检测到script中有install命令,如何执行install命令。

scripts/install.js文件

function checkAndDownloadBinary() {
var cachedBinary = sass.getCachedBinary(),
cachePath = sass.getBinaryCachePath(),
binaryPath = sass.getBinaryPath();
// 下载二进制可执行文件
download(sass.getBinaryUrl(), binaryPath, function(err) {
// ....
});
} // If binary does not exist, download it
checkAndDownloadBinary();

调用checkAndDownloadBinary方法进行下载预编译文件。

getBinaryUrlgetArgument函数:

function getArgument(name, args) {
var flags = args || process.argv.slice(2),
index = flags.lastIndexOf(name); if (index === -1 || index + 1 >= flags.length) {
return null;
} return flags[index + 1];
} function getBinaryUrl() {
var site = getArgument('--sass-binary-site') ||
process.env.SASS_BINARY_SITE ||
process.env.npm_config_sass_binary_site ||
(pkg.nodeSassConfig && pkg.nodeSassConfig.binarySite) ||
'https://github.com/sass/node-sass/releases/download'; return [site, 'v' + pkg.version, getBinaryName()].join('/');
}

下载预编译文件时优先使用在命令行中指定的--sass-binary-site。比如:npm install node-sass --sass-binary-site=https://npmmirror.com/mirrors/node-sass/

其次使用环境变量中指定的SASS_BINARY_SITE。比如:export SASS_BINARY_SITE=http://example.com/

再然后就是读取npm配置(常用的是.npmrc文件)中的sass_binary_site,通过process.env.npm_config_sass_binary_site读取。

再然后读取package.json中配置的binarySite字段。

{
// ...
"nodeSassConfig": {
"binarySite": "https://github.com/sass/node-sass/releases/download"
},
// ...
}

最后就是一个写死的github地址'https://github.com/sass/node-sass/releases/download'

总结:

要安装的包如果使用了node-pre-gyp(比如nodejieba),在.npmrc文件中配置国内预编译文件镜像URL就需要使用--{module_name}_binary_host_mirror。其中的module_name的值为包的package.json中配置的"binary.module_name"的值。

什么时候使用--{module_name}_binary_site实际是由要安装的包内部自己实现的,典型的案例就是node-sass

--{module_name}_binary_host_mirror和--{module_name}_binary_site的更多相关文章

  1. node-pre-gyp以及node-gyp的源码简单解析(以安装sqlite3为例)

    title: node-pre-gyp以及node-gyp的源码简单解析(以安装sqlite3为例) date: 2020-11-27 tags: node native sqlite3 前言 简单来 ...

  2. Python之路第一课Day5--随堂笔记(模块)

    本节课程大纲: 1.模块介绍 2.time &datetime模块 3.random 4.os 5.sys 6.shutil 7.json & picle 8.shelve 9.xml ...

  3. Android studio 中的配置编译错误总结

    1.编译Andorid 工程的时候,有时候出现gradle 报下面的错误. Error:(1, 0) Cause: com/android/build/gradle/LibraryPlugin : U ...

  4. Thinkphp源码分析系列(四)–Dispatcher类

    下面我们来分析一下Thinkphp中的url解析和路由调度类.此类主要功能是 // +--------------------------------------------------------- ...

  5. 分享一例测试环境下nginx+tomcat的视频业务部署记录

    需求说明:在测试环境下(192.168.1.28)部署一套公司某业务环境,其中:该业务前台访问地址: http://testhehe.wangshibo.com该业务后台访问地址: http://te ...

  6. python 动态调用模块、类、方法(django项目)

    需求:近一段时间基于django框架,开发各业务层监控代码,每个业务的监控逻辑不同,因此需要开发监控子模块,动态的导入调用. 项目名称:demo_django App:common_base.moni ...

  7. Linux 2.6内核Makefile浅析

    1 概述 Makefile由五个部分组成: Makefile:根目录Makefile,它读取.config文件,并负责创建vmlinux(内核镜像)和modules(模块文件). .config:内核 ...

  8. 用C++为nodejs 写组件,提高node处理效率

    昨天研究了下如何用C++和node交互,在node的程序中,如果有大数据量的计算,处理起来比较慢,可以用C++来处理,然后通过回调(callback的形式),返回给node. 首先,先来看看node ...

  9. Linux Communication Mechanism Summarize

    目录 . Linux通信机制分类简介 . 控制机制 0x1: 竞态条件 0x2: 临界区 . Inter-Process Communication (IPC) mechanisms: 进程间通信机制 ...

  10. C++调用python

    本文以实例code讲解 C++ 调用 python 的方法. 本文在util.h中实现三个函数: 1. init_log: 用google log(glog)初始化log 2. exe_command ...

随机推荐

  1. 利用BGP Anycast 实现DNS 服务的高可用测试

    一.背景     根据当前某公司内部生产系统容器平台架构设计,在各生产线边缘机房部署容器平台,与数据中心容器平台形成纵向冗余,在此情况下,传统部署在数据中心机房的DNS系统成为容器平台业务服务的短板, ...

  2. JS逆向实战23 某市wss URL加密+请求头+ws收发

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 本文首发链接为: http ...

  3. Go 基础之基本数据类型

    Go 基础之基本数据类型 目录 Go 基础之基本数据类型 一.整型 1.1 平台无关整型 1.1.1 基本概念 1.1.2 分类 有符号整型(int8~int64) 无符号整型(uint8~uint6 ...

  4. 自己把源码生成jar,在android项目中调用

    项目源码下载地址 看了很多,找了很多,都是没有自己想要的效果的,不容易啊,备注下吧. 1.自己的源码 ,java文件,里边有各种方法,生成jar,可以分享给别人使用. 2.目前主要验证在android ...

  5. 计算机三级网络技术备考复习资料zhuan

    计算机三级网络技术备考复习资料     第一章  计算机基础 分析:考试形式:选择题和填空题,6个的选择题和2个填空题共10分,都是基本概念 1.计算机的四特点:有信息处理的特性,有广泛适应的特性,有 ...

  6. Kbaor_2023_9_28_Java第一次实战项目_ELM_V1_食品的实体类、工具类与实现类

    Kbaor_2023_9_28_Java第一次实战项目_ELM_V1_食品的实体类.工具类与实现类 ELM_V1_食品的实体类 package elm_V1; /** * [食品实体类] * * @a ...

  7. JDK21的虚拟线程是什么?和平台线程什么关系?

    虚拟线程(Virtual Thread)是 JDK 而不是 OS 实现的轻量级线程(Lightweight Process,LWP),由 JVM 调度.许多虚拟线程共享同一个操作系统线程,虚拟线程的数 ...

  8. shell脚本之规范与变量

    shell编程规范与变量 名词简述 面向过程语言 按照顺序执行程序 第一件事干什么->第二件事干什么......(C,shell...) 面向对象语言 把程序看成一个整体(java,python ...

  9. XML文件的解析--libxml库函数解释

    [c语言]XML文件的解析--libxml库函数解释 2009-09-02 13:12 XML文件的解析--libxml库函数解释 libxml(一)                          ...

  10. RT-Thread 中 minIni 组件包无法添加的解决方法

    事件 今天在 Env 下添加 minIni 包的时候出现了无法将其添加到工程的情况.借此机会来记录一下如何解决该类问题. 如果你想快速排错可以直接到 [2.minIni 组件出现的问题]查看. 一.准 ...