2016 年我在 React 社区就不是很是活跃了, 虽然还会搬运一下新闻, 也密切关注着 Jordan Walke 的消息, 可是对于 React 社区的新技术不多去上手用了. 再说本身搞了 Respo, 今后怼 React 怼 Vue 就有了资本, 脾气固然是更不温顺了. 我自认为是 ClojureScript 社区的成员, 这一点好久都不会变了.webpack
不过, 虽然我写 ClojureScript, 可是我并不用 EMACS, 或者其余 Clojure 用户爱用的 IDE. 从一开始, 个人热情就是 Cirru 的方案, 直接用网页编辑 S-Expression, 再依靠程序生成文本的代码. Clojure 有着强大的宏, 实际上实现起来反而比 JavaScript 不要简单太多了. 因而我这么作了, 搞得我很孤僻的样子.git
最开始 Clojure 社区对我表示赞同和鼓励的人是 Shaun, 他是 Parinfer 的做者. Parinfer 是一个怼 Clojure 代码进行自动格式化的工具, 就像 JavaScript 这边的 Prettier, 虽然当时 Prettier 还没开发呢. Parinfer 发布的时候还上了 Hacker News, 赚了 600+ 点赞. 而后我发如今底下有个 "acknowledgements" 部分, 里面把 Cirru 列进去了:github
Cirru Sepal in Clojure has an interesting approach to inferring Clojure parens from indentation and other syntax sugar—
$
,$ []
,$
{}
and,
.web
那个是早期的 Cirru 的文本的语法, 基于缩进的版本. 由于 Parinfer 发布挺早的. 后来, 到了今年, Shaun 在 Clojure Conj 有个演讲 Inspiring a future Clojure editor with forgotten Lisp UX - Shaun Lebron, 为此他跟我沟通了一遍关于 Cirru 的细节. 虽然由于意外没有深刻的参与, 可是渐渐我发现 Cirru 探索的方向算是获得了他的承认和鼓励, 而且近期又被引用了一次, 此次感受真是美滋滋的了.面试
夏天的时候我对 ClojureScript 真的以为不耐烦了, 忘了具体的肇因, 就是很郁闷. 毕竟等了好久, Webpack 的生态在逐渐增强, 而 ClojureScript 我连一个舒服的打包工具都用不了. 特别是不能生成像 Webpack 那样生成文件名 Hash, 以及作 Code Splitting. 我在冷清的邮件列表开了帖子, 要是英语够好简直想骂街了. 这时候遇到了 Thomas Heller, 跟我解释了半天说办法是有的. 最后我就向他要文档了.npm
当时 shadow-devtools
工具好像只有他一我的在用, 虽然有文档, 可是就像 Webpack, 鬼知道怎么配置啊. 因而我就一直在 Slack 上问他怎么用. 后来也不知道具体怎么发生的, 他直接把项目改为 shadow-cljs
而后开始加我须要的功能. 最先我想的是既然 Webpack 这么强大吗直接用就行了嘛, ClojureScript 编译成 CommonJS, 或者 ES6. thheller 就给了个 CommonJS 兼容的方案, 不过仍是要用 JVM 的 ClojureScript 工具编译. 我想, 总比没有好.json
后面 shadow-cljs 实际上提供了 npm 模块直接安装的, 我就不用配置 JVM 了, 关于这一点我是很意外的. 大概这是很大一个好感的来源吧.
因而最开始我就在 Webpack 里用起了 shadow-cljs 生成的 npm-module 格式代码了. 新项目毕竟坑多的, 不过还好 thheller 真是颇有激情, 我在 GitHub 上开 issues, 常常隔夜就发现他修好了还加上了功能. 这样我反而不抱怨了. 渐渐地他说服了我, shadow-cljs 有不少 Webpack 能作的功能, 好比动态加载, 好比 Code Splitting, 好比监视文件热替换, 我渐渐也转移到他推荐的开发方案上来了.浏览器
那仍是夏天, 挺顺利的. 后来由于我失恋, 又出去处处玩, 有一段时间就没常常上去看他的消息了. 直到后来偶然在 Slack 上聊起来, 他说在对付 npm 模块引用的问题, 他想在用 Webpack 帮助来作 npm 模块的打包, 想了几个月没有好办法. 打算试试其余的打包工具, 我跟他说了下 RequireJS, Browserify 那些破事, 他当时以为挺好, 就想试一试. 惋惜后来问题仍是很棘手, 直到最后我都不清楚他是怎么解决的. 那段时间 ClojureScript 官方编译器也在处理 npm 模块打包的事情, 总以后来是给出了不错的方案了. 因此也就是秋天的事情, 浏览器模式的 ClojureScript 能引用 npm 模块了, 甚至在 shadow-cljs 里还提供了一下私有的方法.mvc
总之事情过了半年, 我对 thheller 也是服了. 若是你查看 npm info shadow-cljs
的话, 除了七八月份他好像也经历了一些傻逼事情之外, 整个 shadow-cljs 几乎天天都在更新. 从最开始的打包工具, 一步步加入了各类 Webpack 当中实现过的先进的开发方案. 我嫌弃报错看不懂, 他因而加上颜色加上提示, 我嫌 JVM 冷启动太慢, 他优化了 server 模式而后说能够更快的, 而后也有了 Webpack 那样的 manifest.json
文件用于打包, 他本身还加上个简单粗暴 CSS 热替换. 这中间他的用户愈来愈多, 更多的功能也被优化起来了. 对我来讲使用体验在追赶 Webpack 了.
起先的时候, 为了方便查询和传播, 我就注意留一些基础的教程和 demo, 写不来就催着 thheller 要文档. thheller 很忙懒得写文档, 但好歹也写了一些. 后来我上 Reddit 挺多的, 因而也帮着推销 shadow-cljs, 顺便对 boot-cljs 和 lein-cljsbuild 追加嘲讽. 安利的人多了, 而后就有人在 Reddit 上问 shadow-cljs 究竟怎么回事, theller 上去回答了, Shaun 跟 thheller 也有联系, 因此也去声援了. 我就以为怼 boot 怼 lein 有望了. 至少从如今起这个山头就立在这了, shadow-cljs 是目前对 JavaScript 开发者最友好, 功能也最完善的 ClojureScript 编译工具.
上半年的时候我还在用着 Stack Editor, 逐渐把存储文件迁移到了 ir.edn
, 作了一些生成定义啦, 查找依赖啦, 各类的优化. 失恋加上离职那段时间有了空闲时间, 忽然想到了一个解决实时协同编辑的一个方案, 好比一个列表, 我给每一个节点生成有序的 id, 支持无限差值, 那么协同编辑冲突就能处理了, 因而集中精力实现了 bisection-key. 虽然基于已有的 Cumulo 同步方案, 重写了整个编辑器, 取名叫作 cumulo-editor.
我当时以为真的是很强大的突破. 就在 SHLUG 的聚会上找人试用, 到了 JSConf 的时候带着 Pad 也给人看了. 本身以为很是得意. 那段时间还录了很多 Cumulo Editor 的视频给人看. 刚开始就想着, 反正我离职了时间不少, 我继续加上功能, 也许还能找到试用的场景. 但是实际状况并无想象当中美好, 我折腾了三周, 没啥效果, 虽然几个朋友给了好评, 可是我连陪我测试的人都没有.
八月份我肠胃炎以后心情更差了. 躲着烦恼去逛了下福建广州, 获得很多别的开导吧, 可是由于晒伤了后来就躲起来不爱见人了. 后面去阿里又面试, 在杭州触景生情, 想一想仍是赖在上海吧. 接着机会就调整节奏回来作 React 了. 不过 React 啊 Vue 啊折腾了几年, 我对 JavaScript 的好感已经没剩多少了, 个人思惟习惯也切换到了 Clojure, 我用 Cirru Editor 写代码的顺畅程度远远高于 JavaScript. 当你本身搞出点东西的时候, 就算去大神鼻子底下装逼, 也是有底气的.
如今 Cumulo Editor 能够很方便地跳转到定义, 快速地搜索和切换函数, 表达式的复制剪切也挺方便的, 以及一些原始的重构功能. 放在不少年轻, 很难想象一个 DOM 编辑器处理代码可以方便到这种程度, 可是如今至少凭借一己之力我作出了点样子来, 并且我能看到后续有更多的改进.
因为编辑器也是依赖 Respo 的, 实际上 Respo 在我我的的场景当中被大量使用了. 所以中间也一直被改进着. 最有效并且明确的改进就是 defcomp
这个 Macro 的引入了, 实际上好比 div
这些标签也是经过 Macro 定义的. 为了批量定义出这些标签也花费了很多的心思. 一开始是 Macro 的调试, 关于 foo.core$macros
这个奇怪的写法我愣是找到 Lumo 做者问了找搞明白问题, 后来还给他们找到 bug 来了.
调试 Macro 须要一些经验, 虽然自己不是很难, 用 expandmacro-1
也足够, 可是一开始会有坑. 好比 symbol 被屡次 evaluate 啦, 好比没有意识到须要 gensym
来避免变量重名啦, 或者 list 被意外处理成 eval 之类的. 通过足够多的例子, 算是那掌握好基本的用法了.
Respo 早一点还有一次大的改进, 就是对 state tree 的方案进行了简化, 或者说改为了半自动半手动的写法. 把原来基于节点定位的 state tree 改为了手动控制结构的 state tree, 致使了大量依赖 Respo 的项目都须要跟着更新. 包括我后来的其余 Respo 上的更改, 好比 list->
, 也致使了不少的工做量.
从夏天开始我就注意到 Respo 相关的代码的适用范围愈来愈广, 在我我的项目当中涉及到的位置也是愈来愈多. 同时个人脚手架当中不断引入来自 shadow-cljs, Respo, Cirru 的更新, 维护的成本居然是愈来愈高. 近期我还打算看一看 Cumulo 项目下有什么能够突破的地方, 须要处理的仓库算是更多了.
我有一些运营 CNode 和 React China 两个论坛的基础的经验, 到了 Clojure 这边少不了论坛, 我比较早拿到了 Clojure China 论坛版主的权限, 可是一直没起来. 我以为是国内人太少. 后来看到国外有个现成的 ClojureVerse, 同样的 Discourse 系统, 因而要来了版主权限, 时不时就上去刷一刷.
在英语社区混的时间长了, 大体就熟悉了规律. 活跃的地方主要是 Clojurians 这个 Slack group. 若是英语好, 勉强是能够混进去的, 只是说时区不同很难聊到一块儿. 而后就是 Reddit/Clojure 这个新闻站了. 虽然貌不惊人, 可是访问量是比较稳定的. 剩下 Twitter 上跟几个社区的核心开发者套近乎, 基本能看到对方发的进展. 几我的当中写博客最勤快的就是 Plank 的做者 Mike Fikes 了. 我甚至怀疑他就是目前 ClojureScript 的主力开发, 由于大量的优化都是看他作的. 并且最近这拨 REPL 的改进, 几乎都是他在引领.
另外还有 Google Groups, 也就是邮件列表. Clojure 的邮件列表还算活跃的, 不过 ClojureScript 的差多了. 再说我也不稀罕这么难用的编辑器和界面. 有好的东西, 就发到 ClojureVerse 上, Markdown, 多开心啊. 并且站长 Plexus 真是挺 nice 的, 解答问题别提多细心了.
并且近期他以为 ClojureVerse 有从新作起来的但愿, 开始准备 Relaunch. 我也是服了他了, 论坛真的活跃起来了, 社区里的大牛好多过来串门的, 不知道他人脉什么状况. 我偶然看到老帖子上提了一下他的经历, 看上去是柏林那边的聚会的组织者... 总之跟国内比比真实牛逼了. 也好吧, 感受有盼头了.
最近 Jordan Walke 真实蠢蠢欲动了, ReasonML 3 真的很抢镜. 以我敏锐的嗅觉看, ClojureScript 的竞争对手上场了. 原本我以为 ClojureScript 此次优化好编译器的体验, npm 的短板也补上, 能痛快点干一脚 JavaScript. 可是前端圈 WebAssembly 之类各类新东西不断, 就没把 ClojureScript 放在眼里. 如今 Reason 3 新语法真的至关亮眼, 比 ClojureScript 传播起来快得多.
我是笃定的 FP 的支持者, ClojureScript 热不起来, 我用 ReasonML 开发也是期待中的, 那么我只能分出精力学 ReasonML 的. 目前 Reason React 只是给出了组件级别漂亮的方案. 等到全局状态和异步操做完善, 估计就须要投入了. TypeScript 虽然牛逼, 可是能有 React 原做者设计的语言更适合 React 吗.
回到 ClojureScript 社区这边的事情, 我既然花费了两年开发了基础组件, 确定是指望可以造成上层建筑的. 我也会努力证实 ClojureScript 在提高开发效率方面有着强大的一面. 也许 Lisp 真的不适合给开发经验不足于是缺乏自律甚至缺乏 FP 理论基础的人玩, 但我已经看到了它强大的一面, 我就要把它掌握下来安利给别人. 再者说, ClojureScript 社区的几个开发者我总算混熟了点, 我知道他们能力多强, 也多有想法. JavaScript 社区虽然强大, 但多的是杂音, 多的是妥协, 很让人纠结. 等 WebAssembly 平台的语言起来, 不闹翻天才怪.
最后呢, 你想成为怎样的开发者, 你选未来成为哪一个社区的核心开发者那样的人呢?