我不是很懂 Node.js 社区的 DRY 文化

2018-04-19 01:12:14 +08:00
 FrankFang128

原文在知乎,欢迎交(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;
};

后来我发现这两个库的作者是同一个人(该作者水平很高),这个人还写了另外几个库:

需要指出的是

  1. webpack、babel 等库都有「间接地」依赖上面的一些包。
  2. 这些包的 markdown 代码远远多于 JS 代码,可能它们的 markdown 更值得我们学习

这件事对我的启发:

  1. 原来有这么多 JS 程序员不会判断奇数
  2. 只要 markdown 写得漂亮,就能迷倒 JS 程序员
  3. 1 + '1' 的问题一直在困扰 JS 程序员,我要不要写一个 add() 库解决这个问题呢

我终于知道为什么 npm install 总是动不动就下载 300 Mb 的东西了,Node.js 社区强调的 DRY 文化使得 node_modules 臃肿不堪,因为有的库引用了 is-object,有的库引用了 isobject,还有的库引用了 isObject,每个包看起来很 DRY,但是合起来就 wet 得不行了,呵呵。

Node 社区跟我想得不太一样,说不上好也说不上坏,反正不是很适合我。


以下是扯淡。

我是看到 Medium 上的一篇《混乱又危险的 Node.js 生态》才知道这些的,这篇文章里的一个评论我很赞同:

如果你不能在十秒钟内写出一个判断奇数的函数,要么你是一个糟糕的打字员,要么你就不应该当程序员!

还有一些颇为搞笑的评论:

18430 次点击
所在节点    Node.js
105 条回复
welkinzh
2018-04-19 19:53:14 +08:00
@hxd 你这种人就是杠精吧
FrankFang128
2018-04-19 20:03:54 +08:00
@welkinzh 看起来是开玩笑的
MeteorCat
2018-04-19 20:45:42 +08:00
可能是缺少一个大头来做库收集和论证
就像 C++的的 stl 和 boost 库一样,每个轮子都需要先进 boost 论证完才能进入 stl 库
有权威人士为其使用代价来背书
而 node.js 则是过于强调个人,这个作用用了 XXX 库,"你看作者这么牛逼,应该采用他写的库";
而且第二天另外一个作者也做了相同功能,"你看那个作者写的这么牛逼,这些库我们也得引用"
实际上通过权威来论证他们合理性和坑点之后,其他人看到之后也就会自然而然的规范自己使用方式
(当然很多开发都是喜欢自己造轮子的,比如很多著名的 C/C++都是自己搞自己的字符串库)
mooo
2018-04-19 21:38:23 +08:00
@FrankFang128 没有 300M 吧 我这依赖都是 100 多 M, 感觉是来故意引战的。。。
hjdtl
2018-04-19 21:47:07 +08:00
我要指出一点,这个作者一边到处贬低 js 或者前端,一边搞培训教前端。他说的不无道理,只是一些言论很夸张,想搞个大新闻,从中获利(?
mooo
2018-04-19 22:23:08 +08:00
@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
roychan
2018-04-19 22:29:07 +08:00
十行代码,形式化验证都能保证正确性了,居然写了几百行的测试?(逃
msg7086
2018-04-19 22:53:17 +08:00
判断奇偶性的函数,没看过这个包的源代码,你确定你写得出来?
反正我是写不出来的,最多只写得出一个 % 2 === 1 然后回头被其他人骂到死。
fomenyesu
2018-04-19 23:00:20 +08:00
@LeungJZ goooood!
zhuangzhuang1988
2018-04-19 23:03:23 +08:00
Kongtou
2018-04-19 23:31:25 +08:00
前端已凉,同学们!
stzz
2018-04-19 23:52:35 +08:00
不会写奇偶的菜鸡路过🙄
!!(~~i & 1),前面不是判断过整数么,为何还要两次取反…
lolizeppelin
2018-04-20 00:24:32 +08:00
js 为了在浏览器里怎么也不崩溃 代码依赖都没下完都能跑 所以才那么乱的

从骨子里就不适合严格的编程

那个奇数计算里的各种判断就是 tm 多余的
哪个动态语言每次计算有要先判断类型的
要判断也是数据入口做 独立出 type 验证方法 而不是写在计算里
这种库就是在浪费性能
mrcode
2018-04-20 00:25:15 +08:00
我觉得你说的这些不算 npm 的痛点,npm 的痛点在于项目之间的 package 不能共享
FrankFang128
2018-04-20 00:30:51 +08:00
@mrcode 可以用 @scope/p1 这种形式共享,你说的是这种么
nikolai
2018-04-20 01:05:16 +08:00
@stzz 这样总能返回一个 boolean。。。

总的来说还是弱类的坑
nikolai
2018-04-20 01:17:36 +08:00
看完了 is-number 解释为什么要建立这个库:

https://gist.github.com/jonschlinkert/e30c70c713da325d0e81

我决定以后开始用它了
FrankFang128
2018-04-20 01:24:34 +08:00
@nikolai 明明是 + 号的坑,非要用 is-number 来弥补。 不要用 +[] 这样的代码就好了,用 parseInt
xqdoo00o
2018-04-20 11:51:28 +08:00
这难道 不是弱类型语言 隐式转换的锅吗? 前端 TS,后端 ts-node 不就行了吗
sammo
2018-04-20 11:54:58 +08:00
js 的用法好像机器语言阿 ...
其他人为了解决机器语言不好写的问题,发明了高级语言
M$ 为了解决机器语言不好写的问题 发明了 高级语言 TypeScript
“另一些人” (也就是 Node.js 社区的人) 为了解决机器语言不好写的问题,发明了 “高级机器语言”

https://zh.m.wikipedia.org/wiki/TypeScript

不同方向走向了不同的地方 ...

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/448002

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX