I want to compile my .cljs
file for both browser and node.js environments, to get server side rendering. As I understand, there's no way to define cljs env in compile time with reader macro conditions like:
#?(:clj ...)
#?(:cljs ...)
so, I can't easily tell compiler to process something like #?(:cljs-node ...)
in node.js env.
Second option I see here is to develop a macro file which will define env at compile time. But how to define that current build is targeting node.js? May be, I could pass some params somehow to compiler or get :target
compiler param?
Here are my boot files:
application.cljs.edn:
{:require [filemporium.client.core]
:init-fns [filemporium.client.core/init]}
application.node.cljs.edn:
{:require [filemporium.ssr.core]
:init-fns [filemporium.ssr.core/-main]
:compiler-options
{:preamble ["include.js"]
:target :nodejs
:optimizations :simple}}
I am not aware of a public API to achive this. However, you might use cljs.env/*compiler*
dynamic var in your macro to check the target platform (i.e. NodeJS vs browser) configured with :target
in your :compiler-options
and either emit or suppress the code wrapped in the macro:
(defn- nodejs-target?
[]
(= :nodejs (get-in @cljs.env/*compiler* [:options :target])))
(defmacro code-for-nodejs
[& body]
(when (nodejs-target?)
`(do ~@body)))
(defmacro code-for-browser
[& body]
(when-not (nodejs-target?)
`(do ~@body)))
(code-for-nodejs
(def my-variable "Compiled for nodejs")
(println "Hello from nodejs"))
(code-for-browser
(def my-variable "Compiled for browser")
(println "Hello from browser"))