请在2024年Clojure调查问卷!中分享您的看法。

欢迎!请参阅关于页面以获取更多关于此工作方式的信息。

0
ClojureScript

这始于David Nolen在Slack上关于如何https://clojurians.slack.com/archives/C07UQ678E/p1644422895167709的讨论。

现在在编译器警告用户“无法推断目标类型”的地方依赖JS互操作语法以及`^js`,似乎已经变得很常见。同时,使用内置的CLJS函数和宏(如`first`、`seq`、`when-first`等)在JS对象和数组上也不少见——因为它们确实提供了这种支持。

这会导致一个问题,使得向优化构建中引入问题变得非常容易,除非你将`^js`放在每个JS互操作的地方,否则无法防止这些问题。

这在真正依赖互操作性的代码中尤其如此,例如

(defn replace-track-source! [^js playlist track-name src]
  (loop [tracks (.-tracks playlist)]
    (when-first [^js track tracks]
      (if (= (.-name track) track-name)
        (-> (to-audio-buffer src playlist)
            (.then (fn [audio-buffer]
                     (let [audio-buffer (audio-util/normalize-volume audio-buffer)]
                       (set! track -src audio-buffer)
                       (.setBuffer track audio-buffer)
                       (.setCues track 0 (.-duration audio-buffer))
                       (.setPlayout track (doto (Playout. (.-ac playlist) audio-buffer)
                                            (.setVolumeGainLevel (.-gain track))
                                            (.setStereoPanValue (.-stereoPan track))))
                       (.calculatePeaks track (.-samplesPerPixel playlist) (.-sampleRate playlist))
                       (.adjustDuration playlist)
                       (.drawRequest playlist)))))
        (recur (next tracks))))))

上述情况有问题是编译器不会在`track`绑定的前面省略`^js`时进行警告。但是没有这个标签,调用`track`上所有函数的名称将被压缩。

一个可能的解决方案是在CLJS函数在JS对象/数组上使用时不保留`^js`标签时引入一种可选的警告。

我在CLJS 1.11.60上尝试的一个最小可重复示例,使用`clj -M -m cljs.main --optimizations advanced -c app.core`

    (ns app.core)
    
    (set! *warn-on-infer* true)
    
    (defn call-baz [x]
      ;; 提出一个警告。
      (.baz x))
    
    (defn do-stuff [^js items]
      (when-first [item items]
        (js/console.log "about to call doStuff")
        ;; 不发出警告,将被压缩。
        (.doStuff item)))
    
    (do-stuff #js [#js {:doStuff #(js/console.log "doing stuff")}])

1 个答案

0
...