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 平臺的語言起來, 不鬧翻天才怪.
最後呢, 你想成爲怎樣的開發者, 你選未來成爲哪一個社區的核心開發者那樣的人呢?