本文来自网易云社区
作者:陈观喜
网上关于npm升级很多方法多种多样,但是在windows系统下不是每种方法都会正确升级。其中在windows系统下主要的升级方法有以下三种:
首先最暴力的方法删掉nodejs和npm,然后在官网上Download 最新的msi,然后msi的安装会更新你的node和npm。
其次就是利用 npm install -g npm,这种方法是网上大多数人使用的方法,但是这种方法会有潜在的问题,我们在下面会介绍。
-
最后是利用npm-windows-upgrade来升级,参见How can I update npm on Windows?用管理员权限打开PowerShell,然后执行以下命令:
Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Forcenpm install -g npm-windows-upgradenpm-windows-upgrade
其中,推荐使用第三种方法,这也是npm团队官方推荐使用的方法
准备工作
windows下的模拟终端:推荐使用powershell,经本人测试git bash 和mintty 终端模拟器在执行npm命令的时候会有问题,这两个终端执行的原理有兴趣的可以研究一下。
三种方法的比较
1.通过升级nodejs来升级
这种方法只需要删除nodejs和npm,然后下载最新的node进行安装就行。需要注意的是,删除npm的时候,需要把NODEJS目录下的npm文件夹和APPDATA的Roaming目录下的文件夹下的npm、npm-cache文件夹删除干净。
(NODEJS目录指的是你安装nodejs的目录,默认是C:\Program Files\nodejs, APPDATA的Roaming目录指的是C:\Users\<username>\AppData\Roaming,本人的APPDATA目录是C:\Users\chenguanxi\AppData\Roaming。windows系统的应用程序经常把数据和设置存放在用户的APPDATA目录,每个windows用户都有自己的APPDATA目录。)另外,APPDATA目录的用途参考What Is the AppData Folder in Windows?
2.npm install -g npm 方法(重点介绍)
在执行这个方法之前,先看一下我现在的node和npm版本:
$ node -v
v8.11.3$ npm -v5.6.0
然后执行npm install -g npm得到以下结果:
$ npm -v
6.4.1
好像升级成功了?!
我们来看一下是不是真的吧nodejs目录的npm升级成功了:
打开NODEJS目录下对应的npm目录(C:\Program Files\nodejs\node_modules\npm)
的package.json文件:
还是5.6.0!!
然后打开APPDATA路径下的npm目录(C:\Users\chenguanxi\AppData\Roaming\npm),可以看到这里新增加了一个npm,打开其package.json文件可以得到:
在终端下执行npm -v得到的是APPDATA目录npm的版本结果。那么在执行npm命令的时候到底是执行哪一个npm呢?
从上图得出,不管执行哪一个路径下的npm,得到的结果都是一样的。
再深一步,我们先看一下NODEJS目录下的npm是怎么执行的。打开npm.cmd文件,了解这个文件到底执行了什么。
npm命令执行原理:
我们在npm.cmd文件加上一下log看一下相关的变量:
执行npm -v得到的结果:
'~dp0: ' C:\Program Files\nodejs\'NODE_EXE: ' C:\Program Files\nodejs\\node.exe'NPM_CLI_JS: ' C:\Program Files\nodejs\\node_modules\npm\bin\npm-cli.js'NPM_PREFIX_NPM_CLI_JS: ' C:\Users\chenguanxi\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js'NPM_CLI_JS: ' C:\Users\chenguanxi\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js'npm command ===:' C:\Program Files\nodejs\\node.exe C:\Users\chenguanxi\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js6.4.1
重要的注释(具体命令参考windows批处理(cmd/bat)编程详解):
%~dp0只可以用在批处理文件中,它是由它所在的批处理文件的目录位置决定的,是批处理文件所在的盘符:+路径,
设置npm-cli-js文件为批处理文件处理的目录对应的npm-cli.js文件关键:执行"%NODE_EXE%" "%NPM_CLI_JS%" prefix -g这个命令,也就是npm prefix -g这个命令(这个命令在下一小节说明),可以得到:C:\Users\chenguanxi\AppData\Roaming\npm。接着设置NPM_PREFIX_NPM_CLI_JS这个变量,如果存在NPM_PREFIX_NPM_CLI_JS,就把npm-cli.js设置为NPM_PREFIX_NPM_CLI_JS目录下的npm-cli.js文件
最后执行node.exe {对应的}\node_modules\npm\bin\npm-cli.js
npm prefix -g这个命令得到以下结果:C:\Users\chenguanxi\AppData\Roaming\npm具体命令执行的过程大概是通过读取prefix的配置,然后输出配置的结果
打开C:\Program Files\nodejs\node_modules\npm目录下的npmrc文件,可以看到只有一行的代码prefix=${APPDATA}\npm
${APPDATA}指的是node环境下的process.env.APPDATA变量
结果是:C:\Users\chenguanxi\AppData\Roaming
总结:
执行npm命令实际上是执行了node ${对应的}/npm-cli.js这个命令,关键是哪一个npm-cli.js文件:
总的执行过程就是要判断执行哪一个npm-cli.js文件。也就是说,如果存在全局prefix,那就执行全局prefix下的那个npm-cli.js 文件
也就是说执行npm命令,实际上是执行./node.exe ${对应的目录下}/node_modules\npm\bin\npm-cli.js
综上所述,npm命令执行的是nodejs目录下的npm命令。在弄清楚了npm是怎么执行之后,我们可以知道执行npm install -g npm 这个命令,其实是重新下载并安装了全局环境的npm包,然后通过prefix这个配置来链接到全局环境下的npm-cli.js文件,这个过程并没有对NODEJS目录下的npm版本进行任何修改。
所以,潜在的问题是当prefix配置被修改之后,npm执行的环境是未知的,不推荐这种通过链接到全局npm包的代理方式来升级npm。
3.npm升级的正确姿势应该是npm官方推荐的方法
参见How can I update npm on Windows?
用管理员权限打开PowerShell,然后执行以下命令:
Set-ExecutionPolicy Unrestricted -Scope CurrentUser -Forcenpm install -g npm-windows-upgradenpm-windows-upgrade
npm-windows-upgrade的执行过程:
1. ensureExecutionPolicy:检查用户的powershell 执行权限政策等2. ensureInternet:检查用户的网络状况3. chooseVersion: 让用户选择一个npm版本4. choosePath: 找到正确的npm安装目录5. upgrade:自动找到正升级npm的正确目录,保护和重新应用现有的配置,最终调用npm install -g npm
详细过程有兴趣的可以打开源文件看一下:
主要是以下三个文件:
C:\Users\chenguanxi\AppData\Roaming\npm\npm-windows-upgrade.cmd
C:\Users\chenguanxi\AppData\Roaming\npm\node_modules\npm-windows-upgrade\bin\npm-windows-upgrade.js
C:\Users\chenguanxi\AppData\Roaming\npm\node_modules\npm-windows-upgrade\lib\upgrader.js
也就是说执行npm-windows-upgrade,它会帮助我们自动找到正升级npm的正确目录,保护和重新应用现有的配置,最终调用npm install -g npm
总结
综上,在windows系统下升级npm的最佳方法是用npm-windows-upgrade来升级,这样可以保护并且重新应用到现有的配置,避免了潜在的问题。
通过以上实验过程有以下知识点总结:
npm命令是通过node npm-cli.js 命令来实现的
windows系统下,npm的全局包管理环境和node目录是分开的
以上有不对的地方,希望大家指正。
参考:
网易云免费体验馆,0成本体验20+款云产品!
更多网易研发、产品、运营经验分享请访问网易云社区。
相关文章:
【推荐】 SpringBoot入门(四)——自动配置
【推荐】 从细节处谈Android冷启动优化
【推荐】 网易云复盘:云计算前端这一年(AngularJS粉慎入)
windows系统下npm升级的正确姿势以及原理的更多相关文章
-
windows系统下npm 全局安装路径问题
安装了nodejs之后,npm的路径默认一直都是appData,表示很讨厌,于是尝试修改在安装目录(D盘空间很大啊) 安装目录:D:\program files\nodejs 一.在nodejs下新建 ...
-
如何正确入门Windows系统下驱动开发领域?
[作者]猪头三个人网站 :http://www.x86asm.com/ [序言]很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都以英文 ...
-
windows系统下如何正确安装Cygwin(图文详解)
我的操作系统信息是 1.在官网https://cygwin.com/install.html下载win64位安装包 选择包的下载存放目录,点击“下一步” 为了使我们安装的Cygwin能够编译程序, ...
-
[记]Windows 系统下设置Nodejs NPM全局路径
Windows下的Nodejs npm路径是appdata,担心安装的node_modules越来越多,导致C盘满,所以参考别人的博文,将node_modules安装的默认目录修改一下. 参考Wind ...
-
windows系统下简单nodejs安装及环境配置
相信对于很多关注javascript发展的同学来说,nodejs已经不是一个陌生的词眼,这里不想谈太多的nodejs的相关信息.只说一下,windows系统下简单nodejs环境配置 相信 ...
-
如何用python在Windows系统下,生成UNIX格式文件
平时测试工作中,少不了制造测试数据.最近一个项目,我就需要制造一批可在UNIX下正确读取的文件.为确保这批文件能从FTP下载成功,开发叮嘱我:“文件中凡是遇到换行,换行符必须是UNIX下的LF,而不是 ...
-
Windows环境下npm install常见错误
Windows环境下npm install安装包依赖时,常出现一些错误,下面为个人解决办法: 错误一 缺少python环境: G:\nodejs\moviesite\node_modules\bcry ...
-
windows系统下简单nodej.s环境配置 安装
国内目前关注最高,维护最好的一个关于nodejs的网站应该是http://www.cnodejs.org/ windows系统下简单nodejs环境配置. 第一步:下载安装文件 下载地址:官网 htt ...
-
windows系统下安装MySQL
可以运行在本地windows版本的MySQL数据库程 序自从3.21版以后已经可以从MySQL AB公司获得,而且 MYSQL每日的下载百分比非常大.这部分描述在windows上安装MySQL的过程. ...
随机推荐
-
POI完美解析Excel数据到对象集合中(可用于将EXCEL数据导入到数据库)
实现思路: 1.获取WorkBook对象,在这里使用WorkbookFactory.create(is); // 这种方式解析Excel.2003/2007/2010都没问题: 2.对行数据进行解析 ...
-
gulp-babel 取消严格模式方法
最近项目决定用ES6语法重构,于是引入了gulp-babel去编译ES6. 问题来了,babel编译ES6会自动添加"use strict"在js文件的最前面,这就导致之前的项目文 ...
-
Java编码规范
1. Java命名约定 除了以下几个特例之外,命名时应始终采用完整的英文描述符.此外,一般应采用小写字母,但类名.接口名以及任何非初始单词的第一个字母要大写.1.1 一般概念 n 尽量使用完整 ...
-
探讨NSString和NSMutableString的内存问题以及copy和MutableCopy两个方法
NSString: //main.m #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { ...
-
Java 循环和函数(方法)
1 for循环嵌套 简而言之,就是一个for循环语句里面,还有一个for循环语句. 外层循环,每循环一次,内层循环,循环一周. 示例 package java003; /** * 2017/9/1. ...
-
xgboost安装指南(win10,win7 64位)
---恢复内容开始--- Win7 64位系统下安装XGBoost 1. 环境介绍 计算机系统:win7 64位 Xgboost版本:xgboost0.6 2. 依赖软件环境 1) python 64 ...
-
Java开发笔记(六十三)双冒号标记的方法引用
前面介绍了如何自己定义函数式接口,本文接续函数式接口的实现原理,阐述它在数组处理中的实际应用.数组工具Arrays提供了sort方法用于数组元素排序,可是并未提供更丰富的数组加工操作,比如从某个字符串 ...
-
SQL SERVER数据库附加是只读的解决方法
使用sa登录SQL Server2008附加数据库,附加之后数据库为只读的, 点数据库-->“属性”-->“选项”-->“状态”, 发现“数据库为只读”这一项为True,改为fals ...
-
区间DP,数位DP
dp(动态规划)顾名思义便是动态的一种规划,而这种规划往往会跟状态,状态转移方程,记忆化搜索扯上关系,当然DP也是各个OI考试的必考点和常考点,在毒瘤出题人的折磨下,出现了许许多多的动态规划,有线性, ...
-
阿里云rds mysql数据库数据恢复到ecs中
背景:aliyun上的rds数据库快满了,于是删除了某个备份的表后面大boss说是有用的表,需要恢复回来,阿里云有7天内的物理全量备份(通过percona-xtrabackup备份的)第一时间应该延长 ...