V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wlwood
V2EX  ›  Node.js

你们家的 nodejs, node_modules 太占空间了。。。。

  •  
  •   wlwood · 2018-05-10 10:36:19 +08:00 · 24439 次点击
    这是一个创建于 2391 天前的主题,其中的信息可能已经有所发展或是发生改变。
    突然发现空间不够用了。。。
    https://s1.imgs.cc/img/aaaaaROv3.png?_w=750

    然后,写个脚本,把 node_modules 干掉后

    https://s1.imgs.cc/img/aaaaaROvG.png?_w=750

    瞬间有磁盘了😕😕😕
    第 1 条附言  ·  2018-05-11 10:08:11 +08:00
    结帖结帖了。
    不玩了。
    最后讨论结果:
    单个项目,咱不管了。
    多个项目,基本依赖包都一样的话,用软连接。
    10 多个项目以上,搞大点磁盘吧。
    第 2 条附言  ·  2018-05-11 10:39:36 +08:00
    sorry,原题改不了了。这里把题目改下:

    nodejs, node_modules 似乎比较占空间,求解决办法?!
    71 条回复    2019-04-25 18:14:20 +08:00
    linxl
        1
    linxl  
       2018-05-10 10:40:04 +08:00
    也就上百兆吧 哈哈哈
    owenliang
        2
    owenliang  
       2018-05-10 10:41:21 +08:00 via Android
    的确残暴
    xinhangliu
        3
    xinhangliu  
       2018-05-10 10:42:31 +08:00 via Android
    而且文件目录超级多,真的爱不起来。
    janxin
        5
    janxin  
       2018-05-10 10:49:35 +08:00
    你没理解我们 Node 社区 DRY 的真谛
    wlwood
        6
    wlwood  
    OP
       2018-05-10 10:58:48 +08:00
    @janxin 额,Node 不同项目如何 DRY 呢?安装包的时候都是 install -g 么?
    wlwood
        7
    wlwood  
    OP
       2018-05-10 11:08:05 +08:00
    话说,node 如何共享 node_modules 呢?像 python 那样 site-packages,或者 Go 那样, 共享 github.com 也行呀😄😄😄
    janxin
        8
    janxin  
       2018-05-10 11:08:15 +08:00
    并不能
    @wlwood
    wlwood
        9
    wlwood  
    OP
       2018-05-10 11:36:31 +08:00
    所以,所以,一个遍历删除 node_modules 目录脚本是不是就有必要了?



    ···python
    #!/usr/bin/env python
    # encoding:utf-8


    import os
    import sys
    import shutil

    def rm_dir(path, dirname):
    if dirname == "node_modules":
    print ("rm: ", os.path.join(path, dirname))
    try:
    shutil.rmtree(os.path.join(path, dirname))
    except Exception as e:
    print ("rm error: ", str(e))

    def rm_node_modules(root):
    for path, dirname, fs in os.walk(root):
    for dirn in dirname:
    rm_dir(path, dirn)

    def main():
    if len(sys.argv) < 2:
    print ('please input node_modules path! exit !')
    sys.exit(-1)

    path = sys.argv[1]
    print (path)
    rm_node_modules(path)

    if __name__ == "__main__":
    main()
    ```


    (注意的是,不要去删除 公共的 node_modules 啊,否则 npm 可能也会丢了)
    hcj4xhu0jerome
        11
    hcj4xhu0jerome  
       2018-05-10 12:20:57 +08:00
    vjnjc
        12
    vjnjc  
       2018-05-10 12:34:36 +08:00
    我的 maven 缓存也有 1GB 了。。。下了不少包
    buf1024
        13
    buf1024  
       2018-05-10 14:42:47 +08:00   ❤️ 1
    @wlwood 我只能说,一行命令就能解决你辛苦写的那么长一段代码的问题……

    find . -name "node_modules" -print | xargs rm -rf
    shynome
        14
    shynome  
       2018-05-10 14:54:17 +08:00
    试试 npm i --production , 只安装生产依赖
    orzfly
        15
    orzfly  
       2018-05-10 15:23:54 +08:00 via Android   ❤️ 1
    @buf1024 一个参数 -delete 就能解决的问题,至于调用 xargs 和 rm 嘛(跑

    find . -name "node_modules" -delete
    vinsony
        16
    vinsony  
       2018-05-10 15:31:10 +08:00
    我把所有依赖的 js 都打包成一个 js 文件,才几 M
    wlwood
        17
    wlwood  
    OP
       2018-05-10 15:31:14 +08:00
    @buf1024 @orzfly 大神,膜拜。😄😄😄
    wlwood
        18
    wlwood  
    OP
       2018-05-10 15:37:47 +08:00
    @shynome @vinsony 尽管你们说的都是方法,但是,开发时候,还是没有办法让不同的项目,使用相同的 node_modules 呀
    vinsony
        19
    vinsony  
       2018-05-10 15:47:34 +08:00
    @wlwood 不同的项目使用相同的 node_modules ?只怕是项目多了人都要疯
    wlwood
        20
    wlwood  
    OP
       2018-05-10 15:52:32 +08:00
    @vinsony 对呀,像其他语言就可以啊。使用相同的库,像 python,可以使用相同的 site-packages
    xiaoxin8888
        21
    xiaoxin8888  
       2018-05-10 16:42:44 +08:00   ❤️ 1
    我们家的事关你什么事?
    buf1024
        22
    buf1024  
       2018-05-10 17:22:51 +08:00
    @orzfly 至于为什么不用-delete,那是想看删除输出的文件。
    fds
        23
    fds  
       2018-05-10 17:28:38 +08:00
    就是不想共享才搞成现在这个样子的。比如 Go 语言为啥默认直接生成个静态的很大的可执行文件?依赖有问题解决起来可麻烦了,不如浪费点儿硬盘空间。
    maichael
        24
    maichael  
       2018-05-10 17:55:16 +08:00   ❤️ 1
    共用的话不好做依赖版本控制。

    你可以考虑使用 pnpm
    mooncakejs
        25
    mooncakejs  
       2018-05-10 18:06:50 +08:00
    @wlwood py 的依赖处理方式也有人吹?一个多版本直接 gg,然后搞了 pyenv venv virtualenv virtualenvwrapper 一堆出来擦屁股。 搞出来后,并没有比 npm 高多少。
    wlwood
        26
    wlwood  
    OP
       2018-05-10 18:25:56 +08:00
    @mooncakejs 起码有的选择了呀。对于很大部分人来说,并不需要多版本。
    然后,对于多于需求多版本了,可以选择那些创建虚拟环境。

    而且,怎么会不比 npm 好呢? npm 对于,每个包的依赖,不检查环境是否已经存在这个包没有,就直接又去 npm 一份回来。
    pip 对于包里面的依赖,首先检查环境,如果存在就不再下载了。所以,对于同一个环境不存在同一个包,有多个副本的情况。

    npm 对于同一个包,也可能有多个副本拷贝。

    到底哪个高呢?
    wlwood
        27
    wlwood  
    OP
       2018-05-10 18:29:30 +08:00
    @maichael 刚刚去试了下 pnpm,pnpm install 后,运行出错,服务起不来。npm 就 ok。emmmm,我去研究研究下
    wlwood
        28
    wlwood  
    OP
       2018-05-10 18:31:11 +08:00
    @fds 嗯,有道理。对于 node 来说,这样的处理方式,可能会更好吧。
    chenstack
        29
    chenstack  
       2018-05-10 18:33:27 +08:00
    说起来可能不信,我为了让几个 vue 项目共用 node_modules,把 node_modules 做成了软连接
    wlwood
        30
    wlwood  
    OP
       2018-05-10 18:36:42 +08:00
    @chenstack 很好奇,结果怎么养呢?🙂🙂🙂
    chenstack
        31
    chenstack  
       2018-05-10 18:42:12 +08:00   ❤️ 1
    @wlwood 感觉还不错,因为几个项目在同一个父目录下,依赖的库也差不多,用在开发环境上没发现什么问题
    wlwood
        32
    wlwood  
    OP
       2018-05-10 18:43:31 +08:00
    @chenstack 66666. 这个,我要试试。
    beginor
        33
    beginor  
       2018-05-10 18:45:41 +08:00 via Android
    node_modules 就是个毒瘤, 好歹学一下 nuget 嘛,全局放一个目录, 删起来方便
    a132811
        34
    a132811  
       2018-05-10 18:50:50 +08:00
    http://www.ruanyifeng.com/blog/2016/01/npm-install.html
    npm 搞出来这么多破事。。。心寒
    maichael
        35
    maichael  
       2018-05-10 18:57:36 +08:00
    @wlwood 不能就试试 yarn,反正都比 npm 好。至少现在这个版本。
    wlwood
        36
    wlwood  
    OP
       2018-05-10 19:27:21 +08:00 via Android
    @maichael 嗯,有在用的,但是还是感觉太好
    EricXuu
        37
    EricXuu  
       2018-05-10 19:46:11 +08:00
    为啥就这个页面是黑的啊
    yyfearth
        38
    yyfearth  
       2018-05-10 21:14:12 +08:00   ❤️ 5
    @wlwood @janxin @maichael 其实可以的 多个项目其实可以共享全部或者部分 node_modules
    node 会自动向上层目录寻找 所以如果有公共的依赖 而且版本一致 可以提取到上层目录的 node_modules 实现共享
    或者 如果你这些项目的依赖完全一致 可以把其中一个 node_modules 放到上层目录 然后把其他的删掉 或者 symlink
    如果你觉得太麻烦 有工具会自动帮你弄:yarn workspace
    它会自动解决多个项目的相互依赖 同时提取公共的部分到同一个 node_modules
    其他的项目会 symlink 到这个 node_modules 里面的依赖

    @chenstack 不一定要 symlink 其实 node 会自动往上层目录找 另外 yarn workspace 最适合这种情况 会自动 symlink

    @beginor 放全局目录也不一定是好事 如果你项目多 全局目录会非常大
    而且 如果你要删除一些项目的时候 全局目录就没办法清理 只会越来越大 而且你还不敢随便删除

    @wlwood 其实你说的不完全正确 npm 有 cache 的 如果有相同的依赖不会重复下载 但是由于每个项目是独立的 node_modules 自然会有独立的拷贝
    但是我觉得从部署的角度而言 独立 node_modules 其实比较方便和干净
    你只要把项目连同 node_modules 一起打包和拷贝 只要 OS 和 Node 相同 就可以直接跑起来
    而且删除的时候 也很干净 不会在 global 留下不再需要的包

    另外同一个项目下面 如果版本不同 NPM 倾向保留多个版本 这个是 node 社区的问题
    不同版本(一般除了_._.x 修正版本)之间往往不兼容 而且也有可能会有包锁定依赖版本
    NPM 现在的方法 其实是比较省事的 如果要 merge 和 flatten 反而会造成很多问题
    目前新版本的 NPM 和 Yarn 就会做一些 merge 和 flatten 结果每次更新依赖的时候 会造成一些问题
    yuann72
        39
    yuann72  
       2018-05-10 22:13:29 +08:00
    @yyfearth "如果你要删除一些项目的时候 全局目录就没办法清理 只会越来越大 而且你还不敢随便删除"
    小白问下, 不是每个项目下都有 package.json, 里面不是记载了本项目使用了哪些模块吗? 不能写个脚本检查下所有项目的 package.json 文件来确定某个模块是否有被某个项目依赖吗? 如果都没有依赖就可以删
    df4VW
        40
    df4VW  
       2018-05-10 22:18:43 +08:00   ❤️ 2
    磁盘空间什么时候成了开发的难点了
    fulvaz
        41
    fulvaz  
       2018-05-11 02:24:57 +08:00
    yyfearth
        42
    yyfearth  
       2018-05-11 03:16:20 +08:00
    @yuann72 你说的当然可以 但是问题就出在 “检查下所有项目的 package.json ”
    也就是说 要么在 cleanup 的时候整个系统寻找 package.json
    要么在 install 的时候需要记录每一个 package.json 存在的路径
    都不是一件容易而且有效率的办法

    否则 你在做清理的时候 你没办法知道有没有其他项目在使用你想要清理的包
    这样一来 就意味着 所有 node 的项目就不是 portable 的 而且也不能随便移动位置和直接删除

    现在 node_modules 最大的好处就是 node 项目大部分情况是 portable 的
    只要 OS 兼容 Node 版本 兼容 你可以随时挪动位置 或者 删除 而且不影响其他项目
    另外 如果你一个项目的包弄糟了 只需要删掉 node_modules 重来就好

    我觉得唯一的问题 不是 node_modules 太大 而是文件太多 目录太复杂
    我觉得可以学其他的语言把文件打包一下 比如 jar war phar 这些 zip 一下
    而且由于有可能会有不少重复文件 去重再压缩估计会小不少
    然后在运行时按需求解压 因为很多时候 并不是所有文件都有用到
    而且现在的机器性能 解压缩 zip 的时间基本上可以忽略 搞不好从 IO 角度
    从 zip 读取可能比加载一大堆文件还要快

    这个现在可能不是很必要 但是以后有 webasm 了 打包一下其实可以考虑的
    yyfearth
        43
    yyfearth  
       2018-05-11 03:19:04 +08:00
    另外其实还有一个好处就是 因为 node_modules 独立
    所以可以直接修改依赖而不影响其他项目
    尤其是在 debug 的时候 发现依赖的包里面有问题
    甚至可以在 npm postinstall 里面直接 patch 依赖的包
    lkytal
        44
    lkytal  
       2018-05-11 05:11:45 +08:00 via Android
    要共享就 npm link … 没那么多事,虽然不推荐
    wlwood
        45
    wlwood  
    OP
       2018-05-11 06:02:58 +08:00 via Android
    @yyfearth 这个肯定是好。但是却也是缺点啊!相同的包相同的版本,在电脑里已经有了,在不同项目,还必须要有个副本。没错,这样项目互相不依赖,但对于创建了很多很多项目来说,拷贝那么多份这就很没必要了
    wlwood
        46
    wlwood  
    OP
       2018-05-11 06:28:31 +08:00 via Android
    @df4VW 整个 SSD 盘就 50G,结果 node_modules 占用了 10 多 G...
    doubleflower
        47
    doubleflower  
       2018-05-11 08:26:40 +08:00
    可以搞个脚本用硬链接合并机器上的重复 npm 文件
    重复的文件放在一个公共文件夹,在项目目录运行下脚本,如果有和公共目录相同的文件就删除掉项目的直接硬链过去
    alamaya
        48
    alamaya  
       2018-05-11 08:45:50 +08:00 via Android
    作为个 java,用了 npm 才体会到 maven 的好。
    KuroNekoFan
        49
    KuroNekoFan  
       2018-05-11 08:54:23 +08:00 via iPhone
    软连接是可行的办法,也会带来其他问题,不过讲真这个年代真的要吝惜硬盘空间吗?
    kohos
        50
    kohos  
       2018-05-11 09:02:42 +08:00
    新版的 npm 都可以共享 node_modules 里面的文件了,装个 koa2 打开 node_modules 就是一堆包,还是在基本没有链接的 Windows 下,只有引用了不同版本的同样的包才会出现多级 node_modules 的情况。
    除非一个服务器跑几十个项目……然而既然要跑几十个项目,磁盘空间不是应该大一些吗
    ooo3o
        51
    ooo3o  
       2018-05-11 09:03:47 +08:00
    喜闻乐见
    Node 这么种设计垃圾到爆的破东西能这么流行, 给世界网络增加了巨大的流量贡献了.
    tushankaka
        52
    tushankaka  
       2018-05-11 09:26:41 +08:00 via Android   ❤️ 1
    @ooo3o 一不小心点开了你的头像。发现你不喜欢的还有 git。。。。。
    ooo3o
        53
    ooo3o  
       2018-05-11 09:40:43 +08:00
    @tushankaka 那都是以前的事了.
    现在嘛, 只要来钱快, 不喜欢都照用了, 都是赚钱的工具而已.
    yongzhong
        54
    yongzhong  
       2018-05-11 09:51:50 +08:00
    wlwood
        55
    wlwood  
    OP
       2018-05-11 09:59:47 +08:00
    @yongzhong hahah , 我用脚本检查了下,还真就这样。
    npm v5.6.0。同一个项目下,node_modules 目录下,包依赖,有大量的重复的包文件(当然,有部分做了软链接)。
    同一个包,在 node_modules 目录下有大量的拷贝
    yaxin
        56
    yaxin  
       2018-05-11 10:00:19 +08:00
    find / -type d -name "node_modules" | xargs rm -rf
    wlwood
        57
    wlwood  
    OP
       2018-05-11 10:02:38 +08:00
    @kohos
    @KuroNekoFan 对对,我要去买磁盘了。
    mritd
        58
    mritd  
       2018-05-11 10:02:51 +08:00 via iPhone
    @fds 这个,恕我直言,这个不是 "点" 空间啊,轻松上百 m 比 jdk 都大
    wlwood
        59
    wlwood  
    OP
       2018-05-11 10:03:18 +08:00
    @yaxin 这个,会把 npm 也干掉了
    mritd
        60
    mritd  
       2018-05-11 10:07:56 +08:00 via iPhone
    我就感觉 node 这个包机制都是各种神奇的,不论是从 node modules 体积,还是里面文件组织(各种软连接),异或是安装时候让你下载 gcc py2.......无处不透露着一种诡异的氛围 😒后端狗表示完全看不懂
    wlwood
        61
    wlwood  
    OP
       2018-05-11 10:12:46 +08:00
    @mritd 有的包,需要用 c 或者 cpp 来扩展什么的,就会需要 gcc 来编译啥的. 下载 py2 只是用来做脚本工作而已吧?
    mritd
        62
    mritd  
       2018-05-11 10:15:56 +08:00 via iPhone
    @wlwood 😂问题是 py 啥的还要求版本,而且事实上我可能就是为了 生成个 静态页面,后端狗对为了几个静态页面调用 gcc c++ py2 表示非常不解,感觉就像去厕所派专机过来一样
    kohos
        63
    kohos  
       2018-05-11 10:19:29 +08:00
    占容量大的包应该就是那些调 c 或者 cpp 的包,下回来一编译就几百 M,现在良心点的包已经会自带编译好的程序包了,希望其他包能多学习学习
    ipwx
        64
    ipwx  
       2018-05-11 10:25:49 +08:00   ❤️ 2
    恕我直言,我觉得 node_modules 这么庞大的原因主要还是人的问题:

    1、依赖分开来管理是好事,解决版本冲突,降低了引入一个依赖的代价。但这导致 Node 社区发布库不再“谦逊”,随便一个小功能就能开个库,并且随便一个项目就几十个库引用过去。这是人的问题。
    2、npm install -s 让人根本不用手工编辑 package.json。这本来是好事,比起 pip 还要手工写 requirements.txt 。但是手工写的肯定比自动产生的要精简得多啊。

    写 Python 项目的时候,我时不时删掉不再引用的库、尽可能避免引入库、只写直接引用的库,都是常事。虽然麻烦,但是习惯了之后,还是挺顺的流程。什么 pip freeze,是邪道,这种库除非是终端产品,不然谁敢去用?

    由于工具链的落后性,才形成了社区对待依赖库的谨慎态度。我觉得 Node 工具链不错,但是社区还是缺这么一个态度的。
    awesomes
        65
    awesomes  
       2018-05-11 10:31:00 +08:00
    请把 “你们家的” 去掉,谢谢
    df4VW
        66
    df4VW  
       2018-05-11 10:53:11 +08:00
    @wlwood 本地的话,你不常用的项目删了就好了。production 的话,就算是一个项目 10g 的占用也绰绰有余啊。除非你是做 youtube 做 aws 之类的服务,不然这么点占用根本就无所谓
    wlwood
        67
    wlwood  
    OP
       2018-05-11 10:55:11 +08:00
    @df4VW 嗯,是的。本地,之前就是不删。所以,才出现个问题。以后估计都删吧。
    mooncakejs
        68
    mooncakejs  
       2018-05-11 16:29:28 +08:00
    @wlwood "对于很大部分人来说,并不需要多版本" 这句话在实际工作中是很有问题的,你可能没参加工作?
    大部分人都需要多版本,除非你是写着玩的或者只有一个项目。项目添加依赖后,除非有 bug,否则不会轻易升级依赖,但是新开项目的时候,往往会选择新的版本,以获取最新功能,所以多版本是个很明显很直接的需求。
    至于空间浪费,现在硬盘不值钱,还可以把去重的工作丢给文件系统去解决。
    KgM4gLtF0shViDH3
        69
    KgM4gLtF0shViDH3  
       2018-08-06 09:57:02 +08:00
    @ipwx #64 requirements.txt 不需要手工写的,pip freeze >requirements.txt 这样不行吗
    xihesi
        70
    xihesi  
       2018-11-20 11:47:11 +08:00
    麻烦的就是把 node_modules 做一个公共库,多项目共用。当然是因为磁盘不够用才选着这种的。磁盘只有几十 M 了 然后把之前搞过的 NODE 项目 全部清理 node_modules 释放了好多 G。
    DuXing
        71
    DuXing  
       2019-04-25 18:14:20 +08:00
    我的 Mac Book Pro,120G,已经爆满了。
    我计算了一下,约 96 个仓库。其中 3 ~ 5 个是高频使用仓库。38 个是不定时临幸的仓库。
    一个 webpack 编译的工程的 node_modules/ 大概 50MB +。
    清除 node_modules/ 于心不忍。
    很是尴尬。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5452 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 05:58 · PVG 13:58 · LAX 21:58 · JFK 00:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.