录个视频解释一下 http://weibo.com/1651843872/EqdyOFWnY?ref=home&rid=1_0_1_2815985669887175627
因为在 Webpack 里热替换用惯了, 所以到 ClojureScript 环境也少不了想要,
本来折腾半天用了 Figwheel 的, 经过几次升级发现配置变动压力很大,
原因是我用的 Boot, 需要额外的插件来处理, 升级经常遇到配置出错的问题, 而且配置真的很长:
所以在 Lumo 发布之后我就在尝试切换到 Lumo, 并且尝试用 Lumo 的热替换.
Lumo 里大致上就是跟 Clojure 差不多的 require
函数的功能, 可以替换模块:
(require 'a.b :reload)
一般我会开启 Lumo 的缓存, 因为编译太慢了, 结果连缓存文件也需要手动清除,
挺麻烦的, 一直就弄成教脚本, 也跟官方提过 Issue, 但官方没这个心思做,
昨天继续尝试了一下, 得到了微信群里同学的帮忙, 扒了一些 Lumo 的源码出来,
最终得到一份关键代码, 可以配合文件更新事件来替换命名空间:
(defn node-eval [{:keys [name source]}]
(.runInThisContext vm source (str (munge name) ".js")))
(defn eval-inside! [st code]
(cljs/eval st code
{:eval node-eval :load @#'lumo.repl/load}
(fn [error]
(println "Error:" error))))
(defn handle-reload! [ns-path]
(let [st (cljs/empty-state)
segment (-> ns-path
(string/replace "-" "_")
(string/replace "." "_SLASH_"))]
(println "Removing:" segment)
(cp.execSync (str "rm -rf .lumo_cache/" segment "*"))
(eval-inside! st `(~'require (quote ~(symbol ns-path)) :reload))
(main/on-jsload!)))
有兴趣玩的话, 完整代码在这边:
https://github.com/Cumulo/cumulo-workflow/tree/master/server
关键两个难点, 一个是 require
参数需要是 symbol
, 这个宏挺难写的, 抄过来的.
另一个是 eval
, 它并不是官方开放出来的 API, 不看源码我都不知道有这玩意,
虽然以后我尝试翻过 Lumo 的源码来着, 也是知难而退了.
能热替换的话… 架构设计得好的话也能跟前端一样玩了.