V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lihongjie0209
V2EX  ?  程序员

Nodejs 为什么不使用类似 Java 的 ClassPath + Maven 的包管理模式?

  •  
  •   lihongjie0209 · 2020-01-05 15:24:45 +08:00 · 8404 次点击
    这是一个创建于 1586 天前的主题,其中的信息可能已经有所发展或是发生改变。

    腾讯云最新优惠活动来了:云产品限时1折,云服务器低至88元/年 ,点击这里立即抢购:9i0i.cn/qcloud,更有2860元代金券免费领取,付款直接抵现金用,点击这里立即领取:9i0i.cn/qcloudquan

    (福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

    这样做的好处很明显

    1. 包只需要全局存在, 不同版本的包在不同的文件夹, 全局只需要下载一次就好了
    2. 使用包只需要在启动时指定相关的 PATH 就可以了

    这样可以完美的避免每个项目都需要 npm install 问题, 同一个包必须在每个项目中都拷贝一份

    肯定有人说现在磁盘不值钱的, 所有依赖也就几百 MB, 不值得这种优化

    但是有没有想过每次开发时每次 npm install 几分钟, 出错之后 windows 下删除又是几分钟(大量小文件)对开发效率的影响.

    我的问题是:

    1. 这种模式有什么缺点吗?
    2. nodejs 为什么没有往这个方向发展
    第 1 条附言  ·  2020-01-05 16:16:58 +08:00
    在 Youtube 上看到一个新的包管理工具, 和上面的想法类似
    89 条回复  ?  2020-01-07 07:16:48 +08:00
    hantsy
        1
    hantsy  
       2020-01-05 15:32:33 +08:00
    最新的 Yarn,NPM 好像都是全局的吧,只是项目下有一份 Copy。
    lihongjie0209
        2
    lihongjie0209  
    OP
       2020-01-05 15:46:14 +08:00
    @hantsy #1 应该说是全局缓存吧, 安装的时候还是会复制缓存到项目下
    realkenshinji
        3
    realkenshinji  
       2020-01-05 15:50:42 +08:00 via iPhone
    缺点就是同一个包可能在不同项目下的版本不同,所以分项目来安装依赖是必须的,我想这也是 python 下项目为什么要搞 venv 的原因吧
    charlie21
        4
    charlie21  
       2020-01-05 15:59:42 +08:00
    明知道有大量小文件的操作,为什么要在 win 下进行呢?
    lihongjie0209
        5
    lihongjie0209  
    OP
       2020-01-05 16:04:14 +08:00   ?? 5
    @charlie21 #4 我没必要因为一个包管理器换操作系统和硬件吧
    lihongjie0209
        6
    lihongjie0209  
    OP
       2020-01-05 16:06:34 +08:00
    @realkenshinji #3 在 Java 中, 比如说你要使用 packagex 1.1 版本的包, 那么就会在启动时指定 "maven 本地仓库 /packagex/1.1", 当你在另一个项目中使用 2.1 版本的时候, 就会指定 "maven 本地仓库 /packagex/2.1", 所以不会冲突
    watzds
        7
    watzds  
       2020-01-05 16:25:04 +08:00 via Android
    Java 要运行,也会打包复制那些吧
    watzds
        8
    watzds  
       2020-01-05 16:25:20 +08:00 via Android
    Java 要服务器上运行,也会打包复制那些吧
    agagega
        9
    agagega  
       2020-01-05 16:27:25 +08:00 via iPhone
    这不是 Node 一直吹的优点之一吗?像 RubyGems 这些工具就是像楼主说的一样按版本安装在系统目录的。
    另外,install -g 不行?
    lihongjie0209
        10
    lihongjie0209  
    OP
       2020-01-05 16:27:35 +08:00
    @watzds #8 类似 webpack, 是可以配置的. 不过这里讨论的是在开发阶段, 如何避免这种不必要的依赖安装
    lihongjie0209
        11
    lihongjie0209  
    OP
       2020-01-05 16:28:52 +08:00
    @agagega #9 估计全局安装问题很大, 因为设计上之前就没考虑过这么使用
    houzhenhong
        12
    houzhenhong  
       2020-01-05 16:50:58 +08:00   ?? 2
    pnpm 和 yarn 的 pnp 不知道符不符合你的要求
    lihongjie0209
        13
    lihongjie0209  
    OP
       2020-01-05 16:52:17 +08:00
    @houzhenhong #12 我去看看, 感谢回复
    leafdream
        14
    leafdream  
       2020-01-05 17:35:38 +08:00
    你可以 npm i -g
    gitjavascript
        15
    gitjavascript  
       2020-01-05 17:42:29 +08:00
    难道你们在服务器上 install 么
    zappos
        16
    zappos  
       2020-01-05 17:46:27 +08:00 via Android
    @realkenshinji venv 还不如 docker 方便。。。而且 venv 只解决 python 的问题,docker 可以解决任何语言的这类问题。
    jybox
        17
    jybox  
       2020-01-05 17:46:27 +08:00
    最大的好处就是每个包可以对自己使用的依赖版本有充分的控制。Node.js 里一个项目(由若干个包构成)里可以同时使用同一个包的不同版本,而不必像 Java (我不是很了解 Java,但我听说是这样)在一个项目中,只能使用一个包的特定版本,如果不同的包依赖了同一个包的不同版本,就可能出现无法解决的依赖冲突。

    作为一个 Node.js 开发者,我是非常认可这种做法的,我认为这种设计所解决的问题是要比带来的麻烦多的。
    zappos
        18
    zappos  
       2020-01-05 17:52:45 +08:00 via Android
    ( 1 )可以选择安装在局部和全局,( 2 )局部优先

    npm 都实现了啊,没问题啊

    只不过有时候 require 全局的包需要配置个路径,我记得,配置了就好了
    optional
        19
    optional  
       2020-01-05 18:00:03 +08:00 via iPhone
    这是优点。。不是缺点。 全局安装还要管权限之类的问题
    lihongjie0209
        20
    lihongjie0209  
    OP
       2020-01-05 18:02:04 +08:00
    @optional #19 不需要, 类似 maven 全局安装可以指定任何目录, 每一个项目都可以配置自己的全局目录, 极端情况可以做到类似 npm 的一个项目一个本地仓库
    lihongjie0209
        21
    lihongjie0209  
    OP
       2020-01-05 18:02:40 +08:00
    @optional #19 如果这是优点的话, 那么 pnpm 和 yarn 的 pnp 出现的意义是什么
    zhbhun
        22
    zhbhun  
       2020-01-05 18:40:58 +08:00
    同意 jybox 的看法,现在项目依赖多了出现版本冲突的情况很正常(假设模块 A 和 B 都依赖 C,但 C 的版本不同,A 要的是 Cv1,B 要的是 Cv2)。而基于 nodejs 依赖的查找原理(从当前目录开始往上级目录查找 node_modules 下的依赖),将依赖放在本地( B 和 C 各自在其目录下放一个对应版本的 C )可以很好的解决依赖版本冲突问题。
    MoccaCafe
        23
    MoccaCafe  
       2020-01-05 18:46:03 +08:00
    npm 最严重的问题就是安装依赖之后,有上万个细小文件,严重占据 inode 或者说复制困难。像 java 的 jar 包就非常合理了,java 虽然繁琐但是许多设计思想还是很好的
    murmur
        24
    murmur  
       2020-01-05 18:46:30 +08:00
    所以才有了 npm3,所以才有 yarn,npm 老版本的树状结构再 windows 下简直是噩梦,以前真的就是没法用
    zhbhun
        25
    zhbhun  
       2020-01-05 18:47:03 +08:00
    在 window 上的 nodejs 开发体验确实不好,我现在都是在 window 上用 vagrant 开个虚拟机,然后使用 vscode 的 ssh 远程开发,即使依赖再多 node_moduels 也是秒删的,node 运行时 cpu 占用率也低,风扇噪音也小了很多。
    Juszoe
        26
    Juszoe  
       2020-01-05 19:00:26 +08:00
    Node 之父也认为 node_modules 的设计是个错误
    sessionreckon
        27
    sessionreckon  
       2020-01-05 19:27:35 +08:00
    @jybox Java 这种情况是可解的,就是比较麻烦,需要重新用 shade 打个包
    Bromine0x23
        28
    Bromine0x23  
       2020-01-05 19:45:46 +08:00   ?? 1
    个人认为 npm 的问题主要还是 node_modules
    1) 依赖数量多(普遍上千),依赖安装后产生了大量文件夹和小文件,文件系统负担很大(当然这个可能算 js 依赖本身的性质导致的)
    2) 默认将依赖解压到项目下的行为导致了重复存储,结合 1) 加剧了文件系统负担。

    不同项目依赖不同版本的问题和使用全局存储是不冲突的,只要在路径上加上版本信息就行 比如 maven 用 package/version/ 或者 gems 用 package-version/
    optional
        29
    optional  
       2020-01-05 19:55:18 +08:00 via iPhone
    @lihongjie0209 没有银弹解决所有人的需求和爱好
    wangyzj
        30
    wangyzj  
       2020-01-05 20:20:45 +08:00
    说实话
    我更喜欢每个项目单独管理自己的依赖
    干净
    lihongjie0209
        31
    lihongjie0209  
    OP
       2020-01-05 20:23:09 +08:00
    @wangyzj #30 难道 maven 做不到?
    lewis89
        32
    lewis89  
       2020-01-05 20:54:44 +08:00
    @jybox #17 maven 是有一个默认优先的 ,最短引用路径的版本优先机制 ,
    你没遇到过坑,我遇到过 那种动态反射拿出来了一个老版本的 class
    但是用新版本的方法去调用 结果 出现 class 没有这种方法的报错,这种问题在 maven 打包的 java 里面经常遇到
    lewis89
        33
    lewis89  
       2020-01-05 20:58:03 +08:00
    @lihongjie0209 #31

    @jybox #17

    https://segmentfault.com/a/1190000014938685

    看看 maven 吧 一样有很多问题,版本依赖冲突这种问题 没什么好办法 ,只能通过人为管理的办法。
    lewis89
        34
    lewis89  
       2020-01-05 21:04:08 +08:00
    @lihongjie0209 #31 我被 maven 坑了也不是一次两次了,最后还是想办法 excluse 掉一些引用 避免默认的最短路径优先的仲裁机制。
    autoxbc
        35
    autoxbc  
       2020-01-05 21:08:55 +08:00
    所以 Deno 里没有包管理,依赖什么就 import 网络地址,Deno 扫描一下全局缓存着
    wangyzj
        36
    wangyzj  
       2020-01-05 21:21:23 +08:00
    @lihongjie0209 没用过 maven
    可你问的不是全局管理包吗
    uxstone
        37
    uxstone  
       2020-01-05 22:07:01 +08:00
    @jybox 为什么要在项目里使用同一个包的不同版本,强行增加复杂度?
    uxstone
        38
    uxstone  
       2020-01-05 22:12:27 +08:00
    https://v2ex.com/t/334487
    三年前 我也提问过同样的问题, 慢慢习惯下来也就这样了
    lihongjie0209
        39
    lihongjie0209  
    OP
       2020-01-05 22:16:04 +08:00
    @uxstone #37 我看到这种说法的时候也是挺懵逼的, 这种情况应该尽量避免, 避免不了就特殊处理, 从来没把这种东西当作一个正常的需求
    lihongjie0209
        40
    lihongjie0209  
    OP
       2020-01-05 22:19:42 +08:00
    @wangyzj #36 我说的是全局存储, 动态加载, 没必要拷贝到当前项目下
    lihongjie0209
        41
    lihongjie0209  
    OP
       2020-01-05 22:21:47 +08:00
    @lewis89 #34 每次加依赖都应该把 effective pom 导出来看看, 这样可以避免很多问题
    abcbuzhiming
        42
    abcbuzhiming  
       2020-01-05 22:29:33 +08:00
    说 npm 已经解决了的各位,我问一个问题,一个包,怎么才能在全局安装多个版本?到目前为止,我就没发现默认的 npm 有多版本共存的解决办法
    lewis89
        43
    lewis89  
       2020-01-05 22:34:05 +08:00
    @lihongjie0209 #41 但是 Java 有些地方是动态加载 调用的 还是没法避免..
    lihongjie0209
        44
    lihongjie0209  
    OP
       2020-01-05 22:38:34 +08:00
    @lewis89 #43 这种问题应该会在开发和测试阶段就暴露出来, 同样的, 使用 BeanUtils 也只能在运行时报错, 只要使用了反射, 这种问题就无法避免
    MiracleKagari
        45
    MiracleKagari  
       2020-01-05 22:40:52 +08:00 via Android
    @uxstone 不是你用,是你引入的依赖用的依赖是不同的版本
    YuTengjing
        46
    YuTengjing  
       2020-01-05 22:45:00 +08:00
    因为 node 是基于文件系统的模块化方案,设计上没有所谓的 classpath,必然是所有包都要安装到 node_modules 下。
    jybox
        47
    jybox  
       2020-01-05 23:22:35 +08:00
    @uxstone
    @lihongjie0209
    因为你控制不了你依赖的其他包作者用什么版本呀。举个例子 lodash 是 NPM 上被依赖最多的包,你项目依赖的很多其他包可能也依赖了 lodash,而他们依赖的版本可能和你不同。
    Kilerd
        48
    Kilerd  
       2020-01-06 00:51:21 +08:00
    有一说一,为什么还有人觉得 java 的包依赖管理好的呢
    ashong
        49
    ashong  
       2020-01-06 02:01:48 +08:00 via iPhone
    这正是 npm 的优点
    zhw2590582
        50
    zhw2590582  
       2020-01-06 08:39:09 +08:00 via iPhone
    我当时也有这样的疑问
    yinzhili
        51
    yinzhili  
       2020-01-06 08:52:37 +08:00
    nodejs 这种新生事物各种包管理工具还有点混乱,和已经成熟的 java 生态系统没法比
    lihongjie0209
        52
    lihongjie0209  
    OP
       2020-01-06 08:58:04 +08:00
    @Kilerd #48 有什么缺点吗?
    lihongjie0209
        53
    lihongjie0209  
    OP
       2020-01-06 09:18:59 +08:00
    @yinzhili #51 我也是这么想的, 以后的项目我们是不是应该直接照抄业界也有的实现, 然后再根据自己的需求做定制化, 这样可以避免走一些别人已经踩过的坑.
    yhxx
        54
    yhxx  
       2020-01-06 09:31:14 +08:00
    有的
    PnP、pnpm、tink 都是这种思路
    deleteDB
        55
    deleteDB  
       2020-01-06 09:36:00 +08:00
    别问 问就是前端不行
    一会是接口展示不行
    一会是包管理不行

    java 最棒 手动狗头保命
    lihongjie0209
        56
    lihongjie0209  
    OP
       2020-01-06 09:46:56 +08:00
    @yhxx #54 目前来看 pnp 和 tink 都在开发中, 还没有大规模使用, 而且 pnp 和 tink 都是与 hack nodejs 的 require, 如果与 wepack 使用, pnp 还需要使用自己的 loader, 总体来说改动还是比较大的
    lihongjie0209
        57
    lihongjie0209  
    OP
       2020-01-06 09:47:56 +08:00
    @deleteDB #55 你这种话没有任何意义, 行不行是一个很主观的东西, 但是有些东西缺点很明显, 还不能拿出来讨论了?
    hitaoguo
        58
    hitaoguo  
       2020-01-06 09:56:06 +08:00
    1.路径会不会有问题?
    你的电脑跟我的电脑全局安装的路径可能会不一样,项目里面如何引用。
    hitaoguo
        59
    hitaoguo  
       2020-01-06 09:57:24 +08:00
    2.移除包的时候,会不会冗余?
    比如这个包我只在一个项目里面用了,那我在项目里面 npm un 的时候会不会把全局的也删掉,那如果多个项目引用怎么判断。
    yannxia
        60
    yannxia  
       2020-01-06 09:57:57 +08:00
    还是 Rust 的 Cargo 的包管理模式好啊,随便你怎么依赖不同的版本。Maven 的问题就是多版本依赖的问题,至于 NPM 的问题,包的质量的太低是真的。
    deleteDB
        61
    deleteDB  
       2020-01-06 09:59:04 +08:00
    @lihongjie0209
    “有些东西缺点很明显, 还不能拿出来讨论了?”
    换做我, 我会问为什么当初这么设计,为什么没考虑到这些缺陷?有什么原因么?如何避免?

    为什么调侃你, 你想过么?有的人说话特别武断还不能调侃了? 哈哈哈
    lihongjie0209
        62
    lihongjie0209  
    OP
       2020-01-06 09:59:30 +08:00
    @hitaoguo #59 这些都是可以配置的, 而且在 maven 中不存在一个 uninstall 的概念, 你的项目如果不需要这个依赖, 那么就直接在 pom 中移除就好了
    lihongjie0209
        63
    lihongjie0209  
    OP
       2020-01-06 10:00:23 +08:00
    @deleteDB #61 看一下我的问题
    deleteDB
        64
    deleteDB  
       2020-01-06 10:02:18 +08:00   ?? 1
    @lihongjie0209 看一下你平时留言的表达吧 哈哈 就是想怼你
    deleteDB
        65
    deleteDB  
       2020-01-06 10:02:46 +08:00
    @lihongjie0209 其他帖子 别人的帖子里都看看
    szq8014
        66
    szq8014  
       2020-01-06 10:03:13 +08:00   ?? 1
    感觉很多人都理解错了, 依赖 [存储] 和 [加载] 是两回事。。

    嵌套存储:
    app
    -- m1-v1
    -- -- m3-v1
    -- m2-v1
    -- -- m1-v2
    -- -- -- m3-v2
    扁平存储
    app
    -- m1-v1
    -- m1-v2
    -- m2-v1
    -- m3-v1
    -- m3-v2

    扁平存储显然是并不存在什么多版本共存的问题,而且比嵌套存储更节省那一点点存储空间的,也并不限制你打包只能加载一个模块的一个版本,有能力当然可以把 commons-lang3 的所有版本全打进 fat-jar 或 war 包里,只不过 java 的默认类加载制度的限制导致 maven 只能默认选一个它约定下的最合适的一个版本,这并不是扁平化的存储导致的。


    想想如果 java 需要支持多版本 jar 包存在该如何改呢?
    1. 改语法 import, 在包里面加上版本? 需要源码改动不太现实~
    2. 把依赖关系带到运行时告诉类加载器,有一个类似 maven 的 pom.xml 的东西,告诉这个类依赖的版本。比如打包时直接把所有的 jar 重新打,在 META-INF 里面加上依赖描述。
    3. 学 nodejs 弄目录嵌套

    在 java 里面多版本共存还有许多问题,比如两个版本的同一个类在 jvm 看来是两个完全没关系的东西,假如一个接口返回这个类实例传再传给另一个接口时,虽然参数是需要这个类,传的也是,但是仅仅是因为不是同一个类加载器加载的,会报 class cast exception 的。

    这是 java 的问题,不是扁平化包管理的问题。

    所以大家别吐槽 maven 了,锅不在 maven~
    lihongjie0209
        67
    lihongjie0209  
    OP
       2020-01-06 10:09:39 +08:00
    @szq8014 #66 要在 Java 中实现一个包 N 个版本的话要上 OSGI, 目前我还没遇到过这种需求
    whypool
        68
    whypool  
       2020-01-06 10:22:56 +08:00
    npm 除了质量低,没槽点了
    wangxiaoaer
        69
    wangxiaoaer  
       2020-01-06 10:25:36 +08:00   ?? 1
    用 java 这么多年了,就没遇到你们说的一个项目需要依赖同一个库的不同版本这种需求。

    但是碰到过因为多个第三方库(假设是 A 和 B )的传递依赖导致依赖了同一个库的不同版本(假设是 C ),maven 和 gradle 都提供了排除某个版本的办法。如果 A 和 B 在运行时必须用不同的 C 版本,那就对 A 和 B 的版本进行调整(弄不好某个一低版本的 A 或者 B 可以共用某个版本的 C ),确保能够兼容。如果还是不行,那就 A 和 B 里面换一个。

    但即使这样,上述情况也不多见,基本上 spring boot 一把梭,自己手工添加的第三方依赖很少有冲突的情况。

    所以 Node 为了所谓的”项目依赖同一个库的不同版本“这种小众需求而采用嵌套式的依赖存储,不惜放弃存储空间和安装效率,不敢苟同。

    不过想想一个函数作为一个库这种**行为都能够广泛存在,也就不难理解了。
    lihongjie0209
        70
    lihongjie0209  
    OP
       2020-01-06 10:29:21 +08:00
    @wangxiaoaer #69 这个需求应该是类库\中间件的需求, 他们需要保证兼容性, 作为开发者真的很少用到
    https://www.baeldung.com/osgi
    ```
    Several Java mission-critical and middleware applications have some hard technological requirements.

    Some have to support hot deploy, so as not to disrupt the running services – and others have to be able to work with different versions of the same package for the sake of supporting external legacy systems.

    The OSGi platforms represent a viable solution to support this kind of requirements.
    ```
    wangxiaoaer
        71
    wangxiaoaer  
       2020-01-06 10:51:45 +08:00
    @lihongjie0209 #70 我说的是开发过程中的普通依赖,一般通过我说的几步就解决了,还没到需要上 OSGI 的地步。
    lihongjie0209
        72
    lihongjie0209  
    OP
       2020-01-06 10:54:25 +08:00
    @wangxiaoaer #71 嗯, 所以我觉得这个需求很奇怪
    xxdd
        73
    xxdd  
       2020-01-06 10:58:07 +08:00
    @Livid ID:deleteDB 戾气和低效讨论
    yhxx
        74
    yhxx  
       2020-01-06 11:04:12 +08:00
    @lihongjie0209 其实我倒是觉得目前 npm 这样是个优点
    每个项目都很独立,互不影响,我觉得挺好的
    除了 npm install 的时候慢了一点之外好像也没什么不能接受的缺点
    Curtion
        75
    Curtion  
       2020-01-06 11:19:29 +08:00
    npm 非常复杂,该机制成本很大,就 npm3 光展平包就花了大量功夫, 而且现在也有一些好处,比可以直接拷贝文件夹实现移动项目;还有一个好处可以直接修改包的源码,而不影响其它项目,因为 npm 的包实在太多了,很多包之间会产生 bug,这时候需要手动修复,如果等作者更新可能会很慢,因为出现 bug 的包不一定是你自己项目的依赖,有可能是项目依赖的依赖
    lihongjie0209
        76
    lihongjie0209  
    OP
       2020-01-06 11:27:21 +08:00
    @Curtion #75
    使用依赖管理的一个原因就是为了每个项目只存储依赖描述文件, 而不需要把几万个依赖上传到 git, 同时还能保证每个开发者都使用一样的依赖

    如果我们一旦修改由依赖管理软件下载的源码, 那么别的开发者使用 npm install 的时候就无法和你的依赖版本保持一致了, 正确的做法是把需要修改源码的依赖拷贝到你的项目中, 作为你的源码维护, 同时在依赖管理中去掉这个依赖.
    Curtion
        77
    Curtion  
       2020-01-06 11:44:52 +08:00
    @lihongjie0209 #76 移动项目确实毕竟鸡肋,没啥用就不谈了。 至于第二个问题,你说的对,但是这确实又是一个解决办法,我实际遇见过,我使用了一个库 A,它依赖于另一个库 B,而 B 在某些情况下会触发 bug,在 B 已经解决 BUG 的情况下,但是 A 的维护者更新落后,A 中的依赖还是比较落后的版本。
    此时修改库 B 的源代码,或者修改 A 的依赖版本是最简单的方式,等到 A 更新后只需要重新 install 就行,如果库是全局作用的,势必会影响其它项目。

    当然这只是我一厢情愿找的理由,或许实际上或者全局作用更好。不过 npm 有 cache 机制,一定情况下缓解了下载时间过长的问题。
    Curtion
        78
    Curtion  
       2020-01-06 11:51:34 +08:00
    @lihongjie0209 #76 如果把源代码拷贝出来不可行,一是以后有修复就必须手动更新,二是依赖项的层次可能很深入,我也不太了解如果把依赖提升的话,下层的代码还能不能正确找到包
    szq8014
        79
    szq8014  
       2020-01-06 11:56:20 +08:00
    @lihongjie0209 +1 目前依赖冲突就是通过选一个特定版本就解决了,觉得最麻烦的冲突也就是日志库的冲突了,有些库没有用 slf4j,直接依赖了 log4j 或 commons-logging,而项目用的 log4j2/logback,而解决方式就是用现有的 log4j 接口的实现再转回 slf4j 里面。log4j-to-slf4j, log4j-slf4j-impl 能让人迷糊,别的真没这么费脑子
    fox1955
        80
    fox1955  
       2020-01-06 12:03:24 +08:00
    "每次开发时每次 npm install 几分钟"

    - clone 下来后 install 一次, 后面开发时不用 install.

    源码是源码, 依赖也是源码, 我们把程序运行需要的完整源码放在一起, 在结构上是非常干净整洁的. 至于 "大量小文件问题", 还是那句话, 一个项目只用 install 一次, 对开发零影响. "磁盘空间问题" 不是问题.
    lihongjie0209
        81
    lihongjie0209  
    OP
       2020-01-06 12:04:56 +08:00
    @fox1955 #80 你不加依赖了吗? 修改 webpack 配置加 loader 和插件也要 install 的
    shyling
        82
    shyling  
       2020-01-06 12:34:03 +08:00
    其实也很简单。。。npm 算是管理源码的,而 maven 这种是管理 jar 的。。。node 和 jvm 的区别,源码可以随便改,jar 没那么随便。js 复制到 node_modules 里就可以开始魔改了。。。(虽然发布时不建议)

    java 系列用 build 工具解决这些问题,build 的时候去改包名解决版本冲突,文件冲突。。node 系列放在了编码时。

    集中存放 jar 也会让空间一直膨胀,升级了依赖,删了一个项目之后 maven 可不知道旧的 jar 可以删掉了。。

    不过其实也没什么好不好的吧。。。又没啥解决不了的问题。
    shyling
        83
    shyling  
       2020-01-06 12:34:45 +08:00
    @yannxia cargo 多版本的包 link 不也是会有问题
    yannxia
        84
    yannxia  
       2020-01-06 12:43:19 +08:00
    @shyling 没有吧,A 依赖 X 的 0.1 版本和 B,B 依赖 X 的 0.2 版本。是没有干扰的,Maven 不爱处理这样的问题。至于代码要同时依赖 X 的 0.1 和 0.2,这解决不了,Java 靠 Classloader 能解决,Rust 倒是不知道怎么解决,不过这个场景用的倒是不多,上面那个很常见,所以现在 Maven 直接就搞 BOM。
    shyling
        85
    shyling  
       2020-01-06 12:54:01 +08:00
    @yannxia 对,其实就是把类似 java 的 shade 把相同的 rename 了,a 用的 0.1 的 b 里的 Type 和 c 用的 0.2 的 b 里的 Type 不是一个
    azh7138m
        86
    azh7138m  
       2020-01-06 13:02:33 +08:00
    如果是问支不支持,那是支持做链接的,全局保有一份,链接到项目里面。

    因为历史原因,构建工具的 symlinks 处理是存在问题的,如果你不介意 break change,也不介意自己处理,直接用 PnP 就行了。
    love
        87
    love  
       2020-01-06 13:17:39 +08:00
    听起来你就是想节省硬盘?那你可以在工作区根目录安装所有你要用的包,工作区里所有的项目都可以直接用了
    biossun
        88
    biossun  
       2020-01-06 17:20:32 +08:00
    @zhbhun 其实是可以的,只要模块加载器根据 package.json 中的版本声明并结合 package-lock.json 中的版本信息,就可以处理 A 和 B 模块分别依赖 C 模块的不同版本的问题。
    mgoann
        89
    mgoann  
       2020-01-07 07:16:48 +08:00 via Android
    我也挺讨厌 node 的包管理机制的,重使使用了淘宝镜像很多包下载不下来,随便一个空 react 成千上万个小文件在 node modules 下,移动删除都不方便
    另外很多兄弟说为了加载不同版本的依赖包,实际情况这种需求我还真没遇到过
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3410 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 93ms · UTC 11:56 · PVG 19:56 · LAX 04:56 · JFK 07:56
    Developed with CodeLauncher
    ? Do have faith in what you're doing.


    http://www.vxiaotou.com