VSCode掘金插件:我是怎么样在VSCode中刷掘金的?

·  阅读 2396
VSCode掘金插件:我是怎么样在VSCode中刷掘金的?

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 26 天,点击查看活动详情

快速体验

大概在两年半之前,我开发了一个可以在 VSCode 中刷掘金的插件。
本文主要介绍了这款插件是如何设计并逐渐实现的。
通过 VSCode 扩展商店下载,或者在 VSCode 中搜索掘金,可以快速体验。
image.png

背景

大概在两年半前,我特别爱玩掘金的沸点。于是突发奇想,能不能在 VSCode 中刷掘金呢?
说干就干,于是我花了一个周末的下午开发了 VSCode 掘金插件的第一版,这是第一款可以在 VSCode 中刷掘金的插件。
image.png
开发这个插件有很多原因,主要还是当时的条件允许。

  • 当时我很喜欢刷掘金。
  • 在半国企性质的大集团任职,工作相当不饱和,时间充裕。
  • 对 VSCode 插件技术的探索欲望很强烈。
  • 单身。

这个插件发布之后,深受大家欢迎。
过了将近一年后,也就是在 2021 年前后,我没有继续维护这款插件,由于掘金的 API 升级,导致它不能用了,于是很多人受这个插件的启发,陆续出现了一些新的掘金插件,甚至还有人基于 WebStream 开发了掘金插件,都很优秀。
尽管后面有一些其他的 VSCode 掘金插件出现,但这个插件还是一度被大家认为是官方发布的插件(官方确实有个插件,但功能很少,只提供了文章列表导航链接的功能,通过点击跳转到浏览器)。
后来字节跳动收购了掘金社区,字节跳动的某个技术负责人找我聊怎么样合作、未来的开源规划等等,但是掘金并没有开放接口的打算,虽然聊了几次,但最终不了了之。
image.png
后来我也总结了没办法继续维护这个插件的几个原因:

  • 因为对当时掘金的运营不满意,很长一段时间没有继续玩掘金。
  • 跳槽到互联网公司,一边做架构建设一边管理团队,工作节奏快,处理事情很多,没有太多业余时间。
  • 工作性质有所转型,偏底层、偏架构、偏管理。对 VSCode 插件这种技术提不起兴趣了。
  • 非单身。

刚好和开发插件时的条件全部冲突。
虽然项目停止维护了,但有些事情我还在默默关注,比如:

  • 这个插件在下载量 4000 多的时候这个插件无法继续使用了。但即使如此,此后一年多的时间里,下载量仍然到了 6000 多,涨了 2000 多下载量,平均每天还是有将近 10 个人在下载。说明这仍然是个普遍需求。
  • 停止维护后的一年多里,不断有人在群里、Github、邮件、VSCode 扩展市场询问我插件的情况。为什么这个插件不能用了?

image.png
image.png
image.png

为什么我又要继续维护它?

经过慎重考虑后,我决定继续开发这个插件。
主要原因如下:

  • 我又回到掘金写文章了。
  • 我已经逃离上海,逃离 996,逃离快节奏的互联网公司,来到了环境优美、气候温和的海口。remote 工作,每天不需要通勤,为我节省了很多时间。
  • 我目前的主要工作是维护开源项目、互联网教育和自媒体运营。专注处理这些事情做好并不会花费太多时间。总之都是些创造性和探索性的工作,工作强度远远达不到 996。也是有了很多个人时间。

如果你对我离开掘金这一年多时间在做什么感兴趣,可以阅读这篇文章:一名前端 Leader 的转正述职记录
如果你对前端程序员如何找一份远程工作感兴趣,可以和我交流。我也有分享程序员寻找远程工作的计划。

产品设计

在决定继续维护它之前,我先回顾了之前的产品。
由于掘金的接口和数据结构改动较大,原来的代码几乎都不能用了。
稍微想了想,决定一不做二不休,把整个插件的功能逻辑全部重新设计一遍吧。
所以就开始了产品设计的工作,在产品设计过程中,华为 MatePadPaper 起到了很大的作用,当然没有打广告的意思,确实非常好用。
image.png
最近两年我逐渐不喜欢用纸笔写东西了,原因是写很容易,但保存很难。这些年不断换城市、搬家。很多记录了满满干货和灵感的笔记本不知道遗落到何处去了。
在产品设计阶段,我并没有把大部分功能全部设计完,而是按照优先级,采取小步快跑的节奏,渐进式设计。
当前 2.x 版本只做了文章模块的功能,沸点模块的功能暂时归到下一个版本计划中。

文章列表

文章列表最初的设计是有两种风格的,第一种是列表式,第二种是卡片式。
列表式的灵感来自于 medium。141661165708_.pic_hd.jpg
卡片式的灵感来自于 daily.dev。131661165699_.pic_hd.jpg
最终采用了列表式的展示形式。

文章主题

掘金文章的原始内容是 Markdown 文件,如果渲染到 Web 端需要转换成 HTML。
掘金官方的排版引擎提供了一些主题,但是为了阅读体验的一致性,我没有直接使用掘金官方的主题,而是决定自己开发主题。
当然在社区中关于 Markdown 的主题已经越来越多了,我想能不能直接沿用一些开源主题呢?
答案是可以的。
于是我找到了 typora 的主题
image.png
经过反复挑选,我选择了一个叫做 TailwindCSS 的主题作为默认主题。
后续我还考虑提供多套主题,由用户自己选择自己的主题,而不用必须使用作者选择的主题,这是掘金官方不具备的功能,同时这也是我自己的一个需求。这样自由度相对会高一些。

功能特性

在细节上,功能点非常多,比如禅模式、聊天模式等。
除了目前具备的功能特性以外,我还设计了其他特性。
比如离线功能,优化阅读器体验等。我有多年做 Web 阅读器的经验,所以对如何做好 Web 阅读体验有比较深刻的认识。
161661233356_.pic_hd.jpg171661233361_.pic_hd.jpg
我还增加了实时聊天功能,增加了交互性,降低了阅读时的孤独感。
191661278723_.pic_hd.jpg
包括自动签到、自动抽奖功能。
201661278729_.pic_hd.jpg
重新开始设计开发插件是 8 月 3 号,这篇文章是 8 月 8 号开始写的。
image.png
最初只是在写一些设计上的构思和技术上的实现,没打算发出来。那时还没有计划做自动签到和自动抽奖功能,21 天过去了,很多原本只是处于设计状态的功能已经被实现出来了。自动签到和自动抽奖也已经悄悄上线。
包括最近有朋友提议的搜索功能。
7301661222683_.pic.jpg
也已经在设计和开发过程中了。
221661278742_.pic_hd.jpg

重新设计架构

聊完产品设计,再来聊聊我是如何重新设计 VSCode 掘金插件架构的。

交互协议

首先在讲新架构的设计之前,先来回顾一下老的架构是什么样子。
老的架构是典型的事件驱动模式,没有什么数据流的概念,客户端监听一堆事件,服务端监听一堆事件。客户端和服务端收发事件和处理事件的位置散落在代码的各个角落。非常不利于追踪数据变化和 Debugger,对维护来说也是一件非常麻烦的事情。
这次我吸取了教训,我决定采用一种稳定的数据流模型来管理数据,所以我借鉴了的近代前端数据流鼻祖 flux 的模式。它看上去是这样的。
151661165931_.pic_hd.jpg
这样一来,数据的变化和对应的逻辑会变得更加清晰和集中。对 Debugger 和维护来说是更加容易的。
但它也并非毫无缺点,由于这种架构和 Redux 非常相似,所以需要定义一堆 Action Type,在写代码时会出现很多冗余的模板代码。而且还是一种事件驱动模式,我在下一步的迭代计划中打算利用 Promise 将它们改造成“伪请求响应”模型。
整个页面渲染的逻辑是这样的。
181661233365_.pic_hd.jpg

前端页面

在前端页面上,我一直没有在 WebView 中使用框架,因为我觉得这个插件的 UI 部分应该不会太复杂,没必要引入任何框架。
因为代码量比较少,为了能够让 ES6 降级到 ES5,我甚至都没有任何打包工具,而是自己用 Node.js 写了个简易的构建脚本简单处理了一下。
这一切似乎没什么问题。
在刚开始开发的时候,功能很简单,代码也很少,因为它只有一个刷沸点的功能。但是后来随着功能越来越多,评论、纯净模式、文章模块、Loading 组件等等。代码越来越多,也越来越复杂。
后来我就一直在想,可不可以用 React 来开发前端页面呢?想归想,但是一直没有付诸行动。因为有历史的教训,这次我要直接用 React 作为前端框架了!
经过一晚上的折腾,我跑通了在 VSCode 的 WebViwe 中运行 React 的最简单例子。消除了在未来功能迭代时的后顾之忧。

设计和开发过程的工具及框架

首先我要感谢如今近乎完美的互联网软件生态,让我可以聚焦我的产品,而不需要过度关注技术细节。
在这里我打算从头到尾梳理一下开发这款插件所用到的工具和框架,不限于软件、硬件、工具和框架。其实开发其他类型的软件也会用到其中的大部分。

硬件

  • 华为 Matepad Paper:画图神器,当大脑突然产生灵感的时候,快速画出来。它有一个对手是 remarkable 2。在书写上 remarkable 2 更具优势,但是 Matepad Paper 的功能更强大,我还会用它来看书。

软件

  • VSCode:负责开发和调试的 IDE,微软的好产品之一。
  • Figma:做图神器,流程图、原型图、设计稿、Icon 都可以用它来做,由于高交互体验、轻量级、跨平台、高性能等特点,基本上已经秒杀 sketch、axure 和蓝湖等一众软件。

平台/工具

  • dribbble.com/:世界最顶级的设计网站之一,我的很多设计灵感都来自这个网站。
  • www.iconfont.cn/:阿里的免费图标库和字体库。
  • play.tailwindcss.com/:这个网站是 tailwindcss 的 playground,我都是直接用它来编写 UI。
  • github:云上托管代码,没什么好说的。
  • stackoverflow:开发过程中很多问题都是在这里找到的答案。
  • medium:这上面有很多 VSCode 插件开发相关的分享,给了我很多帮助。
  • typora:这上面的主题给了我很多灵感。

框架/库

  • yeoman:脚手架生成器,开发 VSCode 插件初始化项目脚手架时会用到它。
  • TypeScript:增强 JavaScript 的利器,微软的好产品之一。
  • React:UI 库,没什么好多说的。
  • TailwindCSS:CSS 库,没什么好说的。
  • Webpack:打包器,没什么好说的。
  • eslint:代码 lint 工具,没什么好说的。
  • npm-run-all:脚本工具,没什么好说的。
  • esbuild:用来打包 VSCode 源码的工具,没什么好说的。
  • vsce:用来发布 VSCode 插件的工具,没什么好说的。
  • markdown-it:用来渲染 markdown 的工具,没什么好说的。另一个不错的选择是 marked。
  • highlight.js:用来高亮代码的工具,没什么好说的。另一个不错的选择是 prismjs。
  • cheerio:用来操作 DOM 的工具,没什么好说的。另一个不错的选择是 parse5。

插件开发时的问题记录

如何渲染掘金网站的文章内容?

掘金的网站重构过一次,渲染模式和以前服务端直出不一样了,现在的技术栈是 Nuxt.js,采用流式渐进式渲染。
也就是说,我们直接使用 GET 请求文章 URL 返回的 HTML 中是无法直接获取到 DOM 的。HTML 中只有 Loading 的骨架屏,等 markdown 渲染完成后替换骨架屏。
直接返回的 HTML DOM 结构会包含很多 script,通过运行这些脚本来实现客户端渲染 Markdown。
在第一个 script 中定义了一个对象,对象中包含原始 markdonw,属性的路径是:window.NUXT.state.view.column.entry.article_info.mark_content。
使用 Node.js 的 vm 模块就可以运行并获取到它,然后把原始 markdown 交给 markdown-it 就可以实现渲染。

依赖问题

我本来想用全新版本的 VSCode 模板重新开发项目时,意外发现安装依赖失败了。
主要是 @types/vscode 这个包。
因为在 yeoman 模板中它需要的版本是 1.70.0,但是在 npm 中,它的最新版本是 1.69.0。微软也会犯这种问题呀。于是我手动把依赖降级,顺利安装成功。
不过第二天微软就更新了 npm 包。
代码模板和 npm 发包同步是个问题。
后来考虑到有些同学是使用旧版本的 VSCode,所以我决定不升级依赖版本,还是使用原来的模板。
于是 clone 了 github 上的代码。
可是安装依赖又出现问题了!
它卡在这个位置,无论我怎么重新尝试,它始终卡在这里。
image.png
后来在 stackoverflow 中查到了问题。
stackoverflow.com/questions/6…
于是我把 npm 降级为 6.x,安装成功。

postMessage 注意事项

WebView 和 Node.js 进行通信,只能依靠 postMessage。但是 postMessage 只可以传递标准的 JSON,不可以传递 JS 对象,比如不能传递 Funciton。

acquireVsCodeApi 多次调用

acquireVsCodeApi 不可以调用超过一次,否则会报错。

无法引入外部资源

HTML 中有一个 meta http-equiv="Content-Security-Policy" 标签,它的 Content 属性决定了可以导入哪些资源。如果要使用外部资源,要在这里进行配置。

WebView 切换到后台后重新激活会刷新

因为一个 WebView 大概会占用 VSCode 50M 的内存损耗,所以 VSCode 会在 WebView 进入后台时销毁它。
解决方案是把 retainContextWhenHidden 设置为 true 就可以了。
同样是在 stackoverflow 中找到的答案:stackoverflow.com/questions/7…

tsc 编译问题

使用 tsc 进行编译,偶尔会出现 module is not found 'xxx' 的错误,我估计是版本问题,暂时没有找到具体原因。
换成 es-build 顺利解决了这个问题。

其他问题

其实 VSCode 插件在开发过程中还有非常多的细节问题,毕竟没有 Web 应用那么稳定和拥有更丰富的资料。碰到问题还是需要靠自己多去尝试,这很考验一个人的耐心。
原本我有意写一个关于 VSCode 插件开发系列的文章,但又感觉受众并不广泛。加上还有很多更重要的事情要做,所以这件事就暂且搁置了。如果有在开发 VSCode 插件的掘友,也可以和我交流。

感受

在决定做 VSCode 掘金插件后,我没有把它当作一个玩具,而是把它视作一个产品。
开发一个全新的产品是非常令人兴奋的。虽然在职业的细分方向上我是个偏前端的架构师,但实际上我对自身的定位是一个独立开发者,我没有给自己设限,不然我也不可能成长的这么快。所以我的技术栈不会区分某个端,也就是俗称的全栈工程师。只要产品有必要,API、数据库、缓存中间件、搜索引擎这些都不在话下。如果讲的更客观些,我还是个产品经理和 UI 设计师,因为我也会使用 Figma 制作原型、设计稿和 Icon;会用稿定设计制作插图。产品设计和 UI 设计部分也是我非常喜欢做的事。
产生灵感,将它设计成产品,再把它实现出来,这个过程非常令人愉悦。
我希望有更多做技术的同学可以具备产品意识。人的一生,其实就是一个产品,技术是其中的一部分,但绝对不是全部。不要误解我的意思,我没有说技术不重要。
很多人认为好的产品是能盈利的、是能赚钱的,这样太俗气了些。
开源产品并不能赚钱,这样可以让我们更好的回归到产品意义的本身上来:产品是用来为人提供便利的。
我相信 VSCode 掘金插件可以改善一部分人的体验,哪怕只有一点,对它来说,是价值的体现;对我来说,是一种进步与喜悦。
最后,我很喜欢掘金这个平台,希望它可以越做越好。同时也希望广大掘友能够多多参与这个平台的建设,自己受益的同时,也对平台做出些贡献。

收藏成功!
已添加到「」, 点击更改