Как определить целевую среду во время компиляции при создании .cljs?

Я хочу скомпилировать свой файл .cljs как для среды браузера, так и для среды node.js, чтобы получить рендеринг на стороне сервера. Насколько я понимаю, нет возможности определить cljs env во время компиляции с условиями макроса чтения, такими как:

#?(:clj ...)
#?(:cljs ...)

поэтому я не могу легко сказать компилятору обработать что-то вроде #?(:cljs-node ...) в среде node.js.

Второй вариант, который я вижу здесь, - это разработать файл макроса, который будет определять env во время компиляции. Но как определить, что текущая сборка нацелена на node.js? Может быть, можно как-то передать какие-то параметры компилятору или получить :target параметр компилятора?

Вот мои загрузочные файлы:

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}}

person zarkone    schedule 25.11.2017    source источник
comment
попробуйте clojureverse.org   -  person jiyinyiyong    schedule 25.11.2017


Ответы (1)


Я не знаю общедоступного API для достижения этого. Однако вы можете использовать cljs.env/*compiler* dynamic var в вашем макросе, чтобы проверить целевую платформу (например, NodeJS или браузер), настроенную с помощью :target в вашем :compiler-options, и либо выдать, либо подавить код, заключенный в макрос:

(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"))
person Piotrek Bzdyl    schedule 26.11.2017
comment
Спасибо, именно то, что я искал! Но у меня есть одна проблема: :require в ns. Как требовать пространства имен в зависимости от env? - person zarkone; 27.11.2017
comment
В настоящее время я вижу единственный способ использовать require не из макроса ns, а напрямую - person zarkone; 27.11.2017
comment
Хм, это может быть проблемой в зависимости от того, как с этим справляется компилятор CLJS. Вы можете попытаться переместить :require из формы ns в автономную форму (require ...), обернутую одним из макросов, и посмотреть, сработает ли это. - person Piotrek Bzdyl; 27.11.2017