个人/团队/公司开源,Joyqi 谈贡献开源的「不同姿势」
前不久,Answer.dev 创始人 @Joyqi 受到邀请,在刚刚结束的 GitHub Universe 的 Local Party 上做了题为「用 GitHub 构建开源项目的各种姿势」的主题分享。以下为他的分享实录。
Hello 大家好,我是 Joyqi。
刚有同学提问,很多学生在大学期间怎样参与开源项目,怎样做自己的第一个开源项目。我的开源生涯也是从大学时间开始,稍后我会分享一下我的开源历程。其实开源可以有不同的姿势,不一定是你去一家公司里面参与开源项目,也可以通过其他方式开始。
先从技术的角度自我介绍一下,我自 2006 年开始参与开源,因为我 2007 年毕业,所以其实大学时就已开始做开源项目。那时全世界的开源运动还处于兴起的阶段,中国的开源项目也应该是第一批,所以当时我算是挺有幸能参与到开源的世界。
下面是当时的一些开源平台,有些如果你在互联网待的时间比较长的话,会知道这些平台。在 GitHub 之前就有这种开源平台,最早叫 SourceFroge,如果知道那你们够 「老」 的。后面是 Google Code,不过很遗憾,他们做了一段时间且在 GitHub 起来后就不做了。这两个前面应该都是用 SVN,即在 Git 之前的版本管理工具都用 SVN 来做的。我自己本身的技术栈、服务端、前端移动端其实都做过,所谓全栈工程师,其实就是全干,因为之前从事的工作岗位要求我做这些工作,所以我对技术上是很开放的。我自己的开源项目也是各种端都有,我觉得开源是一件挺好玩的事情。
个人开源:用得好所以开源了
说到参与开源的各种姿势,先从最普通的姿势,即大家很多同学或朋友最能接受的一个开源姿势 —— 用得好所以开源了。
这是我的一个小的个人项目,用着比较开心,那它是一个什么项目呢?——给你的身份证图片打码。
我们现在经常要在一些平台做验证,需要上传证件照,但又不放心,就会在上面打码,比如会打上「仅供用于某些身份验证」这种透明的码。当然如果我们用一些网站的 online 项目,其实也会不放心,因为要把我们的图片传上去,相当于把身份证也传上去了,其实更不放心。所以说我就做了一个这样的项目。
这很简单,前端的同学应该知道,我当时在学 CoffeeScript,半天时间就搞定了。代码其实也只有一两百行,它没有任何网络请求,全部用 canvas 去做图片,然后在图片上写上一行字,可以调整间距及颜色,还有透明度。
当初这个简单的功能并没有做宣传,只在群里面发了一下,后面就不断有人去 star 去 fork, 这个项目的 fork 数和 star 数的比例还挺高,别看 star 仅不到 300 个,但 fork 却相当多,有很多人拿这个简单的项目去实现自己的打码平台,我觉得还挺好玩的。
之所以提这个项目,就是因为做开源的初心。我做开源的初心是先解决自己个人的真实痛点,这个痛点是存在的,是我自己想去解决的,且这个痛点对其他人也特别适用。因为我觉得在互联网上普遍存在隐私泄露的风险,而大家都有这种担心,所以我把它做出来后,尽管周期很短,但依旧会有这么多人关注,有这么多人用,还有很多人提意见,包括有人还给我提 PR 等,这是个好现象。所以,我觉得这种项目对于很多人来说其实难度不大,你们可以去尝试去做一下这种项目。
另一个项目也挺有意思,我把它取名叫「闪光时刻」。
很多程序学员都会有突发奇想,即突然觉得我有个想法特别牛,其他人都没实现过,我想把它给做出来。然后当时我就写了一个这样的项目——Mobile Device JS ,我们知道 WebGL 有个接口,它可以读取我们显卡的信息,比如像 iPhone ,它就可以通过其接口读取你手机的显卡/处理器 A1 还是 A12 或是 A13 的信息。将处理器信息读取后,根据分辨率就可以很精确地判断你的机器属于哪一代 iPhone,可精确的判断到底是属于哪个型号的 iPhone,这对很多特殊行业有很大帮助。比如网游等行业,这是我后来了解到的,但是当时我只是觉得这个东西很有趣,我突然发现了这样的用法,就把它做出来了。
对此,我还写了一篇文章发在了 SegmentFault 上,文章的题目叫 「思路清奇:XXXX」,当时挺多人给我评论,挺有趣的。后来有个开发者加我微信,啥话不说先发红包,我从来没见过这种情况。有的同学会给自己的开源项目设立赞助通道,大家会去赞助平台去赞助,但我从没见过有人上来直接给红包的。我当时跟他聊了一下,他说他们是一个比较特殊的行业,这个产品给他们解决了一个很大的问题 —— 原来他们一直想很精确的判断用户的手机到底是什么型号,不能只判断 iPhone 和安卓,必须得判断是哪一代机型,所以说他觉得我的产品对他特别有帮助,我觉得特别有成就感。当然,我的产品给他带来的价值其实肯定不止这些钱,但我依旧觉得挺高兴的。我觉得这是一个特别特殊的经历,可以给大家分享一下,所以说开源其实还是可以创造价值的。
开源还有一种姿势,有很多的朋友自己从编码习惯出发做开源,这其实是一种「偷懒」。我自己就做了一个这样项目,这个项目刚做还没有什么 star 和 contributor,它就是一个 GitHub 的模板,比如说你有段时间经常想做一类项目,可以把它做成一个模板。然后你可以做一类项目的时候,用这个模板发布项目就可以省很多事。最近我写了很多这种 TS 的项目,就是用 TS 发到 npm 上去,但发现很多动作都是重复的。因此,我看到 GitHub 有这样的模板功能,便在模板里面写了一个 GitHub Action 后,它可以根据你的初始化条目,等初始化项目以后,就可以得到一个标准的 TS 的一个脚手架的项目,在里面直接写代码就可以,很多东西都不用去配,tsconfig 可以不用去配置。以上就是我从个人角度出发的项目。
其实,该类项目不仅仅是上面所说的模板项目,其实还有很多,比如很多人之前会将 vim 的配置作为一个开源项目。如果大家用 vim 的话,应该会关注这种项目或者 VS Code 的配置或者是诸如此类的这种项目还有脚本,我们可以提升平时开发效率的一些项目,也可以做开源项目,这是我个人的一些开发项目及怎样去参与这些开源项目的经验。
很多项目会有一些 star,有的没有 star 或是刚发布出来也没有关注。但我认为追求 star 并不重要,首先是开源的态度,能把东西做出来,把文档写好,对其他人有帮助,我觉得能做到这个态度是特别重要的。
社区开源:玩大一点
后面可以玩一点高级的开源姿势,我可以把它叫社区开源。
这是「中国开源码力榜」,一个网站,这是我们和开源社以及 OpenDigger 合作的项目。OpenDigger 负责把 GitHub 上最优秀、协作影响力最大的 100 位中国程序员找出来,然后我们再把程序员的 profile 放到 GitHub 上,去做成一个 Repo,然后这些程序员可以来 fork 该 Repo,更新 profile。我们整个项目就完全托管在 GitHub 上,这是完全社区的项目。所以如果你在这个榜单中,就可以 fork 这个项目,然后去提 PR 跟进你的 profile, 然后我们后面写了一堆 Actions 会自动 build 这个网站,会更新你的 profile。
大家可以看到,该项目的 PR 其实就是很多人在去更新自己的 profile,然后去增加自己的项目经验。右边我们的 Actions 会去做构建然后发布。我们这个项目是全自动运行的。因为当时我们目标是不想把项目做成一个动态的网站,后面有数据库,我觉得那个太不酷了,太老了,我们把它做成一个完全公开的,所有的数据、所有的构建过程都以社区化的方式运行。所以,我们就选择了这样的方式来做这个项目。
然后,就是我人生中比较重要的一个项目——我在 2007 年的时候开始做了这个项目,叫 Typecho , 这个项目现在有 9000 多 star ,从 2007 年做到现在,想想已经有 15 年了,很不可思议,生命力已经出乎了我的意料。创业以后,我工作比较忙,更新的频次很低,在我们 Typecho 的用户群里面,流行一个梗,就是「Typecho 什么时候更新」。这个梗,在我去参加用户聚会的时候,大家经常就会拿出来问。因为更新实在太慢,人家都是以月以周为节点更新,我们则是以年为节点来计算更新时间,但我们其实只是大版本没有更新, commit 还是在经常更新的。
Typecho 项目其实特别纯粹,特别理想化。大学时我就想做一个中国的 WordPress, 因为 WordPress 当时也在 0.1,我跟他当时基本上是同时间发布的这个版本。然后我就想做一个中国的博客软件出来,也是 PHP 的,因为当时在大学里面接触的第一门动态脚本语言就是 PHP。我们在做的过程中,遇到了当时在中国开的第一个 WordCamp, 一个面向 WordPress 开发者和爱好者的聚会,因此我就认识了我的很多团队成员,他们对 Typecho 这个项目很有兴趣,想来参与这个项目。所以我们 2007 年的时候就以完全远程的方式组建了一个这个社区化的开源团队。
大家都来自天南海北,我们都当时就用邮件列表去做沟通,项目管理也是用 GitHub 的 issue 来做。这么多年下来,该项目之所以还有如此强的生命力,这也跟我们当初选择社区化运作分不开。尽管有的人可能比较忙,没时间更新,但 Typecho 依旧社区运作的项目,大家也可以去提交 PR,可以去提交 issue,也可以去参与到项目中,所以我觉得这个项目可以持续到现在是有原因的。
在该项目的成长过程中,遇到了很多有意思的事,我不知道大家知不知道 PHP 这个语言,其实它分很多版本,每个版本又可以部署在不同的平台上,然后部署的平台上又可以有很多不同的部署方式。所以后面我们每天有一个 nightly 版本,每晚会编译该版本。但编译环境特别复杂,即多版本多操作、多环境、多 CPU 架构交叉定义。
GitHub 有一个好处,就是 GitHub Actions Runner 对开源项目是完全免费的。所以尽管编译特别耗时(每天晚上编译一次大概需要三个半小时),如果让我们自己机器去编译的话,这个是很费钱的。但用 GitHub Runner 来做的话,我觉得还是薅到了很多「羊毛」。最早的时候是所有平台全部并行全部并发的去编译,编译的时候直接把 runner 给搞挂了(不知道是我搞挂了还是它自己本身有问题),所以我们后来换了一下,每个平台会有一个 stage, 编译完以后进入到下一个平台,也相当于做了一个小小的分发,这是我们这个项目比较特殊的一点。
还有一点,就是我们的项目用到了比较多的 GitHub 交叉。GitHub Actions 有 API,我们会在 GitHub 多个项目之间,因为整个 Typecho 项目下面会有多个 Repo,比如说有 Typecho 这个 Repo 它是用来放项目主要代码的,Languages 这个 Repo 是用来放所有的多语言的,大家可以看到现大概 17 种语言的都是用户去提交,然后这两个 Repo 之间其实是有联动关系的,做了一个相互交叉的 Trigger。
如果 Typecho 这边修改了某一些语句的话,它会 Trigger 到 Typecho Languages 项目,Languages 项目编译自动把 Typecho 项目的代码 clone 下来,然后去编译 message.bot 这文件,发布语言包,之后 Typecho 再从该项目里下载语言包编译成一个多语言版本的 Typecho,这实际上是多方触发的关系,我们把它用 GitHub Actions 做了个实现,这样就可以减少很多手动过程,由于我们本身人就少,人工特别金贵,因此尽量都自动化。
以上就是 Typecho 的情况。
公司开源:技术能力溢出
由于我们自己在 SegmentFault 也开源了很多自己用到的组件,所以如果公司要做开源项目,或公司的某个产品要去开源,我觉得这是很多国内大厂经常用到的一种开源模式,更多的是来自公司的能力的溢出。
如果你做了一个项目,但由于该项目只能在公司内部用,所以会觉得自己的能力被埋没了,或是自己的影响力应该可以覆盖到更远的地方,所以此时你就该将它开源出来。公司开源的项目有几个特点:
- 把项目开源出来肯定是来自公司项目的能力溢出 —— 因为你的公司能力,你能达到这个地步,你才会去开源这个项目,所以可能只有优秀的公司才有能力去做开源或做成功的开源。
- 它是以公司的技术团队为主体的,就像我们这些项目可能现在还没有做社区化,只是一起提 issue 或修小的 bug 提一下 PR,但主要还是以我们公司的团队为主,因为是我们主动将其开源出来的。
- 另外就是这里面重复造轮子的事情会比较多,下面两个例子就是有点吐槽的意味:比如现在看不少大厂的开源项目有很多重复的轮子,早前前端行业里被吐槽比较多,mix 还有前端很多渲染的项目,都会重复造很多轮子。
- 为什么?我觉得可能就是因为在大厂内部有很多能力需要去释放,可能受到 KPI 影响,所以会重复造轮子,给后面长远发展造成了影响,有「人走茶凉」的风险。如果团队有调整的话,该项目就会因为没有人维护而被「搁浅」。这也是为什么我们之前用开源,如果没有基金会维护,只是一个厂商去开源的项目,我们会有这样的疑虑 —— 他会否有可能过段时间就不维护了?
我们在做功能的时候,就遇到了刚与 GitLab 的同学一直在聊的这个问题 —— 社区与内部同步。因为这个项目是从公司内部开源出来的,所以它肯定是在公司内部的代码托管平台先做了开发,然后再放到 GitHub 上去。它的开发主体可能还是在内部,只是它会定期地去 push 到外面的 GitHub 的 Repo 上去。因此,这就会存在同步问题。
该问题我们目前已经有了一些解决方法,但也不能说完全解决了 —— 因为存在一些代码的同步问题。
- 目前,我们在代码同步方面采用镜像的方式,就是 GitLab Mirror 到 GitHub 上去。但这有一个问题,如果你在 GitHub 上有 PR 的话,merge 就会有很大的问题。
- 所以我们现在也不用 Mirror 的方式了,而是两边分开,会有机器人去做同步,如果那边 GitHub 有 merge 的话,它就会同步到 GitLab 里面, PR 管理也是这样,它有一个 webhook,如果那边有 PR 的话,我们就不会接收这个同步的信号,而是将其同步到内部的代码里面。
- 分支里我们用了一些比较常用的 Flow ,之前用的是 Git Flow ,现在则不常用 。
- 在这里,为什么要强调说一下 CI/CD 呢?就像之前所说,如果将其放 GitHub 上,它的 runner 的计算能力是有限制的,除非买付费 plan,不然其 build 能力是受限的。所以,现在将 build 部分放在我们自己的内部平台里面打包编译,然后社区只做测试,跑单元测试代码或是去做比较轻量的一些计算。
以上就是我们内部和外部的代码管理平台的一些经验。
做了这么多个人开源项目、公司的开源项目以及社区的开源项目之后,我们就开始思考一个事情,我们能不能将开源这件事情做成一家公司,将公司做成一个开源公司,把我们自己的能力充分展现,把我们主要产品的能力开源出来。
有了以上积累,我们做了开源问答社区软件 Answer,该项目正式发布于 10.24,发布后的第一个星期,就在 GitHub Tending 霸榜了一周左右,不到一个月时间已有 4000 多 star。正因为 SegmentFault 是做问答社区起家的,所以我们积累了大部分问答社区的经验。在我们做社区的过程中,有很多 B 端的用户提到他们也需要这样的社区,能不能帮他们搭这样的社区,或是怎样去实现这样的社区。之前我们很难去响应这种需求,只能提议他来我们社区建一个专区或子站,但我觉得这样的话他们的需求不能完全满足,因为他们有些内容是需要完全自定义的或自己去控制自己的数据。
基于这样的想法,也基于我们在社区开源这么多年的思考,我们在想能不能把我们在问答社区领域的能力完全开放出来,变成一个开源的项目让大家来用。这样其实是颠覆了我们整个商业模式 —— 之前我们就是一个社区公司,通过广告服务来赚钱。如今,我们变成了一家开源商业公司,一家软件公司,我们的驱动力也变成了用社区驱动来开发,跟我们此前的驱动方式完全不一样。
但我觉得开源对商业公司来说是至关重要的,正如刚才有人问韩骏老师是否有想法将开源项目做商业化的时候,我们也在想这个问题 —— 开源带给商业化最大的一个作用是什么?其实对商业用户来说,建立信任是很重要的步骤,为什么让用户相信你去买你的产品?你可以想象一下,为什么我们要付费买 GitLab ?如果你的公司足够大,可以支持买 GitLab 这样产品的话,你为什么心甘情愿掏钱买?或者你买 JetBrians 这种编辑器的理由是什么?为什么?因为你用过它的开源产品,你知道它的代码,你知道它整个运作流程,你相信它有一个坚持的社区在支撑着这一切的运作,它有着很健壮的力量。对我们软件开发者而言,健壮性是很必要的一个条件。如果你只是一个小作坊或小公司的话,我很难把自己内部的能力展现给你。但如果开源的话,我可以把我对社区的管理能力统统展现给你。我觉得这对商业化来说是很重要的一步,用户可以通过这个过程来相信你的产品,相信你的产品可以给他们带来价值,也相信你可以很好地去发展这个产品。因为他不可能就用一次,肯定要长期去用的。所以,这也是当时我们要做开源公司的最初的思考。
具体到开源公司后面怎么去做商业化、商业模式,我们想得比较多的就是软件 SaaS 方面了,后面我们可能会围绕这样的能力来去构建商业化产品。以开源模式做公司的话我们会有会遇到一些转变,首先就是国际化。
由于我们的项目是完全国际化的项目,其文档全是英文,发布渠道也是在国际渠道,所以它给我们带来了很多思维上的转变。之前我们没有过多地思考这些问题的,但我可以分享出来,大家可以借鉴一下,我们现在也还在处理这些问题当中,比如我们的文档、注释都是全英文。这一点之前我们可能有些人没有写注释的习惯,或是写文档的习惯,对他来说是一件很难的事情。但如果你要做一个社区,这两样都是特别重要,特别是对一个国际化产品而言,全英文的文档,是用户了解你的第一步。
我们也把英语作为社区的官方语言,现在也有很多中文用户来提问,我们不会拒绝,但我们会引导大家尽量用英文去提问。
现在,我们在做的一步是将语言档剥离,然后交给社区去维护。我们现在把它交给到第三方的开源平台,大家可以在上面帮我们翻译一些词条,目前已经有一些翻译了。
接下来,就是社区化的过程。
其实刚刚也提到过,我们现在的产品路线图已是完全社区化了,现在用 GitHub 的 Project 来做路径图,用 GitHub 的 Project 来发布这些功能,或是参与讨论这些功能,或是它已经实现的功能我们都放在上面。然后告诉大家我们会在哪一个阶段完成,比如 Q1、Q2、Q3、Q4,或者还要标注它是哪个版本,比如在 0.3、0.4 哪个版本发布。在这个过程中,这些功能你都可以参与讨论。如果你还有其他的功能建议,也可以在 issue 里面提出来。提出来后,我们觉得合适的话会把它列入到我们的 Roadmap 里,这些过程全部是公开的,大家可以在里面自由讨论自己想要的功能。
还有一个就是我们的社区,现在除了传统社区如 GitHub 社区及 Stack Overflow 等其他类似的社区以外,我们还在一些比较新的国外社区做推广及社区建设,在上面也可以讨论我们的产品,我们在 Reddit 上有频道,在 Product Hunt 上也发布了,当时也收获了特别好的反响和回馈,我们还建立了 Discord 聊天频道,大家可以在里面聊我们的产品,和我们官方沟通。
最后,聊一下在 Answer 项目里遇到的一些挑战:
第一,就是文档。刚才也说了,文档对我们很重要,因为之前没有受过这种专业的文档训练,所以我觉得这个课我们必须补上。现在我们实际上是在集体学习怎样编写一份好的文档,包括文档结构,描述性的语言,包括它的排版。目前都在疯狂的学习当中,现在还没有做到足够好,但我们的态度是一定要编写一份能让大家、能让开发者或用户阅读起来很舒心的一份文档。
第二,就是社区答复时间和工作时间的分配。这是项目发布以后我们遇到的一个比较大的问题,用户的问题会集中一段时间在上面提出来,我们要解决的话得要 Debug 复现他的问题,要跟他讨论,很费时间,所以该如何平衡这个时间呢?如果所有工程师都在花时间在这里解决这些问题的话,很可能会影响到我们正常的产品开发。
因此,我们现在有一个定期轮值的机制,即前端或后端会分出一个人力来在一段时间重点跟踪这些项目,他的时间会分配得比较多,使得其他人在社区答复上面受到的影响少一点,以此来做正常的项目迭代。这是我们目前的一个做法,还在调整中,后面如果还有更好的解决方式的话大家也可以去讨论。
第三,如何将产品和技术理念国际化。现在我用中文跟大家交流,但如果在更广阔的国际平台上用英语,就是用或写文章或是做演讲的话,对我们自己的语言能力是一个挑战。很多人之前没有重视这方面,但我觉得这是让其他用户对你的项目产生信任的很重要的一步。可以通过这些了解你对产品的态度很重要。
第四,就是社区的规则。这一点我们现在还在建立中,包括怎样奖励对我们贡献比较大的人,我们希望建立成一种规则性的东西 —— 比如:你对我们产品有很大的贡献,我们有实物的奖励或给你有一些荣誉;如果你的贡献足够大,你又有兴趣比较全职性的参与进来的话,我们会给你怎样的身份来将你吸纳进来。还有就是大家怎样参与到项目方向性的讨论中来,这是我们后面社区要去建立规则的一个重点。现在的讨论还比较分散,但我希望我们能有一些定期的话题去讨论,讨论完后可以形成某些提案,大家可以去投票,去决定做不做,很多成熟的基金会是有这样的机制的。
最后是我们项目的一个小广告,大家如果想贡献的话,可以一起来贡献,不管什么形式,哪怕是言语上的鼓励也可以。
https://answer.dev
https://github.com/answerdev/answer
https://twitter.com/AnswerDev
这是我们的官网主页,包括我们 GitHub 主页及我们在 Twitter 的官方账号,欢迎大家随时与我们互动。
我的 ID 是 @joyqi,大家可以在各个平台都可以通过该 ID 搜到我,欢迎大家和我联系!
Answer 官方中文博客
开源问答社区软件 Answer 1.0 正式版发布!
AnswerDev赞 7阅读 3.1k评论 1
知行合一·开源合规沙龙
Yan阅读 23.8k
两次登上了 Github trending!这个 API 管理工具厉害了!
气势凌人的柿子赞 2阅读 489
Postcat IDEA 插件,最全的使用教程
圆圆大姐头赞 2阅读 477
Postcat 如何生成接口文档,2 分钟学会
圆圆大姐头赞 2阅读 397
Kubernetes v1.27 新特性一览
张晋涛赞 1阅读 1.1k
开源推荐!一款高质量的企业培训系统
开源网校系统赞 3阅读 514
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。