##打造GitHub千星项目的经验分享

打造GitHub千星项目的经验分享 - 简书 http://www.jianshu.com/p/ba323bbcdf0f?utm_source=desktop&utm_medium=timeline

Alt text

Product Hunt链接
官网链接 <-- 戳戳我
下载页面
GitHub项目

2017年初,我花了大约三个星期写了基于Electron的GitHub Gist管理软件Lepton。开始只把它作为学习Electron的练习项目,却想不到它意外火了一把。
正式发布后,Lepton在GitHub的星数在一周左右冲上了1000,连续好几天登上了GitHub daily trending的前十(JS和All language)。在收到不少有意思的Issue和PR之余,还被Slack一个高级工程师引荐加入Electron官网的feature app之一。甚至还被一些国外媒体自发报道。(这里这里、和这里

Alt text

网上关于在GitHub上打造高星项目的经验分享不多,少数几篇也是巨牛级别的,让人学习起来无从下手。所以我想把这次有意思的经验写下来和大家分享。
Lepton介绍


Alt text

Lepton是一款跨平台(Mac/Windows/Linxu)的snippet管理软件,简单来说,“码笼”。
功能
查询/新建/修改/删除 Snippet
本地搜索
语言标签 + 个性化标签
格式化Description(title + tag)
Markdown渲染
富文本编辑
语法高亮
云端同步 + 跨平台支持(Win + macOS + Linux)
项目开源

初衷
Lepton项目的初衷是打造一款保存snippet的“印象代码”。
作为一名码匠,平时需要把总结的snippet保存在易于管理的地方,就像平时把笔记保存在印象笔记里一样。如果印象笔记能保存snippet就好了!可惜印象笔记对代码块支持不好,需要在别的地方把代码块高亮,然后再贴回来,并常常出现格式混乱。
我们也可以使用Google Drive/Dropbox/其他云盘。缺点是,这种基于文件夹的管理不如标签适合检索。还有一些单机软件比如Snippets, 能实现本地代码保存,可惜不支持跨平台同步(比如从Mac到Windows)。
到2017年初为止,GitHub Gist可能是最适合保存snippet的云端。它不仅支持基本的语法高亮、分享、隐私设置,还会保存代码的所有历史版本,甚至还提供了REST API支持。美中不足的是,Gist没有提供标签功能,而且网页端开发不完善,所有snippet按照时间顺序堆积在一起,难以有效管理。虽然有少数第三方的客户端,比如GistBox,但是都闭源且开发停滞。所以,我觉得利用Electron + Gist打造跨平台的snippet manager将是一个不错的切入点。
技术调研
项目开始前,我在Electron feature app网页上寻找里面的开源项目,希望可以借鉴经验,少踩坑。
幸运的是,我在GitHub社区找到了一个技术栈相似的项目pupaFM。作者xwartz提供了详尽的commit记录,阅读commit记录就像阅读历史故事一样有意思 。通过在本地重现pupaFM大概前60个commit,我大致了解了Redux+React+Electron搭建项目的基本方法,也同时点亮Webpack技能点。
Lepton就是在这个基础上搭建起来的。为了方便其他开发者方便借鉴Lepton经验,我尽可能保证commit记录的可读性,代码里也提供详细的comment,以传承好开源精神。
社区支持
毫不夸张地说,Lepton项目不是闭门造车,它在开发阶段从太阁程序员社区中获得了很大的支持。2016年底时候,社区中的成员1MHz刚发布了他同样基于Electron的作品Knotes,并在社区中分享了他的开发经验,我读后很受启发。向1MHz请教后,他对Lepton的开发提出了很多中肯的建议,尤其是UI库选择和自动更新这两个地方;)
大概两周后,Lepton框架和基本功能初具雏形,我从太阁程序员社区又邀请到了首批内测用户,得到很多有意思的反馈。(尤其感谢meilinzAaronice1MHzhongbojingblukpine
我这次把项目经验总结成文,也是为了对太阁社区回馈:)
技术实现
Lepton所选用的框架是Electron。Electron把Node.js和Chromium两者结合,开发者可以使用JavaScript进行跨平台的桌面APP开发。同时,项目还选用React + Redux来构建前端UI和管理App的状态,并使用Webpack来作为构建工具。

Alt text

下面将讨论一些技术实现上的细节。
代码高亮
Lepton采用Highlight.js
来进行代码的语法高亮。由于Highlight.js
作者很傲娇地不支持line number,我正好利用这个机会学习这技术。下面是最终效果图。

Alt text

代码分行
如上图,代码块放在了一个HTML table中。首先用正则式/\r?\n/
把代码分行,并同时计算每行对应的line number。line number放在上面HTML Table中的第一列,代码放在第二列。使用Table的好处是,当某行代码太长导致一行放不下而被迫折返时,它不会进入line number的列中。下面是不使用Table时可能会遇到的问题。


Alt text

不要复制line number
有时候,我们在网上复制代码时,会碰到误选line number,导致如下图中line number也一同被复制的现象。


Alt text

Lepton的解决方案是采用data-pseudo-content
来标记行数,避免了line number被误选复制的问题,效果妥妥的!

Alt text

下面奉上snippet。详细代码请看这个gist
let lineNumber = 0 const contentTable = adaptedHighlightedContent.split(/\r?\n/).map(lineContent => { return <tr> <td class='line-number' data-pseudo-content=${++lineNumber}></td> <td>${lineContent}</td> </tr> }).join('') // 最后输出:<pre><code><table class='code-table'>${contentTable}</table></code></pre>

Markdown渲染
Lepton采用marked模块进行Markdown渲染(Markdown 转换为 HTML)。感兴趣的话,大家也可以亲自做一款markdown editor!
var marked = require('marked');console.log(marked('I am using markdown.'));// Outputs: <p>I am using <strong>markdown</strong>.</p>

Alt text

React + Redux state
开始时,我曾把一些Dialog的show/hide作为React component的local state来处理。当时我认为它们和app的全局state无关,应该放在component中。后来,随着dialog数目的增多(search/create/edit/delete/logout),属于不同component的dialog出现了相互覆盖、难以协调的现象。最后我不得不把它们改回全局的redux state。这是一点小经验。
标签实现
GitHub Gist本身不支持标签。我一开始想法是通过一个secret gist来保存和同步标签。后来发现这个方法有些问题。
效率不高,每次标签变化都要把所有标签记录重新写入这个secret gist,而且出错后容易丢失记录,最后弃用。
开发者不应该在没有得到用户同意的情况下,私自使用secret gist来存储数据。任何关于gist的改动都应有用户来做决定。

目前方法是通过description部分的特殊字符#tags
来保存自定义的标签。优点是标签分散到每个gist中,每次只需要更新该gist对应部分的标签即可,可以同步到云端。而且它可读性高,即使用户有一天抛弃Lepton转回原生的网页端,也能轻易读懂description的信息。

Alt text

Alt text

UI设计
图标


Alt text

作为程序员,能把图标制作到这个程度我是很满意的了...
Lepton意思是轻子,是指不参与强相互作用的自旋为ћ/2 的费米子,其中电子Electron是最出名的轻子。项目起名Lepton,是对Electron框架的致敬。(这一系列的项目爱用物理粒子起名,比如Electron、Atom、Photon等)
开始时候,曾想用β衰变图(β衰变会产生两种轻子)来作为Lepton图标,可惜总画不好。后来退而求其次,总能画个圆形图案表现出粒子感吧(其实用圆形表示轻子是很不科学的),最后在写轮眼的启发下,有了现在的设计。
图标的制作方法简单、成本低、时间短,但效果不错。具体而言,先用系统自带工具画一个逗号,然后去下面第一个网站把图片转换成svg,然后再去第二个网站把svg文件转换成Material风格的图标。即使来回折腾几遍也就是半小时的事情。
下面奉上网站链接:
http://pngtosvg.com/
https://android-material-icon-generator.bitdroid.de/

界面设计
Lepton的界面几乎没有设计,我很克制地不去添加不必要的元素。
之前做的项目(比如这个,和这个),由于设计过度,到后来已有点驾驭不了。这次吸取经验, 能用Bootstrap原色就用原色,能不添加button就不添加button,能用黑白就不用彩色。这样下来,不仅节省了时间,界面反而被人称赞好看。有时开玩笑,说灵感来自清水混凝土。
CodeMirror
CodeMirror是一款第三方的text editor,提供了很多非常棒的编辑功能。(比如代码块的collapse/expand、语法高亮)

Alt text

来自GitHub社区wujysh在把CodeMirror集成到Lepton上做了非常出色的工作!正是因为有他的贡献,Lepton原来蹩脚的text editor进化为了现在的代码编辑利器。
同时他在对产品的使用和布局上也提出了很多出色的见解;)
本地搜索
Lepton早期曾经使用elasticlunr.js来实现本地搜索。遗憾的是,它目前只支持英文的整词搜索,比较鸡肋。后来我改用了fusejs,华丽丽地支持partial search和中文,搜索功能瞬间满血复活。

Alt text

遗憾的是,Lepton并不支持对代码部分的搜索,具体技术上的原因可以参考这个Issue。目前支持搜索的部分是:description、文件名、tags
自动更新
Electron自带了一个autoUpdater
模块,可以自动检测server上的新版本,并自动在后台下载。
Lepton并没有直接使用自带的autoUpdater
,而是使用electron-builder集成的更新模块。每次release时候,electron-builder会把打包文件以及带有版本信息的meta data文件上传到GitHub的release页面。当Lepton打开时候,它会自动检测release页面上的最新版本信息,若发现有新版本,便会提醒用户下载。
注意,当发布到Mac App Store时候,必须要关闭这些auto updater的功能。
项目推广
说明文档
任何一个GitHub项目都应该有一份完善的说明文档,以方便别人了解这个项目。我个人的习惯是,即使项目做不完,也会把做不完的原因和目前的进度在说明文档上写清楚,做到有始有终。
这是我写说明文档的一些例子:例子1例子2例子3
Lepton的早期成功得益于较为完整的文档,不少用户还对文档内容提出了改进的建议。这里奉上曾经总结过的写说明文档的资源
初次亮相
项目一开始放在了V2EX社区上发布,获得了很不错的反馈,非常感激。在各位热心用户的反馈下,Lepton从最初只支持查看gist的简单客户端,逐步发展成为集 Tag + Search + CRUD 一身的APP。现在可以很不夸张的说,Lepton目前的很多用户体验要优于基于网页客户端的GistBox。
Lepton早期获得的关注帮助它连续好几天进入GitHub的daily trending,这为它吸引了很多国际开发者的关注。(这是我后来才发现的,一开始还很好奇这些国际友人从哪里听说Lepton
开源合作
Lepton在GitHub上获得不少开发者的贡献,下面一并感谢:
wujysh
meilinz
lcgforever
Calinou
rogersachan

后续思考
毫无疑问,这是一个很有趣的经历,不仅仅是积累了很多技术(在开发Lepton过程中,我自己就使用Lepton记录了大量的gist),还在产品上有了更多的思考。
项目开发前两周,我所有注意力都集中到集成GitHub API、完成基本的CRUD功能上,我所关注的是HOW。当进入第四周到第五周,产品核心功能(Tag + Search + CRUD)逐步完善,受到关注越来越多,我更多思考这个项目是什么(WHAT)。我是要把GitHub自带的Gist网页端复制到桌面吗?还是通过Lepton自建一个snippet生态?我们应该如何取舍平衡功能呢?
我的结论是,Lepton要成为能保存代码的印象笔记,姑且理解为“印象代码”。它的终极目的是以开源本身来回馈开源社区;它的直接手段是帮助程序员有效利用收集的点滴智慧(读作dai ma),在抱StackOverflow大腿之余,也能够抱自己大腿。所以,我在新功能的取舍上以下面“三个有利于”作为衡量标准:
是否有利于用户收集代码 (比如引入CodeMirror)
是否有利于用户便捷获取代码 (比如引入Local Search、copy/share button)
是否有利于用户专心分析代码 (比如 Immersive mode)

并且在社区的帮助以及自己时间允许范围内进行。
最后,Lepton这段经历告诉我们,打造一个GitHub上千星项目,过程其实没有那么神秘,重点在于清晰的项目目标和乐于分享的精神。
一点意外的是,有人想到了把Lepton作为一款支持markdown的轻量级“印象笔记”来使用。

致谢
一年前参加了太阁程序员社区,从里面的免费讲座和项目实战中学到很多!这里强力推荐一下!
1MHz 给了很多技术支持,欢迎大家也去参观一下他的Electron作品Knotes
xwartz 的PupaFM详细的commit记录对我学习Electron帮助很大,希望大家去也给这个项目点个赞。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • Product Hunt链接 官网链接 <-- 戳戳我 下载页面 GitHub项目 2017年初,我花了大约三个星...
    Hackjutsu阅读 8,738评论 17 129
  • WebSocket-Swift Starscream的使用 WebSocket 是 HTML5 一种新的协议。它实...
    香橙柚子阅读 22,930评论 8 183
  • LG牌丝瓜蛋面。豆子辅食:蛋黄大米粥。三文鱼鱼泥。宝宝三文鱼接受很好,妈妈也很爱吃三文鱼噢
    银质新月英子阅读 169评论 0 1
  • 武汉每年都下雪,可是今年到现在还没有。 林白每年下雪的时候都送我一条围巾,可是今年没有。 我们相识八年,大学时候林...
    Edvinsen阅读 10,654评论 0 0
  • 每次和斌老板聊天,都让我坚定的认为keep moving是一生需要坚持的事情。我一直都不太深刻理解人的这...
    薛一ZERO阅读 231评论 3 2