Clojurescript 死代码消除显然不起作用
Clojurescript dead-code elimination apparently not working
我有一个 ClojureScript 项目,其中包含以下准系统前端应用程序(main
是入口点):
(ns shadowman.app
(:require
;; [cljs-http.client :as http]
;; [reagent.core :as r]
))
(defn main
""
[]
(js/console.log "hi from browser"))
这编译为预期的 95.2 kB。一旦我取消注释 [cljs-http.client :as http]
总跳到 299,7 kB;包括 reagent
进一步增加到 457.4 kB。 因为我没有从这些命名空间调用任何函数,所以 Google Closure 编译器不应该将它们作为死代码消除吗?
我的 shadow-cljs.edn 的相关部分如下:(仅省略其他三个构建,我可能会提到,它们确实使用了被注释掉的库):
{:source-paths [;; "env/prod"
"src/server" "test" "src/browser" "src/common" "src/plibs" "target/classes"]
:dependencies [[reagent "0.9.1"]
[bidi "2.1.6"]
[com.taoensso/timbre "4.10.0"]
;; [org.clojure/clojurescript "1.10.520"]
[macchiato/hiccups "0.4.1"]
[macchiato/core "0.2.16"]
[macchiato/env "0.0.6"]
[mount "0.1.16"]
;; [cljs-ajax "0.8.0"]
[cljs-http "0.1.46"]
[hickory "0.7.1"]
;; [markdown-to-hiccup "0.6.2"]
]
;; :dev-http {3001 "public"}
:builds {
:spa-prod
{
:target :browser
:output-dir "public/js/compiled"
:asset-path "/js/compiled"
:modules {:app-comp {:init-fn shadowman.app/main}}
:compiler-options
{:optimizations :advanced
}}
}}
我通过 运行 shadow-cljs release spa-prod
得到上面的数字。除非我对消除死代码的期望有误,否则这张图片有问题。如果是这样,我将不胜感激任何关于如何调查它的想法。
您可以生成一个 build report 来了解您的最终构建包含的内容。
shadow-cljs 和 Closure 编译器不会为构建所需的 npm 依赖项执行 DCE。一旦包含它们,就只完成基本的 DCE(即 :simple
),这不能完全消除代码。这样做是因为 :advanced
打破了太多的 npm 依赖关系。所以在 reagent
的情况下,它最终会默认包括 react
和 react-dom
即使 reagent
是也不会被消除。
但这并不限于 npm 依赖项。并非所有 CLJS 代码甚至 Closure Library 代码都可以完全消除。一些代码模式只是阻止 DCE 启动。一个例子是无法删除的任何 defmulti/defmethod
。
我有一个 ClojureScript 项目,其中包含以下准系统前端应用程序(main
是入口点):
(ns shadowman.app
(:require
;; [cljs-http.client :as http]
;; [reagent.core :as r]
))
(defn main
""
[]
(js/console.log "hi from browser"))
这编译为预期的 95.2 kB。一旦我取消注释 [cljs-http.client :as http]
总跳到 299,7 kB;包括 reagent
进一步增加到 457.4 kB。 因为我没有从这些命名空间调用任何函数,所以 Google Closure 编译器不应该将它们作为死代码消除吗?
我的 shadow-cljs.edn 的相关部分如下:(仅省略其他三个构建,我可能会提到,它们确实使用了被注释掉的库):
{:source-paths [;; "env/prod"
"src/server" "test" "src/browser" "src/common" "src/plibs" "target/classes"]
:dependencies [[reagent "0.9.1"]
[bidi "2.1.6"]
[com.taoensso/timbre "4.10.0"]
;; [org.clojure/clojurescript "1.10.520"]
[macchiato/hiccups "0.4.1"]
[macchiato/core "0.2.16"]
[macchiato/env "0.0.6"]
[mount "0.1.16"]
;; [cljs-ajax "0.8.0"]
[cljs-http "0.1.46"]
[hickory "0.7.1"]
;; [markdown-to-hiccup "0.6.2"]
]
;; :dev-http {3001 "public"}
:builds {
:spa-prod
{
:target :browser
:output-dir "public/js/compiled"
:asset-path "/js/compiled"
:modules {:app-comp {:init-fn shadowman.app/main}}
:compiler-options
{:optimizations :advanced
}}
}}
我通过 运行 shadow-cljs release spa-prod
得到上面的数字。除非我对消除死代码的期望有误,否则这张图片有问题。如果是这样,我将不胜感激任何关于如何调查它的想法。
您可以生成一个 build report 来了解您的最终构建包含的内容。
shadow-cljs 和 Closure 编译器不会为构建所需的 npm 依赖项执行 DCE。一旦包含它们,就只完成基本的 DCE(即 :simple
),这不能完全消除代码。这样做是因为 :advanced
打破了太多的 npm 依赖关系。所以在 reagent
的情况下,它最终会默认包括 react
和 react-dom
即使 reagent
是也不会被消除。
但这并不限于 npm 依赖项。并非所有 CLJS 代码甚至 Closure Library 代码都可以完全消除。一些代码模式只是阻止 DCE 启动。一个例子是无法删除的任何 defmulti/defmethod
。