如何防止闭包编译器缩小 clojurescript 中的某些方法?
How can I prevent the closure compiler from minifying certain methods in clojurescript?
我正在将 quilljs 与我的 clojurescript 应用程序集成。我将它包含在我的 project.cljs 文件中,如下所示:[cljsjs/quill "1.3.5-0"]
。
编译器正在缩小某些方法并导致错误:
function xA(a, b) {
var c = t(a).getSelection(!0)
, d = c.index
, e = c.length
, h = Quill.import("delta");
c = function(b, c, d, e) {
return function(b) {
return t(a).updateContents((new e).rf(c).delete(d).nf({
image: b
}))
}
}(c, d, e, h);
return b.c ? b.c(c) : b.call(null, c)
}
这是错误:Uncaught TypeError: (intermediate value).rf is not a function
clojurescript 代码如下所示:
(defn file-recieve-handler [this cb]
(let [range (.getSelection @this true)
index (.-index range)
length (.-length range)
delta (.import js/Quill "delta")]
(cb (fn [url]
(.updateContents @this
(.insert
(.delete
(.retain (new delta) index)
length)
#js {:image url}))))))
retain
方法和 insert
方法正在缩小 - 他们不应该这样。 (删除不是出于某种原因,我猜那是因为它是 javascript 中的关键字。)
我找到了 quilljs 的外部文件:
https://github.com/cljsjs/packages/blob/master/quill/resources/cljsjs/quill/common/quill.ext.js
我是否需要以某种方式补充外部文件或我可以编写代码的其他方式,以便在为编译器打开高级编译时这两种方法不会被缩小?
对于某些上下文,下面是完整文件。它基于此 https://github.com/benhowell/reagent-quill/blob/master/quill.cljs
(ns quill.core
(:require
[reagent.core :as r]))
(defn quill-toolbar [id]
[:div {:id (str "quill-toolbar-" id)}
[:span {:class "ql-formats"}
[:select {:class "ql-header"}
[:option {:value "1"}]
[:option {:value "2"}]
[:option {:value "3"}]
[:option {:value "4"}]
[:option {:value "5"}]
[:option]]]
[:span {:class "ql-formats"}
[:select {:class "ql-font"}
[:option]
[:option {:value "serif"}]
[:option {:value "monospace"}]]]
[:span {:class "ql-formats"}
[:select {:class "ql-size"}
[:option {:value "small"}]
[:option]
[:option {:value "large"}]
[:option {:value "huge"}]]]
[:span {:class "ql-formats"}
[:button {:class "ql-bold"}]
[:button {:class "ql-italic"}]
[:button {:class "ql-underline"}]
[:button {:class "ql-strike"}]
[:button {:class "ql-blockquote"}]]
[:span {:class "ql-formats"}
[:select {:class "ql-align"}]]
[:span {:class "ql-formats"}
[:button {:class "ql-script" :value "sub"}]
[:button {:class "ql-script" :value "super"}]]
[:span {:class "ql-formats"}
[:button {:class "ql-indent" :value "-1"}]
[:button {:class "ql-indent" :value "+1"}]]
[:span {:class "ql-formats"}
[:button {:class "ql-image"}] ]
[:span {:class "ql-formats"}
[:select {:class "ql-color"}]
[:select {:class "ql-background"}]]
[:span {:class "ql-formats"}
[:button {:class "ql-clean"}]]])
(defn file-recieve-handler [this cb]
(let [range (.getSelection @this true)
index (.-index range)
length (.-length range)
delta (.import js/Quill "delta")]
(cb (fn [url]
(.updateContents @this
(.insert
(.delete
(.retain (new delta) index)
length)
#js {:image url}))))))
(defn editor [{:keys [id value selection on-change image-handler]}]
(let [this (r/atom nil)
get-value #(aget @this "container" "firstChild" "innerHTML")
string-id (if (keyword? id) (name id) id) ]
(r/create-class
{:component-did-mount
(fn [component]
(reset! this
(js/Quill.
(aget (.-children (r/dom-node component)) 1)
#js {:modules #js {:toolbar (aget (.-children (r/dom-node component)) 0)}
:theme "snow"
:scrollingContainer (str "quill-wrapper-" string-id)
:placeholder "Compose an epic..."}))
(.on @this "text-change"
(fn [delta old-delta source]
(on-change source (get-value))))
; FYI this is another area I had trouble. I got around it using
; get and set in the goog.object
(let [toolbar (.getModule @this "toolbar")
handlers (goog.object/get toolbar "handlers")]
(goog.object/set handlers "image" #(file-recieve-handler this image-handler)))
(if (= selection nil)
(.setSelection @this nil)
(.setSelection @this (first selection) (second selection) "api")))
:component-will-receive-props
(fn [component next-props]
(if
(or
(not= (:value (second next-props)) (get-value))
(not= (:id (r/props component)) (:id (second next-props))))
(do
(if (= selection nil)
(.setSelection @this nil)
(.setSelection @this (first selection) (second selection) "api"))
(.pasteHTML @this (:value (second next-props))))))
:display-name (str "quill-editor-" string-id)
:reagent-render
(fn []
[:div {:id (str "quill-wrapper-" string-id) :class "quill-wrapper"}
[quill-toolbar string-id]
[:div {:id (str "quill-editor-" string-id)
:class "quill-editor"
:dangerouslySetInnerHTML {:__html value}}]])})))
(defn display-area [{:keys [id content]}]
(let [this (r/atom nil)]
(r/create-class
{:component-did-mount
(fn [component]
(reset! this (js/Quill. (r/dom-node component)
#js {:theme "snow"
:modules #js {:toolbar false}
:placeholder ""}))
(.disable @this))
:component-will-receive-props
(fn [component next-props]
(.pasteHTML @this (:content (second next-props))))
:display-name (str "quill-display-area-" id)
:reagent-render
(fn []
[:div {:id (str "quill-display-area-" id)
:class "quill-display-area"
:dangerouslySetInnerHTML {:__html content}}])})))
您可以打开外部推理警告,编译器会告诉您可能会重命名的内容。
;; in the actual ns
(set! *warn-on-infer* true)
;; in the build config compiler options
:infer-externs true
见https://clojurescript.org/guides/externs#externs-inference
为了帮助调试重命名问题,您可以在编译器选项中打开 :pseudo-names true
。这将使找出哪些方法被重命名以及可能需要 ^js
typehint 或手动 externs 变得更容易。
我按照@thomas-heller 的建议使用了类型提示并且它起作用了。我把原来的功能分成了两个独立的功能。这里重写:
(defn add-image [^js/Quill quill ^js/Quill.imports.delta delta index length url]
(.updateContents quill
(.insert
(.delete
(.retain delta index)
length)
#js {:image url})))
;https://github.com/quilljs/quill/pull/995/files#diff-6dafc0fe6b5e9aed0859eef541e68372
(defn file-recieve-handler [^js/Quill quill cb]
(let [range (.getSelection quill true)
index (.-index range)
length (.-length range)
delta (new (.-delta (.-imports js/Quill)))]
(cb (fn [url]
(add-image quill delta index length url)))))
我正在将 quilljs 与我的 clojurescript 应用程序集成。我将它包含在我的 project.cljs 文件中,如下所示:[cljsjs/quill "1.3.5-0"]
。
编译器正在缩小某些方法并导致错误:
function xA(a, b) {
var c = t(a).getSelection(!0)
, d = c.index
, e = c.length
, h = Quill.import("delta");
c = function(b, c, d, e) {
return function(b) {
return t(a).updateContents((new e).rf(c).delete(d).nf({
image: b
}))
}
}(c, d, e, h);
return b.c ? b.c(c) : b.call(null, c)
}
这是错误:Uncaught TypeError: (intermediate value).rf is not a function
clojurescript 代码如下所示:
(defn file-recieve-handler [this cb]
(let [range (.getSelection @this true)
index (.-index range)
length (.-length range)
delta (.import js/Quill "delta")]
(cb (fn [url]
(.updateContents @this
(.insert
(.delete
(.retain (new delta) index)
length)
#js {:image url}))))))
retain
方法和 insert
方法正在缩小 - 他们不应该这样。 (删除不是出于某种原因,我猜那是因为它是 javascript 中的关键字。)
我找到了 quilljs 的外部文件: https://github.com/cljsjs/packages/blob/master/quill/resources/cljsjs/quill/common/quill.ext.js
我是否需要以某种方式补充外部文件或我可以编写代码的其他方式,以便在为编译器打开高级编译时这两种方法不会被缩小?
对于某些上下文,下面是完整文件。它基于此 https://github.com/benhowell/reagent-quill/blob/master/quill.cljs
(ns quill.core
(:require
[reagent.core :as r]))
(defn quill-toolbar [id]
[:div {:id (str "quill-toolbar-" id)}
[:span {:class "ql-formats"}
[:select {:class "ql-header"}
[:option {:value "1"}]
[:option {:value "2"}]
[:option {:value "3"}]
[:option {:value "4"}]
[:option {:value "5"}]
[:option]]]
[:span {:class "ql-formats"}
[:select {:class "ql-font"}
[:option]
[:option {:value "serif"}]
[:option {:value "monospace"}]]]
[:span {:class "ql-formats"}
[:select {:class "ql-size"}
[:option {:value "small"}]
[:option]
[:option {:value "large"}]
[:option {:value "huge"}]]]
[:span {:class "ql-formats"}
[:button {:class "ql-bold"}]
[:button {:class "ql-italic"}]
[:button {:class "ql-underline"}]
[:button {:class "ql-strike"}]
[:button {:class "ql-blockquote"}]]
[:span {:class "ql-formats"}
[:select {:class "ql-align"}]]
[:span {:class "ql-formats"}
[:button {:class "ql-script" :value "sub"}]
[:button {:class "ql-script" :value "super"}]]
[:span {:class "ql-formats"}
[:button {:class "ql-indent" :value "-1"}]
[:button {:class "ql-indent" :value "+1"}]]
[:span {:class "ql-formats"}
[:button {:class "ql-image"}] ]
[:span {:class "ql-formats"}
[:select {:class "ql-color"}]
[:select {:class "ql-background"}]]
[:span {:class "ql-formats"}
[:button {:class "ql-clean"}]]])
(defn file-recieve-handler [this cb]
(let [range (.getSelection @this true)
index (.-index range)
length (.-length range)
delta (.import js/Quill "delta")]
(cb (fn [url]
(.updateContents @this
(.insert
(.delete
(.retain (new delta) index)
length)
#js {:image url}))))))
(defn editor [{:keys [id value selection on-change image-handler]}]
(let [this (r/atom nil)
get-value #(aget @this "container" "firstChild" "innerHTML")
string-id (if (keyword? id) (name id) id) ]
(r/create-class
{:component-did-mount
(fn [component]
(reset! this
(js/Quill.
(aget (.-children (r/dom-node component)) 1)
#js {:modules #js {:toolbar (aget (.-children (r/dom-node component)) 0)}
:theme "snow"
:scrollingContainer (str "quill-wrapper-" string-id)
:placeholder "Compose an epic..."}))
(.on @this "text-change"
(fn [delta old-delta source]
(on-change source (get-value))))
; FYI this is another area I had trouble. I got around it using
; get and set in the goog.object
(let [toolbar (.getModule @this "toolbar")
handlers (goog.object/get toolbar "handlers")]
(goog.object/set handlers "image" #(file-recieve-handler this image-handler)))
(if (= selection nil)
(.setSelection @this nil)
(.setSelection @this (first selection) (second selection) "api")))
:component-will-receive-props
(fn [component next-props]
(if
(or
(not= (:value (second next-props)) (get-value))
(not= (:id (r/props component)) (:id (second next-props))))
(do
(if (= selection nil)
(.setSelection @this nil)
(.setSelection @this (first selection) (second selection) "api"))
(.pasteHTML @this (:value (second next-props))))))
:display-name (str "quill-editor-" string-id)
:reagent-render
(fn []
[:div {:id (str "quill-wrapper-" string-id) :class "quill-wrapper"}
[quill-toolbar string-id]
[:div {:id (str "quill-editor-" string-id)
:class "quill-editor"
:dangerouslySetInnerHTML {:__html value}}]])})))
(defn display-area [{:keys [id content]}]
(let [this (r/atom nil)]
(r/create-class
{:component-did-mount
(fn [component]
(reset! this (js/Quill. (r/dom-node component)
#js {:theme "snow"
:modules #js {:toolbar false}
:placeholder ""}))
(.disable @this))
:component-will-receive-props
(fn [component next-props]
(.pasteHTML @this (:content (second next-props))))
:display-name (str "quill-display-area-" id)
:reagent-render
(fn []
[:div {:id (str "quill-display-area-" id)
:class "quill-display-area"
:dangerouslySetInnerHTML {:__html content}}])})))
您可以打开外部推理警告,编译器会告诉您可能会重命名的内容。
;; in the actual ns
(set! *warn-on-infer* true)
;; in the build config compiler options
:infer-externs true
见https://clojurescript.org/guides/externs#externs-inference
为了帮助调试重命名问题,您可以在编译器选项中打开 :pseudo-names true
。这将使找出哪些方法被重命名以及可能需要 ^js
typehint 或手动 externs 变得更容易。
我按照@thomas-heller 的建议使用了类型提示并且它起作用了。我把原来的功能分成了两个独立的功能。这里重写:
(defn add-image [^js/Quill quill ^js/Quill.imports.delta delta index length url]
(.updateContents quill
(.insert
(.delete
(.retain delta index)
length)
#js {:image url})))
;https://github.com/quilljs/quill/pull/995/files#diff-6dafc0fe6b5e9aed0859eef541e68372
(defn file-recieve-handler [^js/Quill quill cb]
(let [range (.getSelection quill true)
index (.-index range)
length (.-length range)
delta (new (.-delta (.-imports js/Quill)))]
(cb (fn [url]
(add-image quill delta index length url)))))