如何开发与坚持维护一个企业级的开源项目 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
moonrailgun
V2EX    程序员

如何开发与坚持维护一个企业级的开源项目

  •  4
     
  •   moonrailgun
    moonrailgun 2020-12-15 09:13:29 +08:00 4586 次点击
    这是一个创建于 1763 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原文链接: http://moonrailgun.com/posts/28f21ef5/

    TRPG Engine 是我一直坚持维护的一个开源项目。正如所有的开源项目都起源于开发者的兴趣,TRPG Engine也是我对于跑团这一小众领域的兴趣。

    我在没有支援没有赞助,单凭个人爱好独立坚持开发 3 年以上不间断。前端代码累计提交 2700+, 后端代码累计提交 1200+,风雨无阻。

    谨以此文,分享一下我维护这个开源项目的经历。并与千千万万独立坚持的开源人共勉。

    起初

    所有的个人项目都起源于想做。因为我想做,因此我建立了这样的项目。最初的目的很单纯,就是作为我学习 React 的一个实践。

    最初选用的技术栈是React + Redux。之所以用React是为了可以共享一部分的代码到React Native, 这样的搭配会很大的减少重复逻辑的开发与后期的维护,以减少成本。

    而事实是我在两者共存与中间代码上花费了很多的精力,写了很多中间脚本使网页版与 RN 版能够相互协作。

    明确定位

    一个项目,如果要走的长远,必须明确你的产品定位与目标用户。比如同样作为即时通讯应用, 钉钉瞄准的用户群是上班族,slack 的用户群是开发者,discord 的目标用户是游戏玩家,而 qq 的用户群是小学生。以此为原点,钉钉开发出了一系列日历,考勤,协同,已读未读,ding 等功能。slack 只做了大量机器人,discord 专注于语音会话与大用户群组聊天,而 qq 则整出了很多花样。

    明确自己的定位,其目标一定是解决某种痛点与缺陷,做出任何的抉择都需要考虑是不是符合自己的定位。一个明确的定位可以帮助你不会花费无意义的时间在没有收益的功能上。

    时刻保持热情与思考

    时刻记住,项目是为自己做的。它不是一种谋生工具,而是一种兴趣爱好。它最初应当起源于你对现状的小小不满,终止于对此兴趣的终止。不妨增加一些筹码:比如它可以作为你的游戏场,比如他可以作为你谋求更高事业渠道的凭证,比如他可以是你与你伴侣之间的小小私人空间,比如你可以这样告诉自己,你的每一行代码都有可能帮助到素未蒙面的陌生人,而他会感谢你的无私付出。这些会帮助你时刻保持热情与动力,而不至于让这个项目半途而废。

    维护自己的门面

    如果一个项目想要宣传,一个门面则非常重要。这可能是一个 README, 一片文章,一个官网。但是如果没有任何说明,告诉别人这是什么,你在做什么。又能期待谁来阅读你的源码呢?

    自己是第一用户

    对于个人项目来说,自己才是自己产品最忠实的用户,只有这样才能不断发掘产品的不足,并不断改善。如果自己都不想用自己的产品,那么这个产品还有存在的必要么?

    开发

    回到技术细节:

    因为技术在不断更新。而有的库又逐步步入生命周期的终结,很多情况不得不花费时间去迁移。

    TRPG Engine经历过几次大的迁移 /迭代:

    • 原来TRPG Engine的后端是使用的node-orm2. 然后这个库被弃用了。因此花了很大经历将其迁移到sequelize,包括代码的修改与数据库的变更。这个没什么好分享的,纯粹是当时的选择有限,而库的生命周期比较短。
    • 最早的TRPG Engine使用的是用纯粹的 js 写的,但是随着业务的不断增多,代码复杂度的变高,我选择使用Typescript对我的项目进行重构。从长远来看这一步是非常值得的,TS 的类型系统长远的帮助到了一个项目的健康发展。(其实有点小遗憾,从目前的角度来看 flow 在一些细节做得比 ts 更加好)。
    • React ClassComponentReact Hooks: hooks 无疑拥有更高的抽象性,使用 Hooks 能抛弃 HOC 这种很难被 typescript 支持的写法。同时更方便代码的复用,特别是对于 React 和 React Native 代码并存的项目来说。
    • 前端重构, 重写界面。原来的 TRPG Engine 是参考的钉钉设计的,但实际的迭代中,频道的需求更为突出。即需要由原来的单层消息列表变成双层消息列表。因此花费了几个月时间写了一版类似于Discord设计的新版页面,并且颜色也从原来的亮色变成保护眼睛的暗色。

    善用单元测试

    为了一个项目的长远发展,测试用例与持续集成都是必要的。特别是单元测试,在很多时候能帮助到项目的提前预知问题。坚持每个 bug 都有一个对应的单元测试用例,防止再次出现类似的问题。

    TRPG Engine 虽然开始写测试用例比较晚,但是一旦有机会就会补充一些测试用例,以防止出现一些边缘问题。

    目前TRPG Engine前端有 223 个测试用例,后端有 284 个测试用例,还远远不够一个项目的健康发展。

    学会数据迁移

    为了方便数据库的升级,自己 fork 了一个sequelize-auto-migrations库用于生成数据库的迁移脚本, 因为原作者已经不维护了。

    数据库迁移脚本可以保证在任意环境下都能生成正确的数据库格式。这对于关系型数据库来说非常重要。

    兴趣是原始驱动力

    与商业项目不同的是,个人项目可以把一切自己感兴趣、想做的东西都想办法以某种形式糅合到自己的项目中。

    TRPG Engine就拥有这些有意思的系统:

    • 基于 xml 描述与 js 沙盒的动态计算的表单系统
    • 基于slate实现的笔记系统与富文本输入框
    • 基于 meta 信息的动态面板
    • 基于 BBCode 的消息解释器

    运维

    为了维护与运营这个项目,唯一的支出就是在服务器和 OSS 上了,零零散散也花费了几千元在上面了。一台 2 核 4G 的主服务器, 在主服务器上运行 Mysql, Redis 与 Mysql 。另外还有一台 1 核 1G 的小型服务器作为语音服务器与测试服务器。前端的代码都是本地编译好后提交到第三方对象存储上,这样用户的访问会更加迅速与快捷。

    赞助?

    曾经也考虑过要不要和别人一样放出二维码,看看能不能获得一些打赏,后来想了想还是算了。一方面没有多少的关注,我本人也比较低调不善于宣传。另一方面感觉,掺杂了利益后的开源项目,总感觉失去了纯粹性。爱好只能是爱好,如果成为一种牟利方式,那么可能就不像当初那么纯粹了。

    感谢

    最后感谢所有开源作者的无私奉献,正是你们存在才能让这个互联网世界变得更加精彩。

    如果能看到最后的朋友,希望能将你的开源项目在评论区留下。我们一起互勉

    33 条回复    2020-12-18 14:41:34 +08:00
    keygen88
        1
    keygen88  
       2020-12-15 09:51:51 +08:00
    这个项目的目标用户是不是比较小众,做了几年怎么会没什么关注?
    f6x
        2
    f6x  
       2020-12-15 09:57:38 +08:00
    整合型的项目适合自己用, 适合产品带起技术.

    加油.
    raaaaaar
        3
    raaaaaar  
       2020-12-15 09:59:22 +08:00 via Android
    支持
    moonrailgun
        4
    moonrailgun  
    OP
       2020-12-15 10:17:07 +08:00
    @keygen88 因为我的项目针对的跑团这个圈子本身就比较小。入门成本高,复杂度高,学习曲线陡峭。这些原因导致了真正的跑团用户并不是很多,另外我个人也不是很擅长宣传。多方面因素下导致这种情况是理所当然。
    glacial
        5
    glacial  
       2020-12-15 10:20:40 +08:00
    加油
    tikazyq
        6
    tikazyq  
       2020-12-15 10:23:12 +08:00
    支持一个
    icyalala
        7
    icyalala  
       2020-12-15 10:25:07 +08:00
    开源项目能健康的维护辖区,宣传和交流是必不可少的一环。。
    试试增加一些宣传能力吧。
    opengps
        8
    opengps  
       2020-12-15 10:35:05 +08:00
    "qq 的用户群是小学生",哈哈

    还是建议带上利益,有利益注入,关停的风险才能更低,不然哪天楼主没兴趣了,项目也黄了,用户不会敢冒险依赖使用的,顶多用来 copy 代码。
    darcylee1998
        9
    darcylee1998  
       2020-12-15 10:57:09 +08:00
    赞...
    zone10
        10
    zone10  
       2020-12-15 10:59:37 +08:00
    我搞半天没理解跑团什么意思, 搜了一下: 跑团是对 TRPG (桌上角色扮演游戏)的一种俗称,是一种比较流行的桌上游戏形式。游戏往往由三五人组成,其中一人担当游戏的主持人,另外几人担当玩家. 说一下我的看法吧, 你这文档还有 Github 的提交挺像模像样的, 做了有几年没理由这么点 star, 归根结底是你并没有真的在做开源项目, 并不是源码放出来就是开源项目. 想体验一下项目得在你那里注册一个账号, 到这里直接就不想继续下去了, 还有你没有提供文档教怎么部署项目, 而只停留在怎么使用你的项目, 各方面都体现你以一种集中化的思维在做开源项目. 建议, 1.闭源并增加运营能力把它做成一款实用的产品. 2. 完全开源, 但别用集中化思维做开源, 别教我做事
    Braisdom
        11
    Braisdom  
       2020-12-15 11:03:10 +08:00
    支持楼主,维护开源项目是需要能力,但最终是自身收益的付出,贡献出代码,大家互相学习,我亦如此,这是我的项目,我给楼主 star 并 follow 了,https://github.com/braisdom/ObjectiveSql,互相支持,一起努力
    Braisdom
        12
    Braisdom  
       2020-12-15 11:04:57 +08:00
    @Braisdom V 站的 Bug 不是一般的多呀,链接都能搞错: https://github.com/braisdom/ObjectiveSql
    CismonX
        13
    CismonX  
       2020-12-15 11:34:01 +08:00
    > 不允许用于任何未经授权的商业行为

    看上去楼主对 GPL 有些误解

    楼主这个项目使用的 GPLv3 是允许商业使用的。甚至 FSF 还大力鼓励在商业场景使用 GPL 当然是建立在遵守其条款的前提下

    (自由软件四大准则第 0 条:以任何目的使用软件的自由)
    lithium4010
        14
    lithium4010  
       2020-12-15 12:15:41 +08:00
    楼主带我跑团
    Kirsk
        15
    Kirsk  
       2020-12-15 13:08:04 +08:00 via Android
    对企业级是不是有什么误解
    renmu123
        16
    renmu123  
       2020-12-15 13:40:41 +08:00 via Android
    做产品其实最重要的一环就是推广,酒香也怕巷子深。如果你做得够好,用得人够多,我相信圈子里的人也是愿意付费了。
    建议接下来做大量推广,等有不少真实用户反馈之后再进行开发。
    以及减少入门的门槛。
    先把这个产品运营好,再去考虑开源的事,毕竟不是所有人都是程序员,大多数人都是懒惰的。
    jones2000
        17
    jones2000  
       2020-12-15 15:22:57 +08:00
    支持作者,加油.
    我自己也有一个前端开源库, 大概 10W+的代码量, 大概开源 2 年了, 都是一个人维护,升级, 是比较累的, 但很有成就感(毕竟第 1 次用 js 开发), 也通过这个开源库交到了很多志同道合的朋友.
    moonrailgun
        18
    moonrailgun  
    OP
      &nsp;2020-12-15 15:31:17 +08:00
    @CismonX 感谢指正。对 GPL 协议有点误解,已改正。谢谢您的指出
    moonrailgun
        19
    moonrailgun  
    OP
       2020-12-15 15:38:56 +08:00
    @zone10 不好意思,一方面自己比较内向没有宣传,开发 3 年+前面 2 年多都是一个人在闷头开发,另一方面因为还在不断迭代,总感觉部署文档写了不久就要失效了的错觉。其实已经提供了 Dockerfile 文件和 docker-compose 配置,以及用于 docker-swarm 的配置和简单的教程。可能放在不明显的地方所以看不见吧。谢谢您的指出,我会花时间去考虑写一个比较正式一点的部署文档的。

    关于账号问题,其实我没有办法考虑一个比较私人(指没有被邀请不能看到聊天记录)的聊天项目什么情况下可以允许匿名用户访问。可能是我个人的局限性吧

    感谢你花时间的回复, 但仍要请教一下什么是一个集中化的思维。因为我目前没有协作者我不知道应该如何开始。期待您的回复
    moonrailgun
        20
    moonrailgun  
    OP
       2020-12-15 15:40:31 +08:00   1
    @Braisdom 之前看到过您的项目,虽然不是很懂 java,但是 star 了,加油开源人!
    dartabe
        21
    dartabe  
       2020-12-15 15:42:19 +08:00
    react 测试看到我头大 变化太快 看各种 best practice 还是很难下手
    moonrailgun
        22
    moonrailgun  
    OP
       2020-12-15 15:43:24 +08:00
    @Kirsk 我不是很确定您对企业级的定位是什么。
    我对企业级的定位是能持续迭代,有明确需求,有错误收集,日志收集,能集群化,有监控。那么这个项目就是一个完备的企业级项目。
    moonrailgun
        23
    moonrailgun  
    OP
       2020-12-15 15:45:12 +08:00
    @dartabe 是的。之前我用 enzyme,然后它不维护了。。。现在转成 testing-library
    moonrailgun
        24
    moonrailgun  
    OP
       2020-12-15 15:46:05 +08:00
    @jones2000 把你的项目 po 出来,大家一起学习呗
    moonrailgun
        25
    moonrailgun   div class="badges">
    OP
       2020-12-15 15:48:23 +08:00
    @renmu123 是的。我觉得减少入门门槛非常重要。我写了一套简单的 DSL 来适应复杂的需求。然后发现其实很多人根本没法使用,哪怕最简单的只需要跟着示例复制黏贴即可。所以我现在正在实现一套布局编辑器以帮助用户使用
    KagurazakaNyaa
        26
    KagurazakaNyaa  
       2020-12-15 16:12:39 +08:00
    看了一下,其实可以考虑在 Client 中也添加 Dockerfile 来支持构建,在 Docker Hub 上可以建立官方镜像并配置自动构建,然后就可以使用 docker-compose 来编排 Server 和 Client 了,甚至可以写成 Helm 的 Chart 进行 k8s 部署
    KagurazakaNyaa
        27
    KagurazakaNyaa  
       2020-12-15 16:21:30 +08:00
    示例的自动构建配置,此配置应当在 https://hub.docker.com/repository/docker/<dockerid>/<image-name>/builds/edit 中进行配置
    ![autobuild]( https://i.loli.net/2020/12/15/AUQKbW9rLDd1npg.png)
    tomsun28
        28
    tomsun28  
       2020-12-15 16:25:51 +08:00
    赞,不要等着 10 全 10 美再宣传出去,比如你之前写的 docker-swarm 可是大家都开始 k8s 了,在开源协作中迭代感觉更快成长哦,说这些其实我的项目也不咋地,也不知道咋宣传 https://github.com/tomsun28/sureness
    moonrailgun
        29
    moonrailgun  
    OP
       2020-12-15 17:08:44 +08:00
    @XiLingHost 感谢你的建议。因为我是客户端编译好了全量丢到 oss 上的,这样就能享受 CDN 的加持,还没想过用 docker 部署。。。毕竟我的服务器只有 1m 小水管
    moonrailgun
        30
    moonrailgun  
    OP
       2020-12-15 17:10:35 +08:00
    @tomsun28 用 docker-swarm 的理由是需要的资源少。k8s 毕竟太大了,适合一个比较大的体量的集群。而我目前只有一台主服务器,主要是想用它的滚动升级。

    适合的才是最好的。如果没有必要我觉得没必要跟风用 k8s 。
    jones2000
        31
    jones2000  
       2020-12-15 21:10:35 +08:00
    @moonrailgun js 金融图形库+量化指标执行引擎( https://github.com/jones2000/HQChart )。 小众插件,就股票,数字货币前端展示用。
    zone10
        32
    zone10  
       2020-12-16 12:00:37 +08:00
    @moonrailgun 举个例子, 微信和 slack, 微信就是集中式的, 你使用微信的服务并且只有使用权, 他随时可以把你断了你就没办法了, 而 slack 就是分布式的, 任何人都可以自己整个微信出来, 不会受制于人. 别人愿意用你这个项目更多的是考虑容不容易部署、自定义、集成、扩展等等. 还有你说这是企业级的那数据安全性敢不敢保证, 你敢强调百分百安全那是加分点应该写出来. 我看你的行文其实做的是微信钉钉而不是 slack, 所以建议干脆闭源算了, 好好推广运营, 说不定能做成个创业项目
    moonrailgun
        33
    moonrailgun  
    OP
       2020-12-18 14:41:34 +08:00
    @zone10 我其实是想做 gitlab 这种,以开源版来推广和让大家使用,然后高级服务与企业服务收费(目前还没有)的这种模式。我觉得这也是很多开源企业项目的盈利方式
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5972 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 06:18 PVG 14:18 LAX 23:18 JFK 02:18
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86