说到 node 的模块,确实既好用又蛋疼。相信无数人吐槽 node_modules 目录结构的设计了。
确实,npm 没有处理好 peerDependencies 的概念,不仅重复安装了模块,而且嵌套层次太深。
我觉得可以在安装依然的时候分析相同模块,安装到合适的层次,但是却面临一个相同模块的不同版本问题。
反正确实挺纠结的,我这样的脑子不够用。

win 的 MAX_PATH 问题

在 windows 下,目录路径不能超过 MAX_PATH 长度,具体请查阅《MAX_PATH 还是 MAX_PATH + 1》。
MAX_PATH 只有 248 字符!呵呵,10-20 个模块深度就可以超过了,大一点的模块,分分钟超越 MAX_PATH,没有最长,只有更长。

其实我也不懂那些底层概念,反正就是超过了最大长度导致的无法删除问题。
听说 npm 3 会有所改进,不过这都是后话了,现在我们先处理当前问题吧。

解决方法

解决方法也简单,把 node_modules 改成 0 然后打开这个目录,继续修改里面的目录,多个就改成 0,1,2 这样的命名。
改个 3-6 层,就差不多可以删除了,如果还删除不了,就再深入修改几层。
不过每次人工修改,确实很累,而且目录分支众多,很不方便。既然 node 惹的祸,就用 node 来解决好了。

js 脚本处理

思路就是递归遍历目录,重命名目录名,递归完成后,删除目录即可。
来看代码吧。

var fs = require('fs');

rmdirSync('./test'); // 你要删除的目录
console.log('done!');

/**
 * 删除 node 模块目录
 * @param {string} filepath 目录名
 */
function rmdirSync(filepath) {
    if (!fs.existsSync(filepath)) { // 无效路径退出
        return false;
    }

    var files = fs.readdirSync(filepath); // 获取目录下文件

    files.forEach(function (file, i) { // 遍历文件
        var subpath = filepath + '/' + file; // 拼接文件路径

        if (fs.statSync(subpath).isDirectory()) { // 判断目录还是文件
            var newpath = filepath + '/' + i; // 生成新的目录名
            fs.renameSync(subpath, newpath); // 重命名目录
            rmdirSync(newpath); // 递归遍历目录
        } else {
            fs.unlinkSync(subpath); // 删除文件
        }
    });

    fs.rmdirSync(filepath); // 删除目录
}

补充

我今天在群里装逼的时候,@Mr.Bin 大神的一句话将我打回了逗逼形态。

npm uninstall

一句话直接搞定,当时我就懵逼了。

当然如果没有保存到 package.json 的包只能手动添加包名来删除了。

npm uninstall 包名

或者多个包都没保存到 package.json 的情况,就这样删除。

for /f %m in ('dir /b node_modules') do npm uninstall %m

虽然装逼失败,但学到了新技能,当逗逼也是值的。(o)/~