ClojureScript

可選的自我託管

此頁面記載了為想要或需要利用 cljs.js/eval-str 和其他自我託管功能的 ClojureScript 專案建構者提供的建議。

如果您正在建構一個最終部署成品的大小至關重要的 Web 應用程式,則不應使用此頁面上概述的任何功能。

生產版本

您可以使用包含 cljs.js 命名空間的版本,最多可以利用 :optimization :simple。其他建議設定:

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

:optimize-constants 對於程式碼大小非常重要,您原始碼中的所有文字關鍵字和符號都將編譯到單個查找表中。

如果您以 Safari / JavaScriptCore 為目標,:static-fns true 尤其重要。(詳情請參閱 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