shadow-cljs clojurescript Cookbook


虽然有官网api文档, 虽然有https://cljs.info/cheatsheet/, 虽然有clojure的书和clojure开发经验.但总还是有一些磕磕绊绊.

自己写个cookbook,备查.

1. REPL报错 already started

npx shadow-cljs stop

calva命令里缺乏停止/重启 REPL

只能自己手动停止, 然后再用calva启动一个就OK

2 .用字符串函数名,调用 js定义的window.XXX 函数

应该叫反射吧,不懂.反正搜索半天,都不work

最后这样

(defn get-fn [fn-name]

  (js/eval  (.format "window.%s" fn-name)))

简单说,利用 cljs的js/eval, 用js的eval函数,对"window.XXX"求值,就得到了函数, 然后就可以调用了.  不是利用cljs的机制,而是利用寄生平台js 引擎的机制. 毕竟js也是参考lisp,有eval,比较functional的嘛.

3. shadow-cljs 依赖本地js文件

比如  XXX.min.js   或者自己写的单个js文件.

希望shadow-cljs把这些和自己的cljs一起作为src打包成1个bundle

文件这样放:

src/js 下  assets文件夹下 放别人开发好的js库,   自己写的config.js放点全局变量啥的

shadow-cljs.edn 这样写:

;; shadow-cljs configuration
{:source-paths
 ["src/dev"
  "src/main"
  "src/test"]

 :dependencies
 []
 :dev-http {8080 "public"}
 :builds
 {:frontend
  {:target :browser
   :modules {:main {:init-fn frontend.app/init}
             
             }
  :js-options
   {:resolve {"stomp" {:target :file
                       :file "src/js/assets/stomp.umd.min.js"}
              "config" {:target :file
                        :file "src/js/config.js"}
              }
   }}}
 }

:file的路径注意从工程根目录开始写起

app.cljs里这样写

(ns frontend.app
  (:require
   [frontend.util :refer (console-log)]
   [stomp]
   [config :refer [para_stomp]]
   )
  )

4 js object作为函数参数

图省事,直接吧参数放js里了, 最好还是用js去组装

也有clj->js函数可以吧clojure数据结构转成js object,但没试验.

5 调用js 对象的方法 提示 warning infer XXX

Cannot infer target type in expression (. fnname obj)

尤其是 这个obj 的构造函数是 js里声明, obj 是(new )出来的

要声明这个obj的类型注解

比如new 一个js的对象,然后调用它的方法.

const client_stomp = new Client()

client_stomp.activate()

cljs这样写:

(ns frontend.app
  (:require
   [frontend.util :refer (console-log)]
   [stomp]
   [config :refer [para_stomp]]
   )
  )




(def ^stomp/Client client-stomp) ;增加类型注解



(defn init []
  (console-log "Hello World")
  (console-log para_stomp)
  (set! client-stomp (new stomp/Client para_stomp))
  (console-log client-stomp)
  (aset client-stomp "onConnect" (fn [frame] (console-log "stomp connected")))

  ;; (console-log client-stomp)
  (.activate client-stomp )
  )

声明时必须加上类型注解  ^stomp/Client

相关