很多人不理解一行式模块 (one-line module) 的好处,你会怎么向那些批评这种现象的人解释这个东西的好处?
这种小但专注于某个功能的模块有更好的可读性,并且在构建大型应用的时候能方便推导分析。
人们很容易被代码的行数吸引住眼球,然而行数对代码来说无关紧要。一个模块的关键不在于它是由一行代码还是几百行代码组成,而是在于它的复杂程度。把模块想象成乐高积木试试,你不会关心这些积木是怎么制造的,你只想知道怎么用这些积木来搭出你想象中的城堡。通过小的模块你不用把各个部分都弄懂就能轻松地构建大型的系统,从短期来看,人的记忆力都是有限的。除此之外,模块化可以方便别人重复使用这个模块,而一旦这个模块有改进或者修复了一些 bug,所有使用这个模块的用户都能得到更新。
假设所有的 PC 制造商都自己生产 CPU 的话,其中大多数都会做得很糟。那样的话计算机会变的更昂贵,在其它方面的创新会变得更缓慢。当只有 Intel, ARM 专注于此情况就不一样了。
模块化的实现同样得益于 npm 的工作原理,你不需要管你的依赖有哪些依赖。
几年前,在 Node.js 和 npm 诞生还没有诞生的时候,我有一个很大的代码片段数据库,当我需要的时候我就从里面复制粘贴。现在情况不一样了,npm 变成了我管理代码的地方。为什么在可以使用 require 的时候选择复制粘贴呢,现在你要修改这些代码片段的话就相当于更新一个模块,而不是在所有使用这些代码片段的地方手动修改。
比如,我有个叫 negative-zero 的模块,它就是用来判断一个数是不是 -0 的。这种情况并不常见,但也可能发生。那当它发生的时候你怎么判断是不是 -0 呢?很简单,x === 0 && 1 / x === -Infinity,你不会真的想知道这是什么原理吧,反正我不想知道,我只想简单地 require 这个模块然后把精力放在更重要的事上。
再举个栗子,chalk 是 npm 上最流行的模块之一,然而你可能不知道它其实是一系列模块的集合,它依赖了「检测终端是否支持颜色」和「获取 ANSI 转义码」等模块,你当然可以把这些模块的代码复制粘贴进 chalk 模块里,但是这意味着如果有其它人想要实现一个在终端显示颜色的模块就要重复造轮子了。通过这些模块,可以让其他人也受益,并且间接带动了社区对这些模块的贡献,提高模块的质量。
最后还有个栗子,我有个用来获取系统用户目录的模块叫 user-home,你可能会说这不是一句 process.platform === 'win32' ? process.env.USERPROFILE : process.env.HOME 就能搞定的吗。是的,大多数情况是这样。但是首先,为什么要人每个人都知道如何获取用户目录呢,为什么不用乐高积木的方式?而且你可能注意到了这个判断没有考虑所有情况。在 Windows 上还有一些特殊情况需要考虑。
你会自己生产自己穿的鞋子吗?不会,你直接在商店里买鞋子。大多数人不关心鞋子的制作原理而只在乎是否合脚。
我想让编程变得更容易,让构建持久可用的系统更容易。但是我的观点并不意味着重复造轮子和重复犯前人犯过的错。
---
原文: Small Modules: Tales from a Serial Module Author
Issue 地址: One-line node modules · Issue #10 · sindresorhus/ama · GitHub