转自:http://www.techug.com/npm-left-pad-have-we-forgotten-how-to-program

开发者朋友们,我们该谈一谈这个问题了。你们应该知道本周的 left-pad 事件: React 、 Babel 和许多流行的npm模块都受到波及,无法正常运行。

这一事件的起因十分令人诧异。

这些受到影响的模块都引入了一个叫做 left-pad 的模块。截至此时, left-pad 这个模块在Github上也只有寥寥十一个star。在整个模块中,作者只用十一行代码实现了一个简单的字符串处理函数。

以下就是这十一行代码:

module.exports = leftpad;
function leftpad (str, len, ch) {
str = String(str);
var i = -1;
if (!ch && ch !== 0) ch = ' ';
len = len - str.length;
while (++i < len) {
str = ch + str;
}
return str;
}

让我感到有意思的是,社区中许多的模块都选择引入这个十一行的模块,而不是花上两分钟的时间自己去实现这个简单的字符串填充功能。

事件发生之后,我开始仔细研究npm生态系统。以下是一些有趣的发现:

  • npm上有个叫做 isArray 的模块。今天一天之内,它就被下载了八十八万份;光是今年二月,它就被下载了接近一千八百万份。模块本身只有一行代码: return toString.call(arr) == '[object Array]'
  • 还有一个模块叫做 is-positive-integer 。这个只有四行代码的小模块,竟然还要依赖另外三个模块。事件之后作者把那三个依赖去掉了;但我还是弄不明白作者为什么不早这样做。
  • 装一次 babel 模块就要引入四万一千多个文件。
  • 随便一个以 npm/jspm 为核心的项目模板就要引入超过两万八千个文件。

以上这些事实让我觉得,

我们是不是早已忘记该如何好好地编程?

这种过度依赖其他npm模块的做法是不是解决问题的正确方式呢?现在,一个空白项目模板一装好就要引入两万八千多个文件、依赖成百上千个其他的npm模块。这太疯狂了、而且过度复杂。

我觉得npm生态系统中,开发者有一种不良的、对微型模块的热衷。相对于自己实现一些小函数,开发者们更愿意去依赖其他人写好的模块。我甚至觉得npm生态系统中的开发者只想尽可能地少写代码,大量引入别人写的模块,拼拼凑凑、串起来交差。

一个函数并不能被称为模块

函数本身太小了,不应该被做成一个模块并被别的项目引入。一个函数本身并没有什么整体意义,只是随便一小段代码而已。假如我们现在要求一个角度的余弦值。 我们肯定不会专门为求余弦值引入一个「cosine」模块。如果要算cosine的值,我们更想要一个功能完整、带有其他三角函数的「三角」模块。 .NET 与其他许多框架都选择提供这样一个功能统一又完整的「核心」模块。大部分语言的设计者都会很仔细地编写语言自带的「核心模块」:这部分基本上是很安全没有bug的。

第三方依赖带来的问题

首先,没有人能肯定别人写的依赖是不是完全正确的。也许它们都不能正常工作。退一步说,就算这些东西都写对了,它们的实现就是最高效的吗?如果你选择不用依赖自己去写,你至少可以自己fix你能看到的问题、还能去尝试把它写得更高效。这不只是依赖写得对不对的问题。

其次,就算这些模块的逻辑正确也十分高效,我还是感到十分吃惊:开发者们竟然懒得自己写这些一两行就能实现的功能,选择去依赖别人写的模块;这些功能明明闭着眼睛都能写对。在我看来,如果你连上面提到的 left-pad 、 is-positive-integer 或者 isArray 都不能五分钟内边搜索边调试着写完,你其实根本就不会写代码。哎,这些小功能真应该被当作面试题:写不出来的话,只能说候选人不会写代码。

最后,我觉得把这些API串到一起、拿别人的模块七拼八凑的做法根本就不叫编程。这只不过是某种七拼八凑、过度设计、把事情复杂化的行为。

更糟糕的是,如果你的代码或者你引入的代码出了问题或者有些bug,你又不懂得如何真正「编程」,你就无法解决问题。

我们应该尽可能减少依赖的模块

每个你依赖的模块都会引入其他的模块。这些依赖,顾名思义,是一些你不得不需要的东西。你越多地依赖别人的模块,你的项目就会有越多崩溃的隐患。同时,你的项目出错的机率更大:你根本就不知道这些第三方模块的作者是否靠谱。

只有在遇到非常复杂,自己解决起来需要花很多时间、金钱的问题时才应该考虑依赖其他模块。比如,当需要一个数据库中间件(ORM)或者一个做客户 端缓存的组件时,你应该选择引入一个依赖而不是自己去写,因为这些活儿太耗时、太复杂了。引入这些组件可以省下很多时间;相比之下,它们出问题的风险也变 得可以接受。

但是除此之外,就算是因为对「编程」这件事的执念,你都应该去写这些基本的小函数。为了一个一两行就能实现的功能多引入一个依赖是一件很蠢的事情。你不信么?尽管想想 left-pad 事件之后React 团队的感受。现在,他们肯定宁愿自己去实现那个十一行的字符串填充函数。

NPM 与 left-pad 事件:我们是不是早已忘记该如何好好地编程?的更多相关文章

  1. Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G

    code&monkey   Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...

  2. 13 个 NPM 快速开发技巧

    摘要: 玩转npm. 作者:前端小智 原文:13 个 npm 快速开发技巧 Fundebug经授权转载,版权归原作者所有. 为了保证的可读性,本文采用意译而非直译. 每天,数以百万计的开发人员使用 n ...

  3. react 中 EventEmitter 事件总线机制

    此机制可用于 react 中兄弟组件中的通信 npm install events -S 事件总线: // eventBus.js import {EventEmitter} from 'events ...

  4. 用block做事件回调来简化代码,提高开发效率

       我们在自定义view的时候,通常要考虑view的封装复用,所以如何把view的事件回调给Controller就是个需要好好考虑的问题, 一般来说,可选的方式主要有target-action和de ...

  5. Release编译模式下,事件是否会引起内存泄漏问题初步研究

    题记:不常发生的事件内存泄漏现象 想必有些朋友也常常使用事件,但是很少解除事件挂钩,程序也没有听说过内存泄漏之类的问题.幸运的是,在某些情况下,的确不会出问题,很多年前做的项目就跑得好好的,包括我也是 ...

  6. C#编程之委托与事件四(二)【转】

    C#编程之委托与事件(二)       我在上一篇文章(C#编程之委托与事件(一) )中通过示例结合的方法介绍了委托,在本文中,我同样以代码示例的方式来介绍C#里的事件机制. 二.事件   1.了解概 ...

  7. node.js的作用、回调、同步异步代码、事件循环

    http://www.nodeclass.com/articles/39274 一.node.js的作用 I/O的意义,(I/O是输入/输出的简写,如:键盘敲入文本,输入,屏幕上看到文本显示输出.鼠标 ...

  8. [DataTable]控件排序事件中用DataView及DataTable排序

    控件排序事件中用DataView及DataTable排序 文章分类:.net编程 在做ASP.NET页面开发时,经常要用到dataset(或者DataTable),绑定到DataGrid或GridVi ...

  9. 基于raw os 的事件触发系统

    Raw os的事件触发系统有以下特点: 1 基于UML的状态机理念设计,实现了有限状态机(fsm)以及层次状态机(HSM). 2 实现了活动对象(ACTIVE OBJECT)的特性,一个活动对象包含了 ...

随机推荐

  1. Spec模板

    Spec模板      一.概述   1.项目背景    图书馆在正常运营中面对大量书籍.读者信息以及两者间相互联系产生的借书信息.还书信息.现有的人工记录方法既效率低又错误过多,大大影响了图书馆   ...

  2. 开启Github之旅

    在那个远古时代,我以为可以用GoogleCode干点事,结果啥也没干好.如今,Github已经成为了业界标杆,就连Google.微软.Facebook的开源项目都往Github搬.Github作为全球 ...

  3. VR快速发展下,从业者如何把握机会?

      美国科技博客VentureBeat周末刊登赛斯·沙赫纳(Seth Schachner)的文章,分析了在虚拟现实快速发展的情况下,业内所面临的机会,以及如何把握这些机会.   沙赫纳是资深的数字战略 ...

  4. GPU---并行计算利器

    转载请引用:GPU---并行计算利器 源于阿里巴巴CCO<猿来如此>分享 1 GPU是什么 如图1所示,这台PC机与普通PC机不同的是这里插了7张显卡,左下角是显卡,在中间的就是GPU芯片 ...

  5. javascript 函数详解2 -- arguments

    今天我们接着上篇文章来继续javascript函数这个主题.今天要讲的是函数对像中一个很重要的属性--arguments. 相关阅读: javascript 函数详解1 -- 概述 javascrip ...

  6. PowerDesigner建表

    SQL: --建表 --管理人员表 admin --drop table WPADMIN cascade constraints; /*================================ ...

  7. JAVA实现多线程入门

    package com.thread;/** * 1:程序员可以在程序中执行多个线程,每一个线程完成一个功能,并于其他线程并发执行,这种 * 机制被称为多线程 * 2:实现线程的两种方法是,分别是继承 ...

  8. 使用Maven编译项目遇到——“maven编码gbk的不可映射字符”解决办法 ——转载

    一.问题描述 今天在MyEclipse中使用Maven编译项目源代码时,结果如下了如下的错误

  9. 在主方法中定义一个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。

    //在主方法中定义一个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’:输出这个数组中的所有元素. char [][]y=new char [10][10 ...

  10. C# winform的WebBrowser非常规编程(强烈推荐)

    本文章被今日头条推荐 1.在WebBrowser中实现抓取301和302协议 在WebBrowser中抓取301和302协议目前官方提供的组件远远不够,需要借助HttpMonitor.dll.这个组件 ...