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

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

  •  1
     
  •   drymonfidelia · 1 天前 · 4782 次点击

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

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

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

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

    71 条回复    2025-03-22 19:26:52 +08:00
    seki
        1
    seki  
       1 天前
    pnpm:你在想我?

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

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

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

    pnpm 也是非常好用的。

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

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

    C 系的依赖管理也没什么优雅的,同样混乱臃肿,只不过它最新的包管理系统穿了个马甲你就不认识了,叫做 Docker
    chengyiqun
        32
    chengyiqun  
       1 天前
    @dcoder #24 我是说给没有 python 环境的服务器导出一份包含完整解释器的环境, conda 的环境是包含完整解释器的, uv 的是软链接
    dcsuibian
        33
    dcsuibian  
       1 天前   ❤️ 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  
       1 天前   ❤️ 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  
       1 天前
    你要是不会问问题就别问,C#的开发者总能把朋友搞得少少的,敌人搞得多多的。要都像你这样,C#啥时候才能出头呀?
    thinkershare
        36
    thinkershare  
       1 天前
    @Al0rid4l Nuget 为什么需要 lockfile 这种垃圾玩意。
    Donaldo
        37
    Donaldo  
       1 天前
    @wangtian2020 #10 我个人项目都上 G 了...大厂上 G 那不是家常便饭,大家都跑路?
    LitterGopher
        38
    LitterGopher  
       1 天前
    所以为什么很少看见项目是使用 nuget install 之类的方式安装一些工具呢?

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

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

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

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

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

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

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

    对饮 Java 是 JNI 。

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

    还真没看到过啥优雅的依赖管理方式。说优雅只能说,用得还不够深度。而且,我比较喜欢都复制在本地文件夹。放在全局,项目一多了,真的头疼。每个项目都能隔离好,才是真正的优雅。而且放在本地还能一起复制走,多好。浪费点存储算什么。我有时候还会 hack 到依赖包里改源码(当然也不提交版本库,要提交也有专门的方法打 patch 吧,通过 build script 什么的),这种改依赖包源码的情况,放全局岂不是灾难?
    wlingxiao
        63
    wlingxiao  
       8 小时 58 分钟前
    宇宙第一的编程语言 c++ 就从来不参与包管理方面的讨论🐶
    niubiman
        64
    niubiman  
       8 小时 48 分钟前
    @jiangzm 你说的就是那些还在认为.net 只能运行在 windows 上的人么
    niubiman
        65
    niubiman  
       8 小时 48 分钟前
    @thoo61871 人家吹 c 井又不影响你学 java
    niubiman
        66
    niubiman  
       8 小时 47 分钟前
    @maix27 无球所谓啊 c#本来也没几个人在用
    niubiman
        67
    niubiman  
       8 小时 40 分钟前
    @LitterGopher #38 真的是精通各种语言的包安装, 大佬大佬
    niubiman
        68
    niubiman  
       8 小时 39 分钟前
    @wlingxiao 大佬没空跟菜鸡互啄
    SkywalkerJi
        69
    SkywalkerJi  
       7 小时 13 分钟前 via Android
    uv 管理依赖还可以。奇怪的是 Python 跨版本的兼容性吧。
    Syiize
        70
    Syiize  
       6 小时 1 分钟前 via Android
    等你写 Python 用到某些一直不升级依赖的 Python 包的时候,你就知道虚拟环境隔离的好处了🐶
    LitterGopher
        71
    LitterGopher  
       4 小时 56 分钟前
    @niubiman #67 开玩笑,卸载我也很精通。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1792 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 16:22 · PVG 00:22 · LAX 09:22 · JFK 12:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.