Skip to content

Commit 5ef5f10

Browse files
martinklepschdnolen
authored andcommitted
provide define macro to support proper use of goog.define
Using Closure defines [1] has always been possible by attaching the appropriate JSDoc metadata to a var: (def ^{:jsdoc ["@define {boolean}"]} APP_DEBUG true) When compiling with :optimizations :none however these defines cannot be overridden. This commit introduces a `cljs.core/define` macro that helps with emitting proper `goog.define` calls. Defines done with `goog.define` can be overriden at runtime by supplying `CLOSURE_UNCOMPILED_DEFINES` or `CLOSURE_DEFINES`. [2] (ns your-app.core) (define APP_DEBUG true) emits the following `goog.define` call: /** @define {boolean} */ goog.define('your_app.core.APP_DEBUG', true) When compiling with `:none` the map passed to `:closure-defines` is now added to the main file, allowing `goog.define` to pick the right value at runtime. [1] https://developers.google.com/closure/compiler/docs/js-for-compiler?hl=en#tag-define [2] http://google.github.io/closure-library/api/source/closure/goog/base.js.src.html#l51
1 parent b7309fd commit 5ef5f10

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

src/main/clojure/cljs/closure.clj

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,8 @@
11231123

11241124
(defn output-main-file [opts]
11251125
(let [asset-path (or (:asset-path opts)
1126-
(util/output-directory opts))]
1126+
(util/output-directory opts))
1127+
closure-defines (json/write-str (:closure-defines opts))]
11271128
(case (:target opts)
11281129
:nodejs
11291130
(output-one-file opts
@@ -1134,10 +1135,12 @@
11341135
"}\n"
11351136
"require(path.join(path.resolve(\".\"),\"" asset-path "\",\"goog\",\"bootstrap\",\"nodejs.js\"));\n"
11361137
"require(path.join(path.resolve(\".\"),\"" asset-path "\",\"cljs_deps.js\"));\n"
1138+
"goog.global.CLOSURE_UNCOMPILED_DEFINES = " closure-defines ";\n"
11371139
"goog.require(\"" (comp/munge (:main opts)) "\");\n"
11381140
"goog.require(\"cljs.nodejscli\");\n"))
11391141
(output-one-file opts
1140-
(str "if(typeof goog == \"undefined\") document.write('<script src=\"" asset-path "/goog/base.js\"></script>');\n"
1142+
(str "var CLOSURE_UNCOMPILED_DEFINES = " closure-defines ";\n"
1143+
"if(typeof goog == \"undefined\") document.write('<script src=\"" asset-path "/goog/base.js\"></script>');\n"
11411144
"document.write('<script src=\"" asset-path "/cljs_deps.js\"></script>');\n"
11421145
"document.write('<script>if (typeof goog != \"undefined\") { goog.require(\"" (comp/munge (:main opts))
11431146
"\"); } else { console.warn(\"ClojureScript could not load :main, did you forget to specify :asset-path?\"); };</script>');\n")))))

src/main/clojure/cljs/core.cljc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,36 @@
685685
:cljs (new js/Error (core/str "Unsupported binding key: " (ffirst kwbs)))))
686686
(reduce process-entry [] bents)))))
687687

688+
(core/defmacro define
689+
"Defines a var using `goog.define`. Passed default value must be
690+
string, number or boolean.
691+
692+
Default value can be overridden at compile time using the
693+
compiler option `:closure-defines`. When overriding the string
694+
you need to pass to `:closure-defines` is the munged version
695+
of the original var.
696+
697+
Example:
698+
(ns your-app.core)
699+
(define DEBUG! false)
700+
;; can be overridden with
701+
:closure-defines {\"your_app.core.DEBUG_BANG_\" true}"
702+
[sym default]
703+
(assert-args define
704+
(core/or (core/string? default)
705+
(core/number? default)
706+
(core/true? default)
707+
(core/false? default)) "a string, number or boolean as default value")
708+
(core/let [defname (cljs.compiler/munge (core/str *ns* "/" sym))
709+
type (core/cond
710+
(core/string? default) "string"
711+
(core/number? default) "number"
712+
(core/or (core/true? default) (core/false? default)) "boolean")]
713+
`(do
714+
(declare ~(symbol sym))
715+
(~'js* ~(core/str "/** @define {" type "} */"))
716+
(goog/define ~defname ~default))))
717+
688718
(core/defmacro let
689719
"binding => binding-form init-expr
690720

0 commit comments

Comments
 (0)