Hello,
I’m trying to use code splitting in my CLJS codebase to separate app code from trackers (think Google Analytics), so that trackers code are not part of the base module and are lazy loaded on-demand only. Good idea, right ?
Our strategy so far (without code splitting) is to write the small javascript tracker code in Javascript files with Google Closure in mind (goog.provide()
, goog.require()
etc.) to seamlessly package them an call them from CLJS. So far so good. Works perfectly, already in production for a long time.
Problems appear when I decided to code split them. Basically the split tracker module code is in the main app code split (cljs_base.js
), and the tracker module split (google_analytics.js
) is empty…
Below the details:
Env
- Linux
- Boot 2.7.1 with boot-cljs 2.1.4
- Clojure 1.9
- ClojureScript 1.9.946
- Java 8
Compiler options
{:main "yoda.core"
:libs ["trackers/google_analytics.js"] ;; lots of trackers here in Javascript
:modules {:google-analytics {:entries '#{yoda.tracking.google-analytics} ;; CLJS wrapper around the tracker above so that we can call `loader/set-loaded! :google-analytics)`
:output-to "js/google-analytics.js"}}
:asset-path "/yd/js/main.out"
:optimizations :simple
:source-map true
:parallel-build true
:verbose true}
CLJS wrapper code
(ns yoda.tracking.google-analytics
(:require [cljs.loader :as loader]
[trackers.google-analytics :as ga]))
(defn start [ga-tracking-id entity]
(ga/start ga-tracking-id entity))
(loader/set-loaded! :google-analytics)
Lazy loading
(loader/load :google-analytics
(fn []
((resolve 'yoda.tracking.google-analytics/start) ga-tracking-id entity)))
With the :verbose true
option, the CLJS compiler seems to behave well:
Building module :google-analytics
# lot of entries...
adding entry [trackers.google-analytics]
adding entry (yoda.tracking.google-analytics)
module :google-analytics depends on :cljs-base
The browser console shows it’s working :
log:Module loaded: cljs_base
log:Module loaded: google_analytics
The problem
- There’s no network request to load
google_analytics.js
-
google_analytics.js
is an empty file (contains only the source-map comment//# sourceMappingURL=google-analytics.js.map
) -
cljs_base.js
contains everything, including the namespaceyoda.tracking.google-analytics
It seems to be related to cross module code motion, but I don’t understand why it produces this result. I think I’ve followed the official guide on Code Splitting to the letter.
Do you see where I’m wrong ?
Thanks in advance !
PS: I first posted in the official CLJS mailing list, but it seems that posts require approval first, so I posted here too in the meantime (had to rewrite it! no draft! arghh!). Sorry for the cross posting.