经常使用 nodejs 的同学对于 node_modules 这个文件夹肯定不会陌生,这个文件夹存放了当前我们这个项目所需要的包依赖。往往我们在开发工程中需要依赖的包有很多,这些依赖的模块避免了我们重复的去造轮子,提高了开发的效率。但是 npm2 设计的包管理存在了严重的BUG。

举个栗子:我的项目需要加载模块 A,所以我的目录下有一个文件夹 node_modules 里面存放了 A。但是这个 A 项目和我一样也是依赖别人的模块才能运行的,比如他依赖了 B,不巧的是,这个 B 模块又必须需要依赖模块 C 才能运行。以此类推,重重迭代,最终导致了这个依赖层级非常非常的深,体现出的就是文件夹过长。

|/node_modules
|- A
|--/node_modules
|---B
|----/node_modules
|-----C
|-----...
|------/node_modules
|-------Z 

上面这种情况已经很不幸了,但是更为不幸的是遇到了 windows 开发平台。 windows 对于文件的路径深度有个 限制,超出了这个限制就会导致无法删除这个文件夹。

node_modules 文件夹文件夹过长

那么这个路径的限制是多少那?根据维基百科的解释:

32,767 Unicode characters with each path component (directory or filename) up to 255 characters long

也就是每一个路径元素最大不能超过 255 字符,总路径不能超过 32767 个字符。假设所有的包名都是 5 位的字母那么最多支持 2730 层嵌套。这还是比较理想的情况。下面以同一个 node_modules 文件夹(185m)演示如何删除。

  • 一、使用 rimraf 模块

针对这种文件删除,npm 上有一个 rimraf 模块,这个模块同样被用于 Gulp 清理过期文件。使用方式很简单,我们在需要移除 node_modules 文件夹下新建一个 JS 文件,代码如下:

var rimraf = require('rimraf');  
rimraf('/node_modules', [], function( err ){ console.log( err ); });  

如果在删除过程中出现了错误,会被打印出来,如果没有错误则输出 null。

这种方式可以实现删除文件夹的功能,但是我不想每次都需要再新建一个文件怎么办?没关系 rimraf 给我们命令行功能。只需要使用 npm 全局加载 rimraf,在当前文件夹下使用 rimraf node_modules 即可。

使用 rimraf 模块删除 node_modules 文件夹

  • 二、使用 DOS 命令

windows 同样也提供了类似 linux 平台的删除文件夹命令,比如删除一个文件可以使用 del/f/s/q xx.file,删除一个文件夹可以使用 rd/s/q floder。但是经过我的实验,发现这种方式也不是很好用,在某些情况下无法完全删除整个的 node_modules 文件夹。

使用 DOS 命令删除 node_modules 文件夹

如果你的电脑上装有 git,那么就一定会有 git bash 这个命令行工具,在当前目录下右键打开 git bash 使用 rm -rf node_modules 命令,同样能够删除当前的整个 node_modules 文件夹。这里就不做演示了。

  • 三、使用 winrar 工具

windows 平台自带了一个压缩软件叫 winrar。这个工具可以将文件夹压缩,但同时也可以压缩后删除原文件。具体用法非常简单,如下:

使用 winrar 工具删除node_modules 文件夹

原来的文件夹压缩后变成了 node_modules.rar 压缩包,现在我们就可以直接删除一个压缩包了。

  • 四、npm3 带来的新改变

tips: 其实还有很多种的方式,但是一般都是需要安装特别的软件,比如某卫士某60的文件粉碎功能,经过我的测试是可以使用的,这里就一笔带过了。通过上面这几张 GIF 可以很明显的看出几种文件删除方式的处理速度,其中我认为使用系统自带的 DOS 命令是最快的,但是这种方式存在有可能不能完全删除的情况,所以我个人用第一种方式比较多一点。

其实这个问题 npm 也意识到了,在最新版本的 npm 中做出了 改变,将 nodejs 的包依赖实现扁平化。假设我们的项目需要依赖模块 A,A 需要依赖 B。npm3 会直接在当前的 node_modules 文件夹下扁平化的加载这两个依赖。但是 npm2 不同的是她是用一种嵌套的方式做到的。

On npm install, npm v3 will install both module A and itsdependency, module B, inside the /node_modules directory, flat. In npm v2 this would have happened in a nested way.

其实不是很理解为什么 npm2 要实现这种方式,结构层次过深多少也会带来一些效率上的问题,也许是为了将依赖分离,不至于混乱吧。npm 我现在还停留在版本2,之后会升到 3 看看,先把毕业论文毕业设计搞搞哈哈。

(完)