V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
drymonfidelia
V2EX  ›  程序员

为什么 Python 、Node.js 就不能学习一下 C#这种优雅的依赖管理方式?

  •  1
     
  •   drymonfidelia · 10 天前 · 6337 次点击

    node_modules 每个项目都有几个 GB ,这站里大部分都是前端,应该都懂,不用多说了

    最近发现 Python 的 venv 也超大,并且比 Node.js 还离谱,每个项目的 venv 里都还会复制一遍 python 解析器

    为什么就不能像.NET 的 NuGet 一样,把依赖都按版本放在一起?放在项目目录里,还要配置版本管理排除

    NuGet 的包缓存目录里有版本号,不同依赖版本不会冲突

    79 条回复    2025-03-25 11:45:46 +08:00
    seki
        1
    seki  
       10 天前
    pnpm:你在想我?

    nv:你在想我?
    seki
        2
    seki  
       10 天前
    哦,python 的那个叫 uv
    abcdxe2v
        3
    abcdxe2v  
       10 天前
    历史遗留 不好改了。。
    rogerer
        4
    rogerer  
       10 天前   ❤️ 1
    因为存储不值钱
    dcoder
        5
    dcoder  
       10 天前   ❤️ 2
    @drymonfidelia
    用下面这个两个, 代替默认的 Python, Node 包管理
    https://docs.astral.sh/uv/
    https://pnpm.io/
    yuankui
        6
    yuankui  
       10 天前
    yarn2: 你在说我?
    c0t
        7
    c0t  
       10 天前 via iPhone   ❤️ 2
    我一个以前很讨厌 python 的人,用了 rye + uv 之后,开始喜欢写 python 工具了,特别是嵌入式工具的脚本
    crackidz
        8
    crackidz  
       10 天前
    Python venv 不应该会复制解析器,直接链接的啊... 但是 venv 和 node_modules 的情况类似,你都需要每个项目复制一遍依赖包,当然情况多少比 node_modules 好一点点
    charlie21
        9
    charlie21  
       10 天前
    npm: 不同 package 自己在 package.json 里指定了自己的依赖版本,怪我咯?
    https://stackoverflow.com/questions/65487385/should-i-duplicate-peerdependencies-in-dependencies-field-of-package-json
    wangtian2020
        10
    wangtian2020  
       10 天前   ❤️ 2
    其他语言什么装包速度也配跟 nodejs 比。我看一了一下新项目的 node_modules 大小只有 500MB 。一般能 node_modules 上 G 的,肯定是什么公司里的屎山代码,这种公司啊,不值得待应该跑路。
    node_modules 要是容量大了,那还不是编译了 node-sqlite 、node-sass 之类外来二进制包的锅
    samnya
        11
    samnya  
       10 天前
    pnpm 和 uv 都是靠链接,我个人还是更喜欢全局中央仓库的概念,让软件自己去中央仓库找。

    依赖版本号冲突的时候,在那里反复安装删除就受不了,用 pip 的肯定都体验过。中央仓库直接什么版本都有,反正调用的时候去取吧。
    guiyumin
        12
    guiyumin  
       10 天前 via iPhone   ❤️ 1
    现在才$0.1/gb
    没必要吧
    不要为了节省空间而浪费大家的时间
    chengyiqun
        13
    chengyiqun  
       10 天前   ❤️ 1
    uv 这种靠链接, 有时候需要打包一个可执行环境给别人, 还是用 conda 方便些
    yolee599
        14
    yolee599  
       10 天前 via Android
    独立的 venv 也有独立的好处,不同环境不会互相污染,清理的时候文件夹一删就完事
    darktutu
        15
    darktutu  
       10 天前
    那生成 requirements.txt 有什么好方式吗,每次都是切到 venv 环境下一顿处理,才能弄到只有必须的包,要不总会包含很多别的不用的包?才开始使用 python ,希望不吝赐教啊
    cdwyd
        16
    cdwyd  
       10 天前 via Android
    @darktutu pipreqs
    Bingchunmoli
        17
    Bingchunmoli  
       10 天前 via Android
    @wangtian2020 没见过公司项目少于 g 的 node_mofules 。。。
    NessajCN
        18
    NessajCN  
       9 天前
    Sounds like a skill issue
    darktutu
        19
    darktutu  
       9 天前
    @cdwyd 尝试过,不知道哪弄得不对,会出异常。就没有继续研究。
    qsnow6
        20
    qsnow6  
       9 天前
    @NessajCN i don't think this is a issue.
    kzfile
        21
    kzfile  
       9 天前
    非不为也,实不能也
    a33291
        22
    a33291  
       9 天前
    @wangtian2020 先不说 node_modules 大,就算 500 也不小了.大部分 c#的包以 nupkg 形式发布(实际上就一个压缩包),基本都是 kb 级别
    nziu
        23
    nziu  
       9 天前
    历史遗留问题,当初设计的时候就是凑合用能跑就行甚至都没有包管理。
    dcoder
        24
    dcoder  
       9 天前
    @samnya @chengyiqun
    uv 靠链接的主要问题是什么? uv 里的 lock (with version+hash) 还是可以靠谱的重复 build 的.

    @chengyiqun
    还有, 你要打包成执行文件的话, 不是应该靠 pyinstaller 么?
    如果只是导出执行环境的话, uv 的配置文件不比让 conda 打包环境更方便么?
    encro
        25
    encro  
       9 天前
    rye + uv 是非常好用的。

    pnpm 也是非常好用的。

    conda 也是非常 nice 的。
    maocat
        26
    maocat  
       9 天前 via Android
    看了 op 的历史帖子,原来是 c 艹艹的死忠啊
    CyouYamato
        27
    CyouYamato  
       9 天前
    看了眼正在写的三个 node.js 项目, 两个后端一个前端, 最多的一个是后端也没超过 500MB.好奇上 G 的都是什么重量级的项目?
    ipwx
        28
    ipwx  
       9 天前
    好几年前我也迷信过 static linking 、single binary executable ,觉得这样做个小工具给别人用很 cool 。觉得 python 拖一堆依赖库很麻烦。

    现在嘛,面向工资编程了还管这个?依赖库大无所谓,写程序快就行 。
    woniu7
        29
    woniu7  
       9 天前
    我不喜欢 py 和 node 的原因之一就是这个,看来不是我只有我这么认为
    觉得这两好的多用别的后端语言都能感觉到差距,生态成就了他们。
    向来都是市场决定价值,只要不烂到不行,优秀的东西他没市场就是要凉,哎😮‍💨
    来吧,冲我(引战
    Subfire
        30
    Subfire  
       9 天前
    Maven Gradle 这种就挺好, 去本地中央仓库里自取需要的版本
    nomagick
        31
    nomagick  
       9 天前
    首先开发依赖和运行依赖是不一样的,你说的 python 和 node.js 都是兼顾开发和运行依赖的。

    C 系的依赖管理也没什么优雅的,同样混乱臃肿,只不过它最新的包管理系统穿了个马甲你就不认识了,叫做 Docker
    chengyiqun
        32
    chengyiqun  
       9 天前
    @dcoder #24 我是说给没有 python 环境的服务器导出一份包含完整解释器的环境, conda 的环境是包含完整解释器的, uv 的是软链接
    dcsuibian
        33
    dcsuibian  
       9 天前   ❤️ 2
    因为 Node.js 和 npm 作者太菜了呗,抄都不会抄
    C#我不知道就不说了。反正 npm 给 Maven 提鞋都不配,属于屎中屎
    1 、本地统一中央仓库。存储空间我倒感觉无所谓,但问题是速度。Maven 的一旦本地有依赖了,就不走网络请求了( SNAPSHOT 版除外)。速度差别极大,尤其是对于细碎小文件来说
    2 、命名空间。Maven 的包名其实分了 groupId (域名反写)和 artifactId (模块名),即使模块名冲突,域名也不会。你再看看 npm 的包名抢注: https://v2ex.com/t/974118 。当初 left-pad 事件的导火索我记得就是 npm 的包名转移吧。
    3 、审核机制,npm 曾经还被人拿来保存盗版视频: https://www.v2ex.com/t/1012222
    4 、关于包的删除。https://stackoverflow.com/questions/9789611/removing-an-artifact-from-maven-central ,除非你有特殊情况联系 Sonatype 的审核,否则你是删不掉自己上传的包的。我真的很难想象是怎么发生 left-pad 这种事件的。
    5 、语义化版本控制。属于说的很好,但完全没用的设计。最好的方法就是完全锁死版本,手动升级,保证构建稳定性。联系到 npm 投毒,就显得更垃圾了。
    Al0rid4l
        34
    Al0rid4l  
       9 天前   ❤️ 3
    首先, 现在还在用 npm 的肯定都是业余兼职前端的, 十有八九都是后端在公司被迫兼职前端的, 那就别锐评了

    其次, pnpm 没有每个项目都复制一遍依赖的问题. npm: Windows 可以复制 dll, 我不可以学习一下微软先进思想复制 node_modules?

    另外, 哪怕是 npm 的几个 G 放现在根本算不上什么黑点, Nuget 依赖小, 但.NET 构建产物可不小, 我随便打开本地一个.NET 项目一看, 几百 M 到几个 G 的都很正常, Rust 项目下的随便几个 G 十几个 G 也没见人黑

    最后, pnpm 就是这个星球最好的包管理器, 没有之一. .NET 吹下 C#语言啥的没问题, 但别吹 Nuget, 这玩意和优雅沾不上边, 黑前端黑点别的可以, 黑包管理也属于是黑不到点子上. 以前我也以为前端包管理非常 sb(但那时我都已经在用 pnpm 了), 直到我看了其他家都是怎么做的, 才发现原来都是残疾人, pnpm 真香.

    以 Nuget 为例, 2018 年才整出个 lockfile 这种连 npm 都玩剩下的东西, 结果到现在还没几个人用. 总是听前端扯什么幽灵依赖菱形依赖的, 我看看 Nuget 菱形依赖怎么解? 一看解析个最低版本依赖只保留一份我差点昏了过去, 合着原来你们都不解决的啊, 不解决就等于没有问题, 天才, 以至于现在我都是用 paket 做包管理了(但 paket 也有它的问题). 区分 dev 依赖和 runtime 依赖吗? 不区分, 当然你要说能通过 PrivateAssets 和 ReferenceOutputAssembly 控制那勉强也算有吧.

    文档, 都说 MSDN 文档天下第一, 结果为了发个包去看 Nuget 的文档发现好几份, 我随手一翻 https://learn.microsoft.com/zh-cn/nuget/what-is-nuget,
    https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-nuget-config-get,
    https://learn.microsoft.com/en-us/nuget/nuget-org/publish-a-package

    MSBuild, 这玩意的文档更是散落在 MSBuild 的各个角落, 以前我觉得 webpack 工程师名不虚传, 后来发现 MSbuild 才是重量级
    https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/compiler-options/language,
    https://learn.microsoft.com/zh-cn/dotnet/core/project-sdk/overview,
    https://learn.microsoft.com/en-us/dotnet/core/deploying/single-file/overview?tabs=cli,
    https://learn.microsoft.com/zh-cn/visualstudio/msbuild/common-msbuild-project-properties?view=vs-2022,
    它就不能把这些配置项写在一起, 以至于我专门为了 MSBuild 的配置整了个收藏夹目录作为手册方便查阅, 看完这些我都要成 MSBuild 配置仙人了

    https://imgur.com/k9cA79s

    补充一点参考资料
    https://www.zhihu.com/question/36697792/answer/3575608392
    https://www.zhihu.com/question/586423333
    https://fsprojects.github.io/Paket/faq.html
    maix27
        35
    maix27  
       9 天前
    你要是不会问问题就别问,C#的开发者总能把朋友搞得少少的,敌人搞得多多的。要都像你这样,C#啥时候才能出头呀?
    thinkershare
        36
    thinkershare  
       9 天前
    @Al0rid4l Nuget 为什么需要 lockfile 这种垃圾玩意。
    Donaldo
        37
    Donaldo  
       9 天前
    @wangtian2020 #10 我个人项目都上 G 了...大厂上 G 那不是家常便饭,大家都跑路?
    LitterGopher
        38
    LitterGopher  
       9 天前
    所以为什么很少看见项目是使用 nuget install 之类的方式安装一些工具呢?

    你看 go 有 go install, rust 有 cargo install, python 又 pip install, node 有 npm install, 不会是 C 艹艹做不到吧?
    thinkershare
        39
    thinkershare  
       9 天前
    @LitterGopher 你不知道是你菜比
    LitterGopher
        40
    LitterGopher  
       9 天前
    @thinkershare #39 惭愧,确实是菜逼, 而且扣脚的那种.

    但是实际情况确实是你在 GitHub 上找一些工具之类的(即便就是 C# 写的工具) 也很少有提供 nuget 进行安装的(也许有, 但我从来没有看到过, 见识浅薄)

    也有可能也许这并非 C# 的舒适区, 如果不是的话, 那 neget 又怎么有能力对其他语言的包管理器指指点点呢?
    thoo61871
        41
    thoo61871  
       9 天前
    怎么最近那么多吹 C 井的
    Al0rid4l
        42
    Al0rid4l  
       9 天前   ❤️ 2
    @thinkershare 为什么需要? 官方知道会有你这样的人来问, 所以已经给你回答了 https://devblogs.microsoft.com/nuget/enable-repeatable-package-restores-using-a-lock-file/#why-use-a-lock-file
    anzu
        43
    anzu  
       9 天前
    初始的 venv 并不大,我 python3.9 的 venv 只有十几 MB 。即使我安装了 opencv-python 和 numpy 也只有 185MB 。如果很大,你需要用 pip list 检查一下是否安装了多余的包。
    python 的哲学就是 simple is better. venv 虚拟环境完全隔离,与其它的东西毫无关联。删除也是简单地删除文件。
    Al0rid4l
        44
    Al0rid4l  
       9 天前   ❤️ 1
    @LitterGopher 有的, 叫作 dotnet add 和 dotnet restore, 分别对应添加单个依赖和安装所有依赖, 不过后者通常不会用到, 因为 build 等非常多的命令会默认执行一次 restore 以至于基本上不会用到 restore 这个命令

    还有一部分情况是, .NET 的人大多用 vs, 鼠标点点就装完了根本不知道有这些东西
    jiangzm
        45
    jiangzm  
       9 天前
    @maocat #26 人心中的成见是一座大山
    jqtmviyu
        46
    jqtmviyu  
       9 天前
    有了 uv, python 总算能用了. 之前的体验差 pnpm 太多.

    现在还有个问题, 为啥还得自己激活 venv, 就不能配置自动激活吗? 把这串 `source $PWD/.venv/bin/activate` 加到 alias 或者用 direnv, 还是很不方便.
    DOLLOR
        47
    DOLLOR  
       9 天前
    @thoo61871 最近 tsc 计划要移植到 go 嘛,c# 有点不服气了🐶
    lambdaq
        48
    lambdaq  
       9 天前
    拿 C# 和 maven 对标的其实压根不懂

    纯 py 代码没有任何依赖管理问题。你甚至直接把包复制到 PYTHONPATH 下就能跑。py 的依赖管理都是 .so 扩展导致的。

    对应 C# 你需要解决的是 winsxs 那一堆 COM 接口的组件依赖问题

    对饮 Java 是 JNI 。

    我不觉得 C# / Java 解决了这个问题。
    UnluckyNinja
        49
    UnluckyNinja  
       9 天前 via Android
    pnpm 和 bun 都是 hard link ,除了 ci 应该没人用 npm 来安装依赖了,这个问题有点“先问是不是,再问为什么”的问题
    eBPF
        50
    eBPF  
       9 天前
    @c0t +1 ,uv+typing 让我对 py 有了很大改观
    guanzhangzhang
        51
    guanzhangzhang  
       9 天前
    @ipwx 信创很多客户不能联网,还是静态编译好些,有 cve 了换二进制就行,不然就像升级 sshd openssl 把 glibc 搞崩了的
    minottomie4383
        52
    minottomie4383  
       9 天前
    别的不知道,OS 配置一下,鄙视链走起来
    nixpkgs.overlays = [
    (final: prev:
    builtins.listToAttrs (map (name: {
    inherit name;
    value = throw "FK ${name} !";
    }) (builtins.filter (name: builtins.match "nodejs.*" name != null) (prev.lib.attrNames prev)))
    )
    ];
    harlen
        53
    harlen  
       9 天前
    @chengyiqun 打包用 nultka
    harlen
        54
    harlen  
       9 天前   ❤️ 1
    @darktutu uv com 啥可以直接生成,写个流,提交的时候直接自动生成
    mayli
        55
    mayli  
       9 天前
    之前 venv 的确是,现在 uv 用 hardlink ,明显少很多了。
    nodejs py 问题是包管理器其实都是野生手搓,核心就是能用就行。
    直到最近才出现一些比较优化的工具。
    chengyiqun
        56
    chengyiqun  
       9 天前
    @harlen #53 是 Nuitka 不是 Nultka
    LaTero
        57
    LaTero  
       9 天前 via Android
    @Al0rid4l 微软文档是真的烂,不知道为什么国内这么多人吹。学 Unity 的时候查 C#的文档简直绝望,所有微软产品的文档都是一股脑塞在一起,根本猜不到想要的信息会被拆到哪个分类里,搜索也不能限定 C#,只能限定到 dotnet ,然后搜索结果全是什么 excel api 之类的。
    kakki
        58
    kakki  
       9 天前
    吵起来了,我就想看这个,maven 的管理不知道高到哪里去了
    Trim21
        59
    Trim21  
       9 天前
    不能理解 lockfile 的意义的就别参与包管理器话题了...
    Trim21
        60
    Trim21  
       9 天前
    @jqtmviyu #45 你直接 uv run 不就行了
    jqtmviyu
        61
    jqtmviyu  
       9 天前
    @Trim21 #60 我还是官方文档没仔细看, 一直以为 run 是用在 project 里, 而我一直很抗拒生成 pyproject.toml, 坚持 uv pip install -r requirements.txt 的古法仙人 . 网上的中文教程太落后了. macos 上全局设置 hardlink 和 pip 镜像也是网友评论区提醒的.
    crackhopper
        62
    crackhopper  
       8 天前
    我其实刚想说,看已经撕起来了,哈哈。

    还真没看到过啥优雅的依赖管理方式。说优雅只能说,用得还不够深度。而且,我比较喜欢都复制在本地文件夹。放在全局,项目一多了,真的头疼。每个项目都能隔离好,才是真正的优雅。而且放在本地还能一起复制走,多好。浪费点存储算什么。我有时候还会 hack 到依赖包里改源码(当然也不提交版本库,要提交也有专门的方法打 patch 吧,通过 build script 什么的),这种改依赖包源码的情况,放全局岂不是灾难?
    wlingxiao
        63
    wlingxiao  
       8 天前
    宇宙第一的编程语言 c++ 就从来不参与包管理方面的讨论🐶
    niubiman
        64
    niubiman  
       8 天前
    @jiangzm 你说的就是那些还在认为.net 只能运行在 windows 上的人么
    niubiman
        65
    niubiman  
       8 天前
    @thoo61871 人家吹 c 井又不影响你学 java
    niubiman
        66
    niubiman  
       8 天前
    @maix27 无球所谓啊 c#本来也没几个人在用
    niubiman
        67
    niubiman  
       8 天前
    @LitterGopher #38 真的是精通各种语言的包安装, 大佬大佬
    niubiman
        68
    niubiman  
       8 天前
    @wlingxiao 大佬没空跟菜鸡互啄
    SkywalkerJi
        69
    SkywalkerJi  
       8 天前 via Android
    uv 管理依赖还可以。奇怪的是 Python 跨版本的兼容性吧。
    Syiize
        70
    Syiize  
       8 天前 via Android
    等你写 Python 用到某些一直不升级依赖的 Python 包的时候,你就知道虚拟环境隔离的好处了🐶
    LitterGopher
        71
    LitterGopher  
       8 天前
    @niubiman #67 开玩笑,卸载我也很精通。
    maix27
        72
    maix27  
       7 天前
    @niubiman 没人用真得想想社区和生态的原因,国内的 C#社区就不太健康,社区里的资源基本没有 有的资源也要钱 好像大家都知道 C#要死了一样 赚快钱 能赚多少是多少,喜欢发帖的开发者也很魔怔,就跟 op 一样魔怔。

    最重要的 我不止一次看见 C#的使用者发帖抱怨面试的 C#开发者素质不高,这点对社区的建设很有阻碍作用。
    chesha1
        73
    chesha1  
       7 天前
    @kakki #58 maven 太重,别的语言( c++这种手动太多的除外)基本 1 分钟就能上手依赖管理,这个命令是安装,这个文件是依赖的配置文件,这行代码用来导包,然后就完了。maven 要讲一堆东西
    junkun
        74
    junkun  
       7 天前
    有一个原因可能是 npm 和 pip 很多都是源码分发的,很多人喜欢直接去修改依赖库的源码(比如我),如果用全局管理的方式,会导致被污染。
    另外,npm 和 pip 的很多包需要编译,甚至需要自己下源码来编译,因为有编译脚本,不独立目录容易冲突和污染。
    不像 C#和 java 基本都是字节码分发,编译好的包到处都能用。
    StephenHe
        75
    StephenHe  
       7 天前
    npm 挺好的,那些往 C 盘装东西的都不是好鸟,一点不考虑公司电脑的垃圾配置。
    mlhiter955
        76
    mlhiter955  
       6 天前
    空间不值钱,造就完了
    thinkershare
        77
    thinkershare  
       6 天前
    @Al0rid4l 事实上就是这玩意没啥用
    Al0rid4l
        78
    Al0rid4l  
       6 天前
    @thinkershare 那么反过来说, Nuget 设计确实很烂, 工作不饱和闲着没 p 事设计了一个没啥用的东西

    又或者, 这个星球上主流几个语言的包管理器(cargo, uv, npm, pnpm, uv, pdm, nuget, gradle)设计者都是 sb, 闲出屁来要整个没啥用的 lockfile, 那还等什么呢, 包管理器的革命就等你了, 这个世界需要你, 快到主席台上来吧
    waleslau
        79
    waleslau  
       5 天前
    @StephenHe 哈哈哈哈,确实,npm 这个“特性”确实蛮好😂
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5292 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 01:28 · PVG 09:28 · LAX 18:28 · JFK 21:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.