首页IT科技better call saul百科(better sqlite3安装node gyp原生模块编译prebuild-install)

better call saul百科(better sqlite3安装node gyp原生模块编译prebuild-install)

时间2025-05-05 02:22:27分类IT科技浏览3658
导读:关于node-gyp node-gyp是一个用 Node.js 编写的跨平台命令行工具,用于为 Node.js 编译本机插件模块。它包含之前由 Chromium 团队使用的 gyp-next项目的供应副本,扩展以支持 Node.js 原生插件的开发。...

关于node-gyp

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

node-gypis a cross-platform command-line tool written in Node.js for compiling native addon modules for Node.js. It contains a vendored copy of thegyp-nextproject 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的编译过程?

prebuild-install

node-gyp的编译是让人难受的过程           ,所以社区出现了node-pre-gyp和prebuild-install,它们都会优先下载插件作者预编译的二进制文件                ,当二进制文件下载出现问题时                ,再使用node-gyp进行编译兜底      。但因为我们网络环境的特殊性,这些二进制文件我们大概率是不会下载成功的           ,接下来一起来看看在better-sqlite3的安装过程中prebuild-install干了什么事     。

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

better-sqlite3安装过程追踪

better-sqlite3就使用了prebuild-install来优化构建过程

1. 安装 better-sqlite3

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

npm install better-sqlite3

2. better-sqlite3的package的命令脚本

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

{ ..., "scripts": { "install": "prebuild-install || npm run build-release", "build-release": "node-gyp rebuild --release", "build-debug": "node-gyp rebuild --debug", "rebuild-release": "npm run lzz && npm run build-release", "rebuild-debug": "npm run lzz && npm run build-debug", "test": "mocha --exit --slow=75 --timeout=5000", "benchmark": "node benchmark", "download": "bash ./deps/download.sh", "lzz": "lzz -hx hpp -sx cpp -k BETTER_SQLITE3 -d -hl -sl -e ./src/better_sqlite3.lzz" }, }

3. prebuild-install的package.json

可以看到prebuild-install使用bin将prebuild-install命令链接到了bin.js

{ ..., "bin": "./bin.js", ... }

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

可以看到bin.js中核心函数就是startDownload

const startDownload = function (downloadUrl) { download(downloadUrl, opts, function (err) { if (err) { log.warn(install, err.message) return process.exit(1) } log.info(install, Successfully installed prebuilt binary!) }) } if (opts.token) { asset(opts, function (err, assetId) { if (err) { log.warn(install, err.message) return process.exit(1) } startDownload(util.getAssetUrl(opts, assetId)) }) } else { startDownload(util.getDownloadUrl(opts)) }

其中opts的核心参数项如下           。粘贴的代码有删减                 ,完整的请自行查阅源码

const rc = require(rc)(prebuild-install, { target: pkgConf.target || env.npm_config_target || process.versions.node, runtime: pkgConf.runtime || env.npm_config_runtime || node, arch: pkgConf.arch || env.npm_config_arch || process.arch, libc: libc, platform: env.npm_config_platform || process.platform, debug: env.npm_config_debug === true, force: false, verbose: env.npm_config_verbose === true, buildFromSource: buildFromSource === pkg.name || buildFromSource === true, path: ., proxy: env.npm_config_proxy || env.http_proxy || env.HTTP_PROXY, https-proxy: env.npm_config_https_proxy || env.https_proxy || env.HTTPS_PROXY, local-address: env.npm_config_local_address, local-prebuilds: prebuilds, tag-prefix: v, download: env.npm_config_download })

opts中并没有发现token的踪迹     ,那程序将进入else分支     ,接下来我们进入getDownloadUrl查看于构建二进制文件下载地址的拼接逻辑     。可以看到针对包名prebuild-install会移除包名以@组织开头的部分

function getDownloadUrl (opts) { const pkgName = opts.pkg.name.replace(/^@[a-zA-Z0-9_\-.~]+\//, ) return expandTemplate(urlTemplate(opts), { name: pkgName, package_name: pkgName, version: opts.pkg.version, major: opts.pkg.version.split(.)[0], minor: opts.pkg.version.split(.)[1], patch: opts.pkg.version.split(.)[2], prerelease: opts.pkg.version.split(-)[1], build: opts.pkg.version.split(+)[1], abi: opts.abi || process.versions.modules, node_abi: process.versions.modules, runtime: opts.runtime || node, platform: opts.platform, arch: opts.arch, libc: opts.libc || , configuration: (opts.debug ? Debug : Release), module_name: opts.pkg.binary && opts.pkg.binary.module_name, tag_prefix: opts[tag-prefix] }) }

接下来我们进入urlTemplate函数                 ,函数内又调用了其他的函数           ,这里我们针对重要的代码做说明不粘贴源码

// 构建了二进制文件名的模板字符串, 在稍后`{}`中的内容将会被替换掉 const packageName = {name}-v{version}-{runtime}-v{abi}-{platform}{libc}-{arch}.tar.gz // 获取npmrc中的镜像配置{包名}_binary_host(或{包名}_binary_host_mirror) const hostMirrorUrl = getHostMirrorUrl(opts); // 当hostMirrorUrl存在时, 在hostMirrorUrl拼接上版本号和包信息返回 if (hostMirrorUrl) { return hostMirrorUrl + /{tag_prefix}{version}/ + packageName } // 当hostMirrorUrl不存在时, 将会检查包中是否配置了binary以及binary.host, 存在时返回格式为 // {binary.host}/{binary.remote_path}/{binary.package_name || packageName} // 当binary以及binary.host均不存在时, 将会返回二进制文件在github上的托管地址 return github(opts.pkg) + /releases/download/{tag_prefix}{version}/ + packageName

接下来就是expandTemplate函数对urlTemplate返回的下载地址中的占位符做替换处理生成真正的预构建二进制文件地址     ,至此prebuild-install完成了二进制文件的下载                ,跳过了node-pyg的编译过程

让prebuild-install通过淘宝源下载预构建文件

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

better_sqlite3_binary_host=https://registry.npmmirror.com/-/binary/better-sqlite3 better_sqlite3_binary_host_mirror=https://registry.npmmirror.com/-/binary/better-sqlite3 better-sqlite3_binary_host=https://registry.npmmirror.com/-/binary/better-sqlite3 better-sqlite3_binary_host_mirror=https://registry.npmmirror.com/-/binary/better-sqlite3

鉴于node-pre-gyp只读取{包名}_binary_host_mirror,针对原生模块我们在.npmrc中以{包名}_binary_host_mirror={mirror}的格式配置预构建文件下载镜像

以上就是better sqlite3安装node gyp原生模块编译prebuild-install的详细内容           ,更多关于node 模块编译prebuild install的资料请关注本站其它相关文章!

声明:本站所有文章                ,如无特殊说明或标注     ,均为本站原创发布。任何个人或组织           ,在未征得本站同意时                 ,禁止复制           、盗用                、采集      、发布本站内容到任何网站           、书籍等各类媒体平台                。如若本站内容侵犯了原著者的合法权益     ,可联系我们进行处理                。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
进程和程序的区别和联系(ashmaisv.exe进程安全不安全 ashmaisv进程信息查询)