结论:

  • 1. npm uninstall会备份包本身依赖的node_modules,rm -f会删除整个目录
  • 2. npm uninstall不会删除被依赖的包。即使显式要删除这个包,但它被依赖不会删除。rm -f会
  • 3. npm uninstall有全局模式,还会删除软链,rm -r只删目录,可能漏掉软链
  • 4. npm uninstall会删除package.json中的dependencies条目,rm -r不会
  • 5. npm uninstall会安装那些在package.json中漏装的包,rm -r当然不可能有这个副作用

总之,npm uninstall和npm install是同一套代码,同一逻辑,都是【同步当前包环境】的操作。而rm -r是强制删除一个目录。

从名称上看,uninstall确实命名不佳,它非常复杂,和install一样复杂,是整个npm设计的核心,容易误解成删除。

没有文档,只能看代码,哎

分析:

比如,要删除 mkdirp

npm uninstall mkdir 

会执行下列操作

第一步 加载本地实际存在的包列表

 
readLocalPackageData (如果用 -g 全局模式会执行 readGlobalPackageData,此线不表)
read-package-tree
 这是个包,这个包会递归的读取 node_modules 下的包,返回一个排重过的列表。
 
 
 

第二步 加载 package.json 得到理想包列表

通过分析package.json得到列表

loadAllDepsIntoIdealTree

在IdealTree中过滤掉要删除的包,这样就得到两个Tree,一个是 CurrentTree,一个是 IdealTree

第三步  同步CurrentTree和IdealTree

  • 1.  如果CurrentTree中存在,IdealTree中不存在,忽略
  • 2. 如果CurrentTree中不存在,IdealTree中存在,则安装
  • 2. 如果CurrentTree中存在,IdealTree中不存在,则删除

第四步 执行删除操作的逻辑

  • 1. 如果要删除的包被当前IdealTree中其它包依赖,则不删除
  • 2. 如果要删除的包中有依赖的包,则备份它们,稍候恢复
mv ./node_modules/mkdirp/node_modules ./node_modules/.mkdirp.MODULES
rm -rf
./node_modules/mkdirp/
mkdir
./node_modules/mkdirp
mv ./node_modules/.mkdirp.MODULES ./node_modules/mkdirp/node_modules
使用 rimraf删除目录,rimraf是个包,它提供类似rm -rf的功能,递归的删除目录和文件,有重试逻辑等。

看似简单的 rm -rf为什么要单独实现呢?


nodejs fs模块早期确实没提供rm -r的功能,fs模块只提供了删除单个目录和单个文件的能力


在 v12.10.0 后提供了递归删除目录的api,在 v14.14.0 提供了rm -rf的api。


来的太迟了,所以在开发npm的时候,就采用了rimraf这个包。

如果要删除的包中,没有node_modules,则不会执行备份的操作。

npm uninstall和rm直接删除的区别的更多相关文章

  1. rm(操作系统的删除文件)与git rm的区别

    git rm:1.删除了一个文件2.把这个删除的文件纳入暂存区如果想要恢复这个文件,则需要做2个操作a.git reset HEAD file_name --将文件从暂存区恢复到工作区b.git ch ...

  2. npm install、npm init、npm update、npm uninstall和package.json

    npm install 安装本地包 npm install <package_name>:这个命令将在当前目录中创建node_modules目录(如果尚不存在),并将该软件包下载到该目录. ...

  3. npm 常用指令 使用指令删除 node_modules 包

    查看 npm 命令 npm help 全局命令参数 -g npm install -g 安装全局 npm uninstall -g 卸载全局 全局node包中 i5ting_toc 这个包可以把md文 ...

  4. rm: 无法删除&quot;/run/user/root/gvfs&quot;: 是一个目录 问题

    2013-03-02    bxd@linux:~$ sudo su [sudo] password for bxd:  root@linux:/home/bxd# exit exit rm: 无法删 ...

  5. Linux中RM快速删除大量文件/文件夹方法

    昨天遇到一个问题,在Linux中有一个文件夹里面含有大量的Cache文件(夹),数量级可能在百万级别,使用rm -rf ./* 删除时间慢到不可接受.Google了一下,查到了一种方法,试用了下确实比 ...

  6. Linux下通过rm -f删除大量文件时提示"-bash: /bin/rm: Argument list too long"的解决方法

    Linux下通过rm -f删除/var/spool/postfix/maildrop/中大量的小文件时提示: "-bash: /bin/rm: Argument list too long& ...

  7. rm: 无法删除 "xxxxx.o" : 输入/输出错误.

    rm: 无法删除 "xxxxx.o" : 输入/输出错误. 碰到无法删除的文件,以为完蛋了,要重装. 后面重启一下就可以了

  8. 一文看懂npm、yarn、pnpm之间的区别

    文作者对比了当前主流的包管理工具npm.yarn.pnpm之间的区别,并提出了合适的使用建议,以下为译文: NPM npm是Node.js能够如此成功的主要原因之一.npm团队做了很多的工作,以确保n ...

  9. Linux下通过 rm -f 删除大量文件时报错:Argument list too long

    Linux下通过 rm -f 删除大量的小文件时出现类似如下错误信息:  -bash: /bin/rm: Argument list too long 如下图所示: 问题原因 如果待删除文件中包含的小 ...

随机推荐

  1. 深度剖析text-align家族

    大家好,我是半夏,一个刚刚开始写文的沙雕程序员.如果喜欢我的文章,可以关注 点赞 加我微信:frontendpicker,一起学习交流前端,成为更优秀的工程师-关注公众号:搞前端的半夏,了解更多前端知 ...

  2. PicLite 开发日志 (v0.0.3)

    PicLite 开发日志 (v0.0.3) 感谢您阅读本片文章! Gitee 地址:https://gitee.com/XiaoQuQuSD/pic-lite. 新增功能 当错误出现时不再强制 rai ...

  3. mybatis混淆概念

    1.resultMap与resultType <mapper namespace="com.dao.FilmMapper"> <resultMap id=&quo ...

  4. Redis 缓存穿透、缓存击穿、缓存雪崩的解决方案

    一.缓存雪崩 缓存雪崩表示:指缓存同一时间大面积失效或缓存重启又或者第一次启用缓存的情况下,导致请求跳过缓存直接请求数据库,造成数据库短时间内承受大量请求而崩掉. 解决方案: 方案一 缓存数据的过期时 ...

  5. 10个 Linux 命令,让你的操作更有效率

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 根据老九大师兄口头阐述,Linux是最适合开发的操作系统 ...

  6. 老生常谈系列之Aop--Aop的经典应用之Spring的事务实现分析(三)

    老生常谈系列之Aop--Aop的经典应用之Spring的事务实现分析(三) 前言 上一篇文章老生常谈系列之Aop--Aop的经典应用之Spring的事务实现分析(二)从三个问题导入,分析了Spring ...

  7. grafana v8.0+ 隐藏表格字段

    Select panel title → Inspect → Panel JSON Set "type" to "table-old" Apply The vi ...

  8. this-3

    this是什么?JavaScript中,this关键词指的是他所属的对象:它拥有不同的值,具体取决于它的使用位置. 1.在单独情况下,this指向全局对象window:2.在函数中,this指向全局对 ...

  9. MySQL中的全表扫描和索引树扫描

    引言 在学习mysql时,我们经常会使用explain来查看sql查询的索引等优化手段的使用情况.在使用explain时,我们可以观察到,explain的输出有一个很关键的列,它就是type属性,ty ...

  10. html5 tts(文字朗读)

    在 chrome 下使用比较好的中文语音包. 注意 speechSynthesis.getVoices() 有时候可能会返回空数组,需要做验证 var zhCnLangs = speechSynthe ...