你们家的 nodejs, node_modules 太占空间了。。。。 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wlwood
V2EX    Node.js

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

  •  
  •   wlwood 2018-05-10 10:36:19 +08:00 25083 次点击
    这是一个创建于 2712 天前的主题,其中的信息可能已经有所发展或是发生改变。
    突然发现空间不够用了。。。
    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 呀
        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-5-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     Solana     2712 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 09:56 PVG 17:56 LAX 02:56 JFK 05:56
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86