node-gyp的作用我已经不想赘述了,这里给一个我之前文章的链接:cnblogs看这里知乎看这里。本文主要从源码入手,介绍node-gyp查找VisualStudio的过程

为了方便我们研究node-gyp的源码,我们随意创建一个node项目,然后我们npm install node-gyp,安装node-gyp这个包来开始我们源码探索之路吧。

E:\Projects\node-gyp-demo> npm init
...
package name: (gyp-demo)
version: (1.0.0)
...
npm install node-gyp@latest // 安装最新的node-gyp

安装完成后,在项目/node_modules/node-gyp中,已经有了我们需要的node-gyp的js脚本代码:

那么,我们应该怎么入手呢?这里需要再次提到node-gyp的处理过程,主要分为两个步骤:

  1. configure

gyp首先根据C/C++源码目录下的binding.gyp文件+操作系统(Windows、macOS以及Linux)+编译构建工具(Windows下的VS,macOS以及Linux下的make)来决定生成什么样的项目结构(Windows下的sln以及vcxproj、macOS以及Linux下的make项目)这一步是configure配置过程,不会进行源码的编译,仅仅是生成能够作为对应平台下对应编译工具输入的项目结构。

  1. build

生成项目结构以后,执行build过程调用对应的编译工具完成编译任务。

所以,我们首先查看lib/configure.js文件,试着从源码中探索一下。进入configure.js,一下就可以看到我们期望的东西(图片顶部显示了js代码位置):

如果当前进程平台是win32(Windows操作系统标识),则会引入模块find-visualstudio。暂时停止阅读configure.js的代码,直接上我们的主角:find-visualstudio.js

find-visualstudio.js

在该文件中定义了一个名为VisualStudioFinder的类,查找的过程就是执行创建该类的一个实例,并调用实例的一个名为findVisualStudio的方法。该方法被定义在该类的原型里:

对于该函数来说,主要分为了三个步骤:

  1. 对于参数msvs_version的处理
  2. 对于环境变量VSINSTALLDIR的处理
  3. 查找各个版本的VS

对于步骤1和2,我们暂时不进行解析,主要解析步骤3。因为绝大多数开发者就卡在这个步骤,导致安装需要原生编译的node模块失败。对于步骤3来说,我们不难看出处理的过程是优先查找本地的vs2017以及更高的版本,然后是vs2015,最后是vs2013,所以开发者Windows机器上没有安装VS或者是不在源码中支持的范围都一定会报错,提示VS找不到。我们首先解析findVisualStudio2017OrNewer这个函数,然后解析findVisualStudio2015findVisualStudio2013,对于后两个,实际上最终都是相同的逻辑,后面会提到。

findVisualStudio2017OrNewer

该函数的签名表示,这个函数是通过调用PowerShell脚本来获取关于VS2017或是更高版本VS的安装信息。

那么这段代码的运行情况到底如何呢?我们将该段代码单独拿出来,并将Find-VisualStudio.cs拷贝到运行目录下来Debug它。

上图中,我模拟了node-gyp中查询VS2017以上版本的函数,通过Debug方式断点调试:

ps变量值为:C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe,即为Windows下对应的最初版本的PowerShell。cs文件不再赘述,我们也不对CSharp代码解读了。代码的最后就是执行弄得的chile_process模块中的execFile函数,通过传入可执行程序的完整路径已经执行参数,完成外部程序调用。

而在这一步当中,如果执行出现了异常就会导致node-gyp的执行过程出现异常,进而导致需要原生编译的模块无法完成安装等。为了方便开发人员进行在Windows上查找VS2017以及以上版本,我把这段代码和CSharp代码提取出来,放在了github仓库(w4ngzhen/node-gyp-find-vs-check),读者如果出现了问题,可以直接下载脚本和CSharp代码进行环境的确认。

当然,有些读者的机器还是VS2015或者VS2013等版本,我们继续分析。

findVisualStudio2015/2013

通过源码可以知道,最终都调用了方法:findOldVS,并且还知道,nodejs的主版本大于等于9时,根本不会查找VS了。接下来我们查看方法findOldVs

对于该段代码,其实一点也不难理解,就是根据注册表上对应的键去查找的VS的安装路径(PS:好像又学习到了VS的安装路径可以从注册表里面查看呢!)对于该段代码,本人不提供demo代码帮助查询了。有兴趣的读者可以自己提取代码,模拟调用。

Windows下node-gyp查找VS安装路径简单解析的更多相关文章

  1. Windows下Node.js+Express+WebSocket 安装配置

    Linux参考: Linux安装Node.js 使用Express搭建Web服务器 Node.js是一个Javascript运行环境(runtime).实际上它是对Google V8引擎进行了封装.V ...

  2. windows下node.js+sublime中安装coffeescript

    node.js中安装Coffeescript 1.我的node.js安装目录 2.node.js 全局模块所在目录   3.node.js安装coffeescript npm install -g c ...

  3. 安装选择msi格式还是zip(windows下Nodejs zip版下载安装及环境变量配置)

    安装选择msi格式还是zip((windows下Nodejs zip版下载安装及环境变量配置)) -----以node.js 安装为例: 1,外观对比: ✿ 简单介绍一下node的作用: • node ...

  4. Windows下当地RabbitMQ服务的安装

    Windows下本地RabbitMQ服务的安装 本文参考:刘若泽相关技术文档 当然这些内容页可以通过RabbitMQ官方网站获得. RabbitMQ配置说明手册 一.RaibbitMQ服务器配置 1. ...

  5. windows下使用cpanm进行模块安装

    windows下使用cpanm进行模块安装 要放假了,突然想整理一下手头上的软件,突然发现perl的安装模块这个功能不能用. 弄了一下,使得windows 下 perl 的 cpanm能用,避免成天为 ...

  6. windows下配置lamp环境(1)---安装Apache服务器2.2.25

    window下lamp成为wamp; 安装wamp环境的第一步是安装Apache服务器.下面开始安装步骤图文并茂. 一.双击安装包点“next”进行下一步,然后同意协议(这张图没有截):

  7. Windows下的lua-5.3.4安装过程

    Windows下的lua-5.3.4安装过程 Mingw平台下的编译过程: $ make echo$ make mingw$ make local $ make echo PLAT= none CC= ...

  8. <亲测>CentOS 7.3下Node.js 8.6安装配置(含NPM以及PM2)

    CentOS 7.3下Node.js 8.6安装配置 2017年09月30日 14:12:02 阅读数:2245更多 个人分类: Nodejs   版权声明:本文为博主原创文章,未经博主允许不得转载. ...

  9. Windows 下 MySql 5.7.20安装及data和my.ini文件的配置(转)

    Windows 下 MySql 5.7.20安装及data和my.ini文件的配置     本文通过图文并茂的形式给大家介绍了MySql 5.7.20安装及data和my.ini文件的配置方法. my ...

随机推荐

  1. T-SQL - 习题02_将数据表year|month|amount查询成year|m1|m2|m3|m4的样式

    时间:2017-09-11 整理:byzqy 题目:有个年度统计表,结构如下: 怎么样把这个表,查询成这样一个结果: 这是在面试过程中遇到的一个关于数据库的题,没有一点思路,不知它考查到的知识点是什么 ...

  2. python 实用技巧:几十行代码将照片转换成素描图、随后打包成可执行文件(源码分享)

    效果展示 原始效果图 素描效果图 相关依赖包 # 超美观的打印库 from pprint import pprint # 图像处理库 from PIL import Image # 科学计算库 imp ...

  3. css之px、em、rem

    rem是css3新定义的设置字体大小属性,常用的两种字体大小设置有下面2种:1. px为单位2.em为单位(百分比用法跟em类似) PX为单位 在Web页面初期制作中,我们都是使用"px&q ...

  4. Nginx反向代理之巨坑underscores_in_headers

    一.背景 因为项目需求,在做Windows的相关的事情:基本架构就是Nginx--> Nginx --> IIS,在Linux机器上通过Nginx做反向代理到Windows的IIS:然后遇 ...

  5. Spring依赖注入的四种方式

    首先,我们需要定义一个Bean的class类: package framework.spring; import org.springframework.beans.BeansException; i ...

  6. Django的模板文件的路径设置

    TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS' ...

  7. unity渲染篇:烘焙模型贴图

    今天要来做一件有趣的事情,那就是把一个模型数据烘焙到贴图上! 什么意思?就是下面酱紫,把这只小喵从第一张图拍扁,变成第二张图的样子(似乎有点残忍~) 可能你经常会从美术那边听到"烘焙光照贴图 ...

  8. 小狐狸钱包怎么使用?MetaMask(小狐狸) 使用教程 - 如何添加BSC链、Heco链

    MetaMask介绍 MetaMask是一款在谷歌浏览器Chrome上使用的插件类型的以太坊钱包,只需要在谷歌浏览器添加对应的扩展程序即可使用. 1.Download & Install: 官 ...

  9. 什么是maven与maven的使用过程(例如在idea创建maven工程(重点讲讲idea创建使用maven管理的web工程,并且部署到tomcat上))

    什么是maven与maven的使用过程(例如在idea创建maven工程) (重点讲讲idea创建使用maven管理的web工程项目,并且部署到tomcat服务器上) 一.什么是maven? 1, M ...

  10. 技术栈:springboot2.x,vue,activiti5.22,mysql,带工作流系统

    前言 activiti工作流,企业erp.oa.hr.crm等审批系统轻松落地,请假审批demo从流程绘制到审批结束实例. 一.项目形式 springboot+vue+activiti集成了activ ...