ClojureScript

可选的自托管

此页面记录了针对想要构建 ClojureScript 项目,并想要或需要利用 cljs.js/eval-str 和其他自托管功能的人员的建议。

如果您正在构建一个 web 应用程序,其中部署工件的最终大小非常重要,那么您不应该使用此页面中概述的任何功能。

生产构建

您可以利用包含 cljs.js 命名空间的构建的 :optimization :simple。其他推荐设置

:pretty-print false
:optimize-constants true
:static-fns true

:optimize-constants 对于代码大小很重要,源代码中所有文字关键字和符号都将被编译成一个查找表。

:static-fns true 对于针对 Safari / JavaScriptCore 尤其重要。 (有关详细信息,请参见 CLJS-1381。)

默认情况下,为了便于使用,cljs.js/empty-state 将直接将 cljs.core 的分析缓存转储到 cljs.js 命名空间中。 这将使最终工件的大小增加一倍。 您可以在编译器构建选项中设置 :dump-core false 来禁用此功能。

这意味着您需要自己加载核心分析。 转储核心分析缓存很容易。 在您的 ClojureScript 项目中,加载一个 Clojure REPL 并执行以下操作

(require '[clojure.java.io :as io]
         '[cognitect.transit :as transit])
(import [java.io ByteArrayOutputStream])

(def out-path
  "../../assets/js/cljs/core.cljs.cache.aot.json")
(def out (ByteArrayOutputStream. 1000000))
(def writer (transit/writer out :json))

(def cache
  (read-string
    (slurp (io/resource "cljs/core.cljs.cache.aot.edn"))))

(transit/write writer cache)

(spit (io/file out-path) (.toString out))

然后,在您的 ClojureScript 源代码中,您可以加载此缓存 - 例如,这可能看起来像这样

(def st (cljs.js/empty-state))

;; path to Transit encoded analysis cache
(def cache-url "/assets/js/cljs/core.cljs.cache.aot.json")

(defn main []
  (http/get cache-url
    (fn [json]
      (let [rdr   (transit/reader :json)
            cache (transit/read rdr json)]
        (cljs.js/load-analysis-cache! st 'cljs.core cache)
        ;; ...
        ))))

这种简单的优化消除了大约 2.7mb 的生成的 JavaScript。

原作者:David Nolen