你可能误解了开源,让我们重新认识它!

发表时间: 2019-01-16 14:10

“开源很像是公开演讲,许多人不认为他们的东西有价值,这种想法完全错了——每个人都有人类知识的一小部分,但没有任何人有能力掌握所有知识。所以,必然有一些人需要你的东西。”开源的原始意义,简而言之,不过如是。

如果你曾了解过 Slick Carousel、Webpack Dashboard、Spectacle、Cash 等开源库,应该就对 Formidable 开源总监 Ken Wheeler 不陌生,他在本文中分享了自己在开源方面的经验。

以下为译文:

作者 | Ken Wheeler

译者 | 弯月

责编 | 仲培艺

出品 | CSDN(ID:CSDNNews)

在正式介绍这些经验之前,我想先说明一下为什么要开源,以及在这一点上我的一点个人体会。

为什么应该写开源代码

我有不计其数的理由可以说明开源对你个人和你的职业生涯都大有裨益:

  • 开源对你的个人品牌非常有利。如果你有非常受欢迎的项目,那么人们就会熟悉你和你的作品。
  • 开源对你的公司品牌非常有利。提供并维护一些开源项目可以增加公司品牌的知名度。让员工花一些时间在开源上并让他们分享他们的点子,能让你的公司成为最好的工作场所。
  • 作为开发人员你可以得到成长!你个人项目的脚本不必在 /Users/Me/devshit 等目录下蒙尘长蜘蛛网。别人会关注你的项目,所以你有动力去不断改进它们。
  • 你能够回馈社区。就像 John-David Dalton 写的 lodash 为你的项目节省了不少时间一样,你也可以通过自己的代码为他人提升效率。你可以成为社区的一部分,大家通力合作并分享,一起节省时间。
  • 满满的成就感。虽然只是个人看法,但是每当别人感谢你的项目,或者告诉你你的项目节省了他的很多时间时,那种感觉非常美妙。
  • 开源也许不会为你带来一份工作,因为绝大多数公司并不会根据 GitHub 上的 Star 数招聘,但开源肯定会对你的面试有积极影响。

我的开源经验

我可能是有史以来最差劲的开源维护者了——好吧,也许不是最差的,但每次我做得都不够好。

有好几次我都没能很好地管理开源项目,我常常希望自己没有搞过这么多项目。

但是我能从每个项目的失败中学到很多东西,从而促使自己以后做得更好。这一点我稍后再说。当然在这方面我已经越做越好了,不过我还是希望读者能从我的失败中得到教训,避免走弯路。

下面我简单介绍一下我的经验,因为与正常的开源经验相比,我的经验相对“非主流”一些——我的整个职业生涯中给别人的项目做的贡献大概不超过 20 次,我只不过是写了一些代码然后推送了上去。所以我觉得应该介绍一下每个项目的背景。

我的第一个开源项目大概是我最成功的项目。当时我在某个软件公司工作,为纽约的一个大型时尚品牌做一个电商网站,作为团队中的高级开发,我需要做不少难度很高的 JS 开发。想念那段使用 jQuery 的日子……

时尚品牌的电商到处都是跑马灯式的图片,他们还喜欢使用各种复杂又宏大的设计。我发现,现有的跑马灯或幻灯片的库都不够灵活,无法支持他们给我的设计,所以我只好从头开始用 CoffeeScript 编写自己的“跑马灯”。最后终于实现了,但是显然同事们并没有因此给我好评。

但是我看到了明确的需求。人们需要一个跑马灯插件,它要足够灵活,能支持任何设计,又易于使用、便于修改。所以我就自己写了个插件。后来我觉得既然这个插件很有用,为什么不贡献出来节省所有人的时间呢?于是我就把它开源了……

结果发现,我的确节省了很多人的很多时间,人们都很喜欢它。发布后的最初几个月里,该插件的受欢迎度一飞冲天。当时我刚刚接触开源,看到有人使用我的代码,自是激动万分,经常通宵修改 bug、发布新版本,想尽办法确保没人能和我的代码竞争。

简而言之(毕竟这篇文章是忠告,不是我的个人简史),最后的结果就是我不再关心那个项目。原因有几个:首先,我换了份工作,所以不再需要跑马灯,不再需要解决这类问题了。另一个原因是 React 出现后,我第一时间开始使用,所以对 jQuery 也兴趣不再。

但最大的原因是我身心俱疲——我在那个项目上花费了太多精力,我仔细阅读每一篇评论,人们似乎都很有主见,他们指责我不应该那样使用跑马灯(甚至我正常工作中的项目都未能幸免,而我只不过是依照别人的设计干活),我还因此发福,连我老婆都因此很有意见。

在那以后,我在多个不同领域做了几个流行的库,每个都是为了解决不同的问题。我最害怕的一点是我无法再写出任何流行的库,我的辉煌时刻已然成为过去。时至今日我都很抗拒这件事,一直以来我都在做傻事,但我一直对我在那个跑马灯项目上的管理不善而耿耿于怀。

所以,下面是我对于开源的一些忠告,希望你能利用好并建立成功的项目,不要在开源上做傻事。

万事开头难

开源很像是公开演讲,许多人不认为他们的东西有价值。这种想法完全错了。“冒名顶替症候群”这个词说得太对了。每个人都有人类知识的一小部分,但没有任何人有能力掌握所有知识。所以,必然有一些人需要你的东西。

我的优点有二,一是脸皮厚,二是迷之自信,所以我敢发布代码,但我发现很多人觉得这一步很难。

对此,我的建议是:

放手去做!别让梦想变成梦。

最坏还能怎样?别人会议论?坦白说,就算是你写出 GitHub 上最完美、最有用、最惊艳的代码,那又怎样?一些傻x还是会骂你。这是不可避免的。最坏也不过是你学到了新东西。如果他们说,“这玩意儿太慢了。”那么你该怎么办?是说“我写不了代码,我放弃”,还是说“谢谢你的意见,我改好了,现在性能好多了”?显然你应该选择后者。

那么,你该构建什么呢?这个问题价值一百万!

我这么看:

  • 你遇到了一个问题
  • 你想到了该问题的解决方案
  • 你把这个解决方案打包得很好,别人也想用你的方案解决他们的问题

所以,我们来说说怎么才能打包好……

API 设计

好了,现在你有了想法——你遇到了一个问题,并解决了这个问题——但你想让别人也用你的方案,对吧?要想实现这一点,我这里有几条建议。

首先,也是最重要的一点,去找找竞争者和现有的方案。如果别人的库和你的功能一样,那么你就需要做一些有区分度的东西。比如,假设你想做另一个 lodash。首先祝你好运,但除此之外,如果你想从 lodash 那里分一杯羹,那么就得有自己的特长。你得更小,或者更快,或者提供更好的 API。看到问题所在了吧?

说起 API 设计,必须要考虑平衡性。你可以写一个不用任何配置拿来就能用的库,但别人就会抱怨他们想自己定制。你也可以写出非常灵活的可以配置的库,但那样你就会像 Tobias Koppers 或者 Sean T. Larkin 那样被人抱怨工具太难配置(不好意思 Sean,说的就是 v4)。

你要找到拿来就用和可配置之间的完美平衡。在此之上,还要保持代码整洁、明确和可配置。命名要直观,不要用那些自嗨的函数式编程,如果需要 hack 就一定要在注释里写明原因。

现如今,我在写出理想的 API 的 mock 之前不会编写一行代码。虽然 mock 的 API 会在实现过程中会不断变化,但它是代码应该努力的目标。只有你喜欢用的 API 才是正确的 API。

做好发布的准备

现在你解决了问题,也包装好了,到了该发布的时候了。但如果你希望别人使用你的代码的话,在发布之前还有一些工作要做。

写文档

这不是开玩笑,你必须写出最优秀的文档。不要用那种优越感满满的“只需”、“很简单就可以”等口气。文档开头要有目录链接,要有“快速入门”一节,极其详细地为第一次使用的人解释怎样开始使用。API 中的每个细节都要写到文档中。

如果你有个方法,就要写出方法应有的参数、类型和返回值。要写明方法的功能,还要给一个使用的例子,让别人很容易地使用你的库。

你还应该写明怎样做贡献。你应当在文档里写出怎样运行所有的构建步骤。如果需要引用另一个库或某个概念,就要给出链接。如果要引用任何可以链接的东西,也要给出链接。

完整的文档会为你打开新世界的大门,给你完全不同的开局。

写测试

在这点上一定要听我的:你必须测试你的代码,且测试覆盖率要达到合理的百分比。原因如下:

  • 测试能证明你的库是健康的
  • 测试能让你安心地合并 PR
  • 测试能让你离开项目一段时间后自信地回来继续为之工作

有一次我发布一个库时没有写测试,Paul Irish 就评论说,“要是有一些测试就好了。”我很自然地回答:“竟然是你。”然后乖乖地去写了测试。结果写测试的过程中就发现了大约 15 个bug!多亏了 Paul!

不论做任何事情,都要写测试。而且要写好。它可以为我节省很多时间,避免很多噩梦。

使用类型

测试抓不住的 bug 就要靠类型。现在,如果你的 JS 不使用类型,就相当于开车不系安全带。而且,随着越来越多的人使用 TS 或 Flow,人们都开始期待代码里自带类型。要么编写库时自带类型,导出并提供类型。要么就等别人用第三方的形式给你写类型,这种类型一般都是过时的,很可能还是错的。自己选择吧。

代码库的基本要求

  • README.md
  • CONTRIBUTING.md
  • LICENSE.txt
  • 正确的 package.json

关于 README 就不必多说了。永远别忘了加上 LICENSE.txt,否则别人就不会使用你的代码,用 MIT 就好。不要为了假装可爱就写一些乱七八糟的授权,只要用 MIT 就好,不要问我为什么。

CONTRIBUTING.md 里不仅可以写出怎样参与项目,还可以添加或链接行为准则(code of conduct)。一定要加行为准则,不管你是否同意里面的理念。相信我。有了行为准则,一些人才会愿意贡献并参与,而且如果以后遇到麻烦,可以指着行为准则来对付那些讨厌的人。

其他加分项

现在你写了完美的文档、优美的 API,所有必须的东西都完成了,一切都准备就绪就只差发布了,不过我还有一些建议:

添加一些徽标。没什么能比徽标更能表现你代码的正确性了。徽标太多看上去会招人厌,但一些有用的徽标是正确性的标志,它表明你在乎这个项目。

徽标你可以选用 npm 版本、测试状态、覆盖率等等。

而且,Markdown 支持纯 HTML,所以可以让代码库的门面变得更漂亮。居中、加一些引用,装点一下门面吧。

如果真想做到最好,可以加一个贡献者列表,就像这个一样:
https://github.com/kentcdodds/all-contributors

感恩每个为项目做出贡献的人这一点很重要。在这里感谢 Kent C. Dodds!

发布和宣传

现在一切都搞定了,该发布了。怎样才能让别人下载并使用你的代码呢?

我的建议非常具体。一定要在美东时间周一中午 12 点发布。这个时间在欧洲是工作日的结束,在纽约是午饭时间,在旧金山是大清早人们还没开始工作之前,你的大部分受众都在玩手机上网呢。(编者注:时间这一点依据具体受众群体而定,不拘泥,供参考)

至于怎样发布,我觉得你应该首先在社交平台(包括 Twitter) 上进行——打出最漂亮的广告词。

“厌倦了用键盘写 CSS 吗?你现在可以用 XBox 手柄写了!”

“栈跟踪给你 dump 了?要是能用 VR 来浏览栈跟踪有多好!”

诸如此类,还要加上图片,最好是视频。让人们一眼就能看明白你的代码是干什么的,为什么要用,还要加上链接。人们阅读的大概过程如下:

  • 浏览社交平台
  • 看到了你发布的内容
  • 我去,这个能干啥?
  • 点链接
  • 看到代码库:哇哦真酷,看着不错咧
  • 翻到入门指南
  • 复制粘贴到命令行,开始使用
  • 点击 Star 按钮

具体情况根据账号粉丝数量以及他们对于技术的态度,可能每个人都有所不同,但一般来说这种方式都有很好的效果。除此之外,其他宣传渠道还有 HackerNews 和 Reddit 等。

此外,如果你的想法很好,那么可以在发布的同时写一篇博客,特别是要以公司的名义发布,这样就可以通过更多的细节来对其加以介绍。

勇敢、自信,不要怕别人的批评。

维护

我很怕讨论这一部分,因为这是我最不擅长的。但我还是很愿意介绍一下我经历过的所有能想象到的失败,希望你能了解其中的大致情况。

你的库发布之后,一般会有两种结果:

1. 无人问津

这无所谓,对于我来说这种情况太常见了,回去继续干就好了。有时候一个东西不火,并不意味着你的想法不好,只是时机不对。重要的是你做了,而且做对了。那么下次再做时,你就可以做得更好,更容易成功。安慰一下自己,至少你已经发布了!

2. 火了

这才是真正可怕的时刻——人们喜欢你的东西,Twitter 上到处都在说,你不断改 bug、回答问题、回击反对者。这里我有几个建议:

首先,如果有人表示愿意为你的库贡献代码,可以让他们做维护者。再重复一遍:

如果有人表示愿意为你的库贡献代码,可以让他们做维护者!

原因是:随着时间流逝,会出现新的技术,问题也在变化。而你也会变化。但你但代码永远在那里。如果你不放权,你的日子会很难过。你会为了维护而精疲力竭,你开始怨恨你的项目,最终它会变成一个垃圾堆。相信我,一定要放权。

接下来,我要说说如何应对别人。

这是开源最重要的一部分,很多时候甚至比写代码还要重要。总会有人喷你,总会有一些自以为是的人,总会有人对你说三道四。

不要听那些人胡扯。

我也曾花了很多时间与人骂战,真希望当时的我能够把这些时间花在别的地方上。相信我,不要理他们。

但是,在判断他人是否有恶意时一定要谨慎。有时候似乎有恶意,但实际上并不是。想想吧,你的代码发布到了全世界。假如你是美国人,项目是用英语写的,那么千万不要忘记并不是每个人都说英语。

假设你想给一个俄语的项目写代码。但你不懂俄语。所以你用 Google 翻译说:“嗨,你有计划什么时候实现吗?”但 Google 翻译成的俄语是“这个什么时候能搞定?!”第一眼看上去你可能会想,“这人是不是脑子有问题?”稍后你就会发现这只不过是翻译没有表达清楚本意而已。

一定要注意这一点,有些人并没有恶意,只是他们不会说你的语言。

除此之外,我能给出的最好建议就是:为 PR 建立牢固的 CI 流程,并为 issue 和 PR 准备模版。你的代码库会收获超大量的 issue 和 PR,如果你想管理好,就要设置一些规则。我的建议:

  • 要求写出复现步骤或失败的测试用例
  • 要求写出 bug 出现的条件

你没有时间处理那些很难出现的 bug。让别人给你证明 bug 确实存在,并帮你找出 bug,这样你才能迅速地改正它。

此外,或许还应该在 CONTRIBUTING.md 或其他地方写明,人们在写 PR 之前应当先通过 issue 与你沟通想法。世界上最悲伤的事情莫过于非常努力地编写 PR 却不被接受了。

说起接受 PR,我想说的最后一条就是,你没有必要做人们要求你做的一切。我就在这方面浪费过很多时间。

许多时候,有些人只需要一个小功能去解决一个孤立的问题,但这个功能对于社区没有任何价值。所以修改 API 时一定要谨慎,因为事事都需要处理的极端情况会让你发疯。全心全意做好你的核心库,不要为那些冷眼旁观者服务。

其实还有点:使用语义化版本,且一定要正确使用。

否则,别人就会不知所措了。还有别忘了推送标签。还要写发布说明——详尽的发布说明。随着库的改进,任何参与的人都有必要知道库发生了哪些变化。

此外还要保持透明、清晰、信息丰富。在弃用某些功能前一定要有宽限期。如果有人投资了你的代码库,而你做出的改变破坏了他们的应用程序,那么他们会恼怒。在更新你的代码库的时候,一定要顾及别人。

总结

到此为止,你可能已经意识到我不仅没有做好开源,而且也不擅长写文章。但因为有人问起,我才勉为其难写了本文。我希望这篇粗文能够帮助那些想发布自己的开源代码的人,帮助他们节约一些时间,减少他们的烦恼。

开源之路崎岖坎坷,希望你在阅读了本文后,前途更加顺利,并取得成功。

尽管如此,我还有最后一条建议。如果没有坚定的决心,不要轻易踏上开源之路,不要将其视作你应做的事情。即使不做开源,你也同样可以找到工作。即使没有开源,你也可以成为一名优秀的开发。虽然开源让我获益匪浅,而且我也很享受做开源的经历,但是我永远也无法挽回花费在那些代码库上的时光,我宁愿与家人一起共度,或追求一些兴趣爱好,或者其他可以带来被动收入的事情。兴之所至,心之所安。如果你对自己构建的东西没有热情,那么就无法取得成功。

原文:
https://medium.com/codezillas/a-bitter-guide-to-open-source-a8e3b6a3c1c4

作者:Ken Wheeler,Formidable 公司开源总监。

本文为 CSDN 翻译,如需转载,请注明来源出处。