本文来自网易云社区

作者:陈观喜

网上关于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团队官方推荐使用的方法

准备工作

  1. 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

详细过程有兴趣的可以打开源文件看一下:
主要是以下三个文件:

  1. C:\Users\chenguanxi\AppData\Roaming\npm\npm-windows-upgrade.cmd

  2. C:\Users\chenguanxi\AppData\Roaming\npm\node_modules\npm-windows-upgrade\bin\npm-windows-upgrade.js

  3. 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升级的正确姿势以及原理的更多相关文章

  1. windows系统下npm 全局安装路径问题

    安装了nodejs之后,npm的路径默认一直都是appData,表示很讨厌,于是尝试修改在安装目录(D盘空间很大啊) 安装目录:D:\program files\nodejs 一.在nodejs下新建 ...

  2. 如何正确入门Windows系统下驱动开发领域?

    [作者]猪头三个人网站 :http://www.x86asm.com/ [序言]很多人都对驱动开发有兴趣,但往往找不到正确的学习方式.当然这跟驱动开发的本土化资料少有关系.大多学的驱动开发资料都以英文 ...

  3. windows系统下如何正确安装Cygwin(图文详解)

    我的操作系统信息是 1.在官网https://cygwin.com/install.html下载win64位安装包 选择包的下载存放目录,点击“下一步”   为了使我们安装的Cygwin能够编译程序, ...

  4. [记]Windows 系统下设置Nodejs NPM全局路径

    Windows下的Nodejs npm路径是appdata,担心安装的node_modules越来越多,导致C盘满,所以参考别人的博文,将node_modules安装的默认目录修改一下. 参考Wind ...

  5. windows系统下简单nodejs安装及环境配置

      相信对于很多关注javascript发展的同学来说,nodejs已经不是一个陌生的词眼,这里不想谈太多的nodejs的相关信息.只说一下,windows系统下简单nodejs环境配置     相信 ...

  6. 如何用python在Windows系统下,生成UNIX格式文件

    平时测试工作中,少不了制造测试数据.最近一个项目,我就需要制造一批可在UNIX下正确读取的文件.为确保这批文件能从FTP下载成功,开发叮嘱我:“文件中凡是遇到换行,换行符必须是UNIX下的LF,而不是 ...

  7. Windows环境下npm install常见错误

    Windows环境下npm install安装包依赖时,常出现一些错误,下面为个人解决办法: 错误一 缺少python环境: G:\nodejs\moviesite\node_modules\bcry ...

  8. windows系统下简单nodej.s环境配置 安装

    国内目前关注最高,维护最好的一个关于nodejs的网站应该是http://www.cnodejs.org/ windows系统下简单nodejs环境配置. 第一步:下载安装文件 下载地址:官网 htt ...

  9. windows系统下安装MySQL

    可以运行在本地windows版本的MySQL数据库程 序自从3.21版以后已经可以从MySQL AB公司获得,而且 MYSQL每日的下载百分比非常大.这部分描述在windows上安装MySQL的过程. ...

随机推荐

  1. 【洛谷5280】[ZJOI2019] 线段树(线段树大力分类讨论)

    点此看题面 大致题意: 给你一棵线段树,两种操作.一种操作将每棵线段树复制成两个,然后在这两个线段树中的一个上面进行\(Modify(l,r)\).另一种操作询问所有线段树的\(tag\)总和. 大力 ...

  2. bzoj 3028 生成函数

    计算完后为 f(x): 根据我翻高数书,终于推倒出来了. (- ̄▽ ̄)-

  3. linux jdk环境变量配置

    export JAVA_HOME=/home/faunjoe/java/jdk1.8.0_45export PATH=$JAVA_HOME/bin:$PATHexport CLASSPATH=.:$J ...

  4. maven项目发布到Tomcat丢失jar包

    昨天看了一篇tomcat设置的文章,说要把第一个勾上,这样不需要更新到tomcat.  一启动tomcat就发现丢包.后来在网上看了许多文章,说要update maeven项目,然后你就会发现启动过程 ...

  5. centos7下javac:未找到命令的问题

    在linux下编译java程序,执行javac编译生成class文件时,在centos7终端输入如,javac hello.java    会提示未找到指令,但用java -verison测试环境变量 ...

  6. OS_EVENT 信号量

    1.   OS_EVENT *T2sem=(OS_EVENT *)0; 这句代码的意思是 把OS_EVENT类型的一个指针T2sem赋值为0: 其中 OS_EVENT是数据类型,*代表是指针类型,(O ...

  7. 在Azure上部署Sqlserver网络访问不了的问题

    最近在部署Azure虚拟机的时候,一直访问不了网络数据库,一搜资料才知道,Azure默认是不打开入网规则的,需要手动设置. 在 Windows 防火墙中为数据库引擎的默认实例打开 TCP 端口 在“开 ...

  8. [HAOI2007]上升序列(最长上升子序列)

    题目描述 对于一个给定的 S=\{a_1,a_2,a_3,…,a_n\}S={a1​,a2​,a3​,…,an​} ,若有 P=\{a_{x_1},a_{x_2},a_{x_3},…,a_{x_m}\ ...

  9. ABAP术语-Business Object

    Business Object 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/07/1028364.html Represents a ce ...

  10. spring配置多个视图解析

    <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceVie ...