Search code examples
clojurescript

How to pass env variables to ClojureScript app?


I have a ClojureScript app that is launched from Leiningen. How do I pass env variables to the app when it starts (could be when it buids)


Solution

  • There are two build time options:

    Using macros

    CLJS macros are Clojure code, that runs at compile time. So you can use regular Clojure code to read the environment variables and either include them or do other macro-iy things.

    Using goog.define

    CLJS integrates with this facility of the Google Closure compiler to pass build time configurations.

    Example using both

    Relative minimal project.clj, that sets a goog.define from env-var E1:

    ; project.clj
    (defproject envvars "0.1.0-SNAPSHOT"
      :min-lein-version "2.9.1"
      :dependencies [[org.clojure/clojure "1.10.1"]
                     [org.clojure/clojurescript "1.10.597"]]
      :plugins [[lein-cljsbuild "1.1.7" :exclusions [[org.clojure/clojure]]]]
      :source-paths ["src"]
      :cljsbuild {:builds
                  [{:id "dev"
                    :source-paths ["src"]
                    :compiler {:closure-defines {envvars.core.e1 ~(System/getenv "E1")} ; XXX
                               :main envvars.core
                               :asset-path "js/compiled/out"
                               :output-to "resources/public/js/compiled/envvars.js"
                               :output-dir "resources/public/js/compiled/out"
                               :source-map-timestamp true}}]})
    

    Macro, that reads the env-var E2:

    ; src/envvars/coremacros.clj 
    (ns envvars.coremacros)
    
    (defmacro load-via-macro []
      (System/getenv "E2")) ; XXX
    

    Example "main", to print the content:

    ; src/envvars/core.cljs 
    (ns envvars.core
        (:require-macros [envvars.coremacros]))
    
    (enable-console-print!)
    
    (goog-define e1 "undefined") ; XXX
    
    (def e2 (envvars.coremacros/load-via-macro)) ; XXX
    
    (println e1 e2) ; XXX
    

    Build with:

    E1=E1 E2=E2 lein cljsbuild once
    

    Behold the E1 E2 being printed in the console