> I noticed that if I remove the module for com.foo.common, the code in there gets included in cljs_base.js in the compiler temporary output, but there is no dead code elimination performed there. This may be expected, it just means that I need to declare all my code in modules if I want it minified.
>
>
>
> This is not true. You do not need to declare all your code in modules. It is the presence of ^:export that prevents DCE.
I just want to clarify what I'm seeing. Here is the compiler config with the com.foo.common module removed and the ':depends-on #{:common}' lines removed:
{:optimizations :advanced
:output-dir "resources/assets/js/out"
:modules {
:landing
{:output-to "resources/assets/js/landing.js"
:entries #{com.foo.landing}
}
:editor
{:output-to "resources/assets/js/editor.js"
:entries #{com.foo.editor}
}}}
And here are my cljs files with ^:export on all the functions:
src/cljs/com/foo/common.cljs:
(ns com.foo.common)
(defn ^:export blah [x]
(str "[" x "]"))
src/cljs/com/foo/landing.cljs:
(ns com.foo.landing
(:require [com.foo.common :refer (blah)]))
(defn ^:export land [x]
(str "landing:" (blah x)))
src/cljs/com/foo/editor.cljs:
(ns com.foo.editor
(:require [com.foo.common :refer (blah)]))
(defn ^:export edit [x]
(str "editing:" (blah x)))
When I compile, the landing and editor js files are generated:
resources/assets/js/landing.js:
da("com.foo.landing.land", function(a) {
return[B("landing:"), B(ge(a))].join("");
});
resources/assets/js/editor.js:
da("com.foo.editor.edit", function(a) {
return[B("editing:"), B(ge(a))].join("");
});
There is also a resources/assets/js/out/cljs_base.js file generated in the compiler temporary output with the code from com.foo.common appended at the bottom of a lot of other stuff:
...4700+ lines...
function ge(a) {
return[B("["), B(a), B("]")].join("");
}
da("com.foo.common.blah", ge);
The issue is the 4700+ lines of unused preamble in the cljs_base.js. I guess I was expecting the cljs-base file to simply contain the referenced com.foo.common code and DCE to eliminate the rest of it so I'd have a minimized file with just the code I need that I could load up into the browser.
> Also, about the explicit module dependencies declarations: it seems like it should be possible to automatically generate these by analyzing the namespace metadata. Is there a reason to force this to be explicitly declared instead?
>
>
> As far as I can tell both Thomas Heller & Google have come to the conclusion that only explicit dependencies work reliably. I didn't bother exploring alternatives since I didn't think I would do any better :)
I'm curious about this. Thomas, can you comment on what the issues are? I'm thinking if I scan all the namespaces listed in :entries and collect all of their requires, I should be able to automatically generate the :depends-on for all cljs dependencies. I can understand how arbitrary js/ dependencies may need to be explicitly declared, but any cljs dependencies should be knowable by inspecting the requires metadata on a given namespace.
Thanks,
Edwin