• 请不要在回答技术问题时复制粘贴 AI 生成的内容
drymonfidelia
V2EX  ›  程序员

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

  •  1
     
  •   drymonfidelia · Mar 21, 2025 · 10521 views
    This topic created in 600 days ago, the information mentioned may be changed or developed.

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

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

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

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

    79 replies  •  2025-03-25 11:45:46 +08:00
    seki
    seki
    Mar 21, 2025
    1
    pnpm:你在想我?

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

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

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

    pnpm 也是非常好用的。

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

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

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

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

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

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

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

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

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

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

    对饮 Java 是 JNI 。

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

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

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

    又或者, 这个星球上主流几个语言的包管理器(cargo, uv, npm, pnpm, uv, pdm, nuget, gradle)设计者都是 sb, 闲出屁来要整个没啥用的 lockfile, 那还等什么呢, 包管理器的革命就等你了, 这个世界需要你, 快到主席台上来吧
    waleslau
    waleslau
    Mar 25, 2025
    79
    @StephenHe 哈哈哈哈,确实,npm 这个“特性”确实蛮好😂
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1705 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 176ms · UTC 00:05 · PVG 08:05 · LAX 16:05 · JFK 19:05
    ♥ Do have faith in what you're doing.