原文在知乎,欢迎交(tu)流(cao)
我终于知道为什么 npm install 总是动不动就下载 300 Mb 的东西了,Node.js 社区强调的 DRY 文化使得
node_modules
臃肿不堪,因为有的库引用了 is-object,有的库引用了 isobject,还有的库引用了 isObject,每个包看起来很 DRY,但是合起来就 wet 得不行了,呵呵。
我一直以为 npm 里下载量较大的 package 是 React 这样不错的包。
今天我才知道我错了。
目前 React 每周下载量是 240 万次。
然而下面我要说的几个包的下载量全都大于 React !
is-odd,每周下载 300 万次
源代码如下:
'use strict';
var isNumber = require('is-number');
module.exports = function isOdd(i) {
if (!isNumber(i)) {
throw new TypeError('is-odd expects a number.');
}
if (Number(i) !== Math.floor(i)) {
throw new RangeError('is-odd expects an integer.');
}
return !!(~~i & 1);
};
你没有看错,五行核心代码,还依赖了一个 is-number 库。
这个 is-number 库更厉害,每周下载 1000 万次
源代码如下:
'use strict';
module.exports = function isNumber(num) {
var number = +num;
if ((number - number) !== 0) {
// Discard Infinity and NaN
return false;
}
if (number === num) {
return true;
}
if (typeof num === 'string') {
// String parsed, both a non-empty whitespace string and an empty string
// will have been coerced to 0\. If 0 trim the string and see if its empty.
if (number === 0 && num.trim() === '') {
return false;
}
return true;
}
return false;
};
后来我发现这两个库的作者是同一个人(该作者水平很高),这个人还写了另外几个库:
需要指出的是
这件事对我的启发:
我终于知道为什么 npm install 总是动不动就下载 300 Mb 的东西了,Node.js 社区强调的 DRY 文化使得 node_modules 臃肿不堪,因为有的库引用了 is-object,有的库引用了 isobject,还有的库引用了 isObject,每个包看起来很 DRY,但是合起来就 wet 得不行了,呵呵。
Node 社区跟我想得不太一样,说不上好也说不上坏,反正不是很适合我。
以下是扯淡。
我是看到 Medium 上的一篇《混乱又危险的 Node.js 生态》才知道这些的,这篇文章里的一个评论我很赞同:
如果你不能在十秒钟内写出一个判断奇数的函数,要么你是一个糟糕的打字员,要么你就不应该当程序员!
还有一些颇为搞笑的评论:
1
Dawnki 2018-04-19 01:33:17 +08:00 via iPhone 11
看到那个既不是奇数也不是偶数的那个库 我躲在被窝里笑出了猪声 hhhhhhhhhh
|
2
FrankFang128 OP @Dawnki 讽刺 JS 程序员写代码不带脑子哈哈,说实话我从写代码第一天就是用 n % 2 === 1 来判断奇数,到底是什么人才会想要去引用一个库……是因为不会 % 运算符吗……
|
3
GooMS 2018-04-19 01:42:11 +08:00 via Android
有找包的时间早写了,我这俩月上业务一些 nodejs 就连续碰到三次因为基础库的基础库的基础库更新不兼容故障,就是几行代码,结果自下而上崩塌了。我现在很喜欢用 docker 包装 go
|
4
GooMS 2018-04-19 01:45:24 +08:00 via Android
一个 4000 + star 依赖了一个 20 + star 的库,那个库粗制滥造也没有测试说改就改 也不发大版本
|
5
FrankFang128 OP @GooMS nodejs 找包确实很费时间,经常遇到名字类似功能类似的,大部分时候完全在浪费时间。
|
6
FrankFang128 OP @GooMS 听起来很符合 Node.js 社区的风格
|
7
billlee 2018-04-19 01:49:24 +08:00
is-primitive, 点进去之前我还以为是判断素数的
|
8
FrankFang128 OP @billlee 我觉得 JS 程序员平时用不到这么复杂的算法(误
|
9
Luckyray 2018-04-19 02:01:55 +08:00 via iPhone
哈哈哈哈哈说的好有道理
|
10
QK8wAUi0yXBY1pT7 2018-04-19 02:22:31 +08:00
人家活在无墙的世界,300M 不是问题
|
11
crysislinux 2018-04-19 06:50:44 +08:00 via Android
还真别笑,你写的和这些库跑的测试用例并不一样。所以说起来好像实现的是相同功能,但实际上并不一样
|
12
woodensail 2018-04-19 08:48:51 +08:00
DRY 又不是 node 特有的,事实上 DRY 理念的提出比 node.js 的历史还要长。
|
13
ghostheaven 2018-04-19 08:49:26 +08:00 via Android
好多都是 JS 语法本身的坑,比如判断是不是字符串,是不是函数这种最基本的,都没有简单的方法。再加上早期核心对象的方法缺失,虽然后来补上了,导致某些常用功能要做额外的判断方法是否存在,或者要做 polyfill,比如字符串的 trim 这种。还有现在 ES2015+更新的语法和标准函数对象的快速增加,不得不同时采用 polyfill 和 babel 这种语法转换工具,以兼容比较老的浏览器版本。
|
14
houbaron 2018-04-19 08:53:42 +08:00 via Android 17
我们弱类型语言就是这样的,只能靠隐式类型转换才能维持生活这样子的。
|
15
woodensail 2018-04-19 08:56:02 +08:00
顺便一提,你以为动不动就下载 300M 是 node 特有的问题?
事实上每个包管理工具都是这样的。pip,maven,npm 无一例外。这种现象的出现时由于依赖库太多或太重。另外,包括 npm 在内的所有包管理工具都是有本地仓库做缓存的。所以事实上日常使用中大部分情况都是走缓存,很少需要下载新包。 npm 真正存在的问题是所有依赖文件全部会复制一份到项目文件夹,项目启动时所有依赖资源打包在项目内。而不是其他工具一样,将包留在本地仓库中,解析依赖时从仓库进行加载。 |
16
murmur 2018-04-19 08:58:21 +08:00
这种库一般来说都是严格按照 ES6 或者 ES5 的规范实现的
为什么需要个库 因为 ES 规范就这么定义的 如果要把这些稍微超前一点的东西在 IE 上运行 你少写一行他不就不满足规范 |
18
ywgx 2018-04-19 09:03:03 +08:00
就是因为这点,才彻底看衰 node.js
|
19
linxl 2018-04-19 09:10:05 +08:00
想到上次看到一个 json 解码的 node 包。。 很费解
|
20
kerr92 2018-04-19 09:11:00 +08:00
哈哈,不知道大家怎么看待用到 isArray, isUndefined 必须得引入 lodash 的前端程序员
|
21
mooo 2018-04-19 09:18:45 +08:00
动不动下载 300M 和这个还真没关系。
|
22
viko16 2018-04-19 09:23:49 +08:00 via Android
面向 npm install 编程的我含泪点赞…
|
23
crist 2018-04-19 09:26:07 +08:00
最好语言 PHP 欢迎你!
|
24
misaka19000 2018-04-19 09:27:33 +08:00 2
|
25
zhouxuchen 2018-04-19 09:32:13 +08:00 1
每一次 npm install 都是奇妙的旅行……
|
26
webluoye 2018-04-19 09:33:49 +08:00
php 现在的包管理也是动不动依赖一堆
|
27
qiqico 2018-04-19 09:38:01 +08:00
基本同意楼主观点
不过也不是所有人都这样的,比如我就不喜欢用 lodash 这种库,现在用 babel 的情况下 |
28
janxin 2018-04-19 09:40:16 +08:00
一行代码都不写你都可以拉 300M 下来
|
29
LxRuzx 2018-04-19 09:40:17 +08:00
为啥这个页面是 黑的???
|
30
dany813 2018-04-19 10:10:37 +08:00 1
老哥 cnode 发一遍 这边发一遍 好闲啊
|
31
soulmine 2018-04-19 10:41:46 +08:00
你们 node 不都是写个 hello world 然后下了 1000+的包么
|
33
Wolfpancake 2018-04-19 11:36:10 +08:00 2
is-thirteen 了解一下
https://www.npmjs.com/package/is-thirteen |
34
Mitt 2018-04-19 11:56:12 +08:00 via iPhone
这是一个问题 但这不是一个大问题 它既不影响你开发也不影响你运行和部署 它只是让你看起来很糟糕
|
35
zachguo 2018-04-19 12:07:47 +08:00 via Android
- 跟 DRY 没有关系
- JS 打包和发布太容易了 - ES5 之前的历史遗留问题 - 这个问题不难解决 |
36
StickmY 2018-04-19 12:07:51 +08:00 via iPhone
@FrankFang128 这样这有很明显的问题,因为 js 的弱类型特征,需要做很多判断
|
37
lxy 2018-04-19 12:17:28 +08:00
一次同事突发奇想要打包( rar )项目的 .node_models,电脑是固态硬盘,结果我们出去吃饭半小时回来了还没打包完..
|
38
xiaojie668329 2018-04-19 12:22:52 +08:00 via iPhone
神烦那些什么都要引入一个包的人,为了一个方法引入整个 lodash。还有一些很简单的库,明明写一个也不用多少时间。他引入了,为了确保准确,还得去找这个包来看 api 作用。🙄
|
39
leetom 2018-04-19 12:23:20 +08:00
记得看到过一个一行代码的包,下载量也是惊人。关键是都在鼓吹 NPM 有多先进。不能理解,但还是得用。
|
40
rrfeng 2018-04-19 12:23:57 +08:00 via Android
就不说我们一个项目有 800M 了...(为了安全只能把 modules 也打包进去)
|
41
POPOEVER 2018-04-19 12:27:23 +08:00
@Wolfpancake 被 license 笑死😂
|
42
yushiro 2018-04-19 12:33:02 +08:00 via iPhone 1
人家库的源代码都写的很明白了,你自己写一句简单的奇偶判断,有考虑到源码里面的那些情况吗?如果没有,那就好好的学习别人的思路吧。
|
43
Yuiham 2018-04-19 13:29:01 +08:00 via Android
很多 npm 包的粒度控制得不好,并不是说 leftpad 和 rightpad 分开就 dry 吧
|
44
lujiajing1126 2018-04-19 13:36:24 +08:00
没什么问题啊,如果别人的包更健壮,为什么不用?
楼主怕是从 ES6 才开始学 JS 的吧 |
45
FrankFang128 OP @lujiajing1126 你会用么
|
46
FrankFang128 OP @yushiro 你会考虑用这个库么?
|
47
FrankFang128 OP @lujiajing1126 你会考虑用这个库么?
|
48
jzz7280 2018-04-19 13:54:14 +08:00
确实乱
|
50
chairuosen 2018-04-19 14:28:56 +08:00
|
51
learnshare 2018-04-19 14:34:04 +08:00
当你需要一个功能的时候,必然有一个 npm 包在那里
|
52
mooo 2018-04-19 14:43:35 +08:00
@FrankFang128
> 1.原来有这么多 JS 程序员不会判断奇数 is-odd 每周下载 300 万是因为[nanomatch]( https://www.npmjs.com/package/nanomatch) 中引用了, 引用的原因看这个(pul requests)[https://github.com/micromatch/nanomatch/pull/7] > 讽刺 JS 程序员写代码不带脑子哈哈.. 明显是编程风格问题, 楼主提高到 JS 程序员的角度不知道楼主提问题带不带脑子 |
54
myyou 2018-04-19 14:54:34 +08:00 1
这些东西应该整体做一个工具集,而不应该单独发布
|
55
Pastsong 2018-04-19 15:01:15 +08:00
工具集不符合社区推崇的是最小化 import,如果 is-odd 被项目里的 100 个包引用了,那最终产出的相关逻辑代码只有一份,但如果每个包自己实现了 is-odd,你在最后项目里就有 100 份相同代码
|
56
mooo 2018-04-19 15:17:07 +08:00
|
58
FrankFang128 OP @kerr92 lodash 提供的其他 API 很好用的。
|
59
ke1vin 2018-04-19 15:25:25 +08:00
@Wolfpancake 为什么那么多 star ????
|
60
FrankFang128 OP @mooo 看了,原因是他是模块化的粉丝,也就是「他喜欢这么做」。
|
61
FrankFang128 OP @mooo 不带脑子算是我留的喷点啦,吐槽而已~
|
62
mooo 2018-04-19 15:34:08 +08:00
@ke1vin 娱乐项目 这个星更多 https://github.com/kelseyhightower/nocode
|
63
EyreFree 2018-04-19 15:37:10 +08:00
围观,[吃瓜]
|
64
LeungJZ 2018-04-19 17:12:35 +08:00
换个地方,再一次坐等打脸?
|
65
LeungJZ 2018-04-19 17:12:40 +08:00 1
|
66
lihongjie0209 2018-04-19 17:17:11 +08:00
@woodensail #15 你确定 maven 中会有这种垃圾库并且还有人用??
|
67
lwbjing 2018-04-19 17:27:42 +08:00
驳《我不是很懂 Node.js 社区的 DRY 文化》
https://mp.weixin.qq.com/s/OQsXOeah0ENK7Y6anAbXgg @justjavac @FrankFang128 我只是转一下,大家别打我。。 |
68
yushiro 2018-04-19 17:27:46 +08:00 via iPhone
@FrankFang128 用不用这种总结前人经验的库,看你自己对自己的期望了。如果只是为了完成一份工作,那就自己写个简单的功能代码即可,万一出问题了,debug 解决呗。
如果是想成为一个优秀的开发者,这种库肯定要用啊,这是别人的经验,都已经帮你把坑都填了,非要自己再去踩坑? |
69
woodensail 2018-04-19 17:29:27 +08:00
@lihongjie0209 我只是针对 300M 这一点而已。其他的我不予置评,但是 300M 的问题在任何包管理工具上都有。
|
70
lihongjie0209 2018-04-19 17:35:36 +08:00 1
@lwbjing #67 这篇文章强调了一个函数的正确性和性能,但是却没有说明一个好的模块不是由一个函数组成的, 而是由一系列高级抽象组成的, 到最后只会导致越来越多的臃肿代码
|
71
lihongjie0209 2018-04-19 17:48:51 +08:00 1
@Pastsong #55 最小化是有一个阈值的, 以函数为最小单位发包必定会导致依赖管理异常复杂.
|
72
LadyChunsKite 2018-04-19 17:51:53 +08:00 2
转发:驳《我不是很懂 Node.js 社区的 DRY 文化》
https://segmentfault.com/a/1190000014480379?utm_source=index-hottest |
73
clino 2018-04-19 17:57:58 +08:00
@Wolfpancake #33 370 commits 103 contributors ... 大家好闲啊...
|
74
overflowHidden 2018-04-19 18:03:12 +08:00
@LadyChunsKite #72
“在回过头来看看 is-number 库,不仅仅有 100 多行的 test case,还有一个目录 benchmark。这里面的代码我没有数,但是光看文件数量就有 10 个以上。也就是说作者不仅仅保证了这个函数的运行结果没有问题,更保证了这个函数的性能。 我们为什么要使用这个库,因为作者为了他的 10 行代码,写了几百行的其它代码来保证质量。” 惊呆了。。。 |
75
clino 2018-04-19 18:18:48 +08:00
@LadyChunsKite #72
http://zhuanlan.zhihu.com/p/35870240 驳《驳《我不是很懂 Node.js 社区的 DRY 文化》》 https://zhuanlan.zhihu.com/p/35880323 请 Node.js 社区正面回答 |
76
quxiangxuanqxx 2018-04-19 18:35:42 +08:00 2
楼主说的挺好
就是那三句结论,全文最大的败笔呀,程序猿写结论的时候不应该开这种逻辑明显错误还迎战的玩笑 所以我的结论是 楼主文章没错,指出了 node 社区的问题,但是结论涉及引战 这对讨论问题没有任何帮助,你要是真想好好讨论问题,就别写这种槽点满满的结论 除非,你只是为了制造热度 |
77
easylee 2018-04-19 18:42:41 +08:00
这些算法都算不上的代码 实现都不会是怎么找到工作的?
|
78
mkeith 2018-04-19 18:49:27 +08:00 via iPhone
现在 nodejs 已经从服务端语言又变回浏览器端了
|
79
FrankFang128 OP @quxiangxuanqxx 250 多万 is-odd 的下载量得出这个结论我不觉得很过分,他们就是不会写判断奇数……
|
80
FrankFang128 OP @easylee 同疑惑
|
82
FrankFang128 OP @welkinzh 看起来是开玩笑的
|
83
MeteorCat 2018-04-19 20:45:42 +08:00 1
可能是缺少一个大头来做库收集和论证
就像 C++的的 stl 和 boost 库一样,每个轮子都需要先进 boost 论证完才能进入 stl 库 有权威人士为其使用代价来背书 而 node.js 则是过于强调个人,这个作用用了 XXX 库,"你看作者这么牛逼,应该采用他写的库"; 而且第二天另外一个作者也做了相同功能,"你看那个作者写的这么牛逼,这些库我们也得引用" 实际上通过权威来论证他们合理性和坑点之后,其他人看到之后也就会自然而然的规范自己使用方式 (当然很多开发都是喜欢自己造轮子的,比如很多著名的 C/C++都是自己搞自己的字符串库) |
84
mooo 2018-04-19 21:38:23 +08:00
@FrankFang128 没有 300M 吧 我这依赖都是 100 多 M, 感觉是来故意引战的。。。
|
85
hjdtl 2018-04-19 21:47:07 +08:00 3
我要指出一点,这个作者一边到处贬低 js 或者前端,一边搞培训教前端。他说的不无道理,只是一些言论很夸张,想搞个大新闻,从中获利(?
|
86
mooo 2018-04-19 22:23:08 +08:00 1
@FrankFang128
1。250 多万 is-odd 的下载量得出这个结论我不觉得很过分,他们就是不会写判断奇数…… s-odd 300W 的下载量来自 nanomatch, 很明显 nanomatch 的人不会判断奇偶性(虽然是一个人写的。。。 2. 动不动就下载 300 Mb 的东西, 是的,引用 4000 多字节的 is-odd 会让我们的依赖越来越大,所以我们要多用 24K 的 lodash. 3. 我终于知道为什么 npm install 总是动不动就下载 300 Mb 的东西了,Node.js 社区强调的 DRY 文化使得 node_modules 臃肿不堪,因为有的库引用了 is-object,有的库引用了 isobject,还有的库引用了 isObject, 麻烦楼主给个分析, 你 300 Mb 的依赖到底是来自各种各样的 isobject,is-number 这种仓库还是来自别的地方 4. 成堆的 one-line lib,用的人还贼多, 142 引用 的 is-number 用的人贼多 65955 引用 的 lodash 没人用 你们 node 社区都爱用 is-number 这种 one-line lib 5.关键是大部分库名称类似、质量还不高 module.exports = function isOdd(i) { if (!isNumber(i)) { throw new TypeError('is-odd expects a number.'); } if (Number(i) !== Math.floor(i)) { throw new RangeError('is-odd expects an integer.'); } return !!(~~i & 1); }; 这种质量太差了, 明显不如 %2 质量高 6. 每个库引用了不同的 one-line lib,导致代码非常重复,而且使用者还没法分析重复在哪 麻烦楼主贴一下, 到底这些 one-line lib 怎么重复的,让你的依赖到了 300m |
87
roychan 2018-04-19 22:29:07 +08:00
十行代码,形式化验证都能保证正确性了,居然写了几百行的测试?(逃
|
88
msg7086 2018-04-19 22:53:17 +08:00
判断奇偶性的函数,没看过这个包的源代码,你确定你写得出来?
反正我是写不出来的,最多只写得出一个 % 2 === 1 然后回头被其他人骂到死。 |
90
zhuangzhuang1988 2018-04-19 23:03:23 +08:00
|
91
Kongtou 2018-04-19 23:31:25 +08:00 via Android
前端已凉,同学们!
|
92
stzz 2018-04-19 23:52:35 +08:00 via Android
不会写奇偶的菜鸡路过🙄
!!(~~i & 1),前面不是判断过整数么,为何还要两次取反… |
93
lolizeppelin 2018-04-20 00:24:32 +08:00 via Android 3
js 为了在浏览器里怎么也不崩溃 代码依赖都没下完都能跑 所以才那么乱的
从骨子里就不适合严格的编程 那个奇数计算里的各种判断就是 tm 多余的 哪个动态语言每次计算有要先判断类型的 要判断也是数据入口做 独立出 type 验证方法 而不是写在计算里 这种库就是在浪费性能 |
94
mrcode 2018-04-20 00:25:15 +08:00
我觉得你说的这些不算 npm 的痛点,npm 的痛点在于项目之间的 package 不能共享
|
95
FrankFang128 OP |
97
nikolai 2018-04-20 01:17:36 +08:00 1
|
98
FrankFang128 OP @nikolai 明明是 + 号的坑,非要用 is-number 来弥补。 不要用 +[] 这样的代码就好了,用 parseInt
|
99
xqdoo00o 2018-04-20 11:51:28 +08:00
这难道 不是弱类型语言 隐式转换的锅吗? 前端 TS,后端 ts-node 不就行了吗
|
100
sammo 2018-04-20 11:54:58 +08:00 via iPhone 1
js 的用法好像机器语言阿 ...
其他人为了解决机器语言不好写的问题,发明了高级语言 M$ 为了解决机器语言不好写的问题 发明了 高级语言 TypeScript “另一些人” (也就是 Node.js 社区的人) 为了解决机器语言不好写的问题,发明了 “高级机器语言” https://zh.m.wikipedia.org/wiki/TypeScript 不同方向走向了不同的地方 ... |