# How to deal with development code in ClojureScript?

**URL:** https://clojureverse.org/t/how-to-deal-with-development-code-in-clojurescript/613
**Category:** How to?
**Created:** [October 27, 2017, 5:13pm UTC](https://clojureverse.org/t/how-to-deal-with-development-code-in-clojurescript/613 "2017-10-27T17:13:46Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![jiyinyiyong](https://clojureverse.org/user_avatar/clojureverse.org/jiyinyiyong/32/85_2.png) [@jiyinyiyong](https://clojureverse.org/u/jiyinyiyong)
#### Post date: [October 27, 2017, 5:13pm UTC](https://clojureverse.org/t/how-to-deal-with-development-code-in-clojurescript/613/1 "2017-10-27T17:13:47Z")

</div>

In React community, there are some cases we write:

```auto
if ( __DEV__ ) {
  console.log("some warning or asserting")
}

```

and these lines of code will be removed in Webpack release mode.

Can we do this in ClojureScript?

I thought about using macros with a variable to decide while function to use. But perhaps we still need the compiler to do something about it?

---

<div class="post-metadata">

### Author: ![plexus](https://clojureverse.org/user_avatar/clojureverse.org/plexus/32/6_2.png) [@plexus](https://clojureverse.org/u/plexus)
#### Post date: [October 28, 2017, 1:08pm UTC](https://clojureverse.org/t/how-to-deal-with-development-code-in-clojurescript/613/2 "2017-10-28T13:08:27Z")

</div>

There are a couple things people do. One thing is to check for `goog.DEBUG`, which is what the Google Closure library also uses. In your ClojureScript compiler options you can add

```auto
:closure-defines {goog.DEBUG false}

```

for the production build, and `{goog.DEBUG true}` for the dev build, and then check for it in your code, `(if goog.DEBUG ...)`

This doesn’t stop code from being included in the final build though. You can come up with a macro scheme, although I don’t immediately have a good example. You would have to rely on something else than `goog.DEBUG` since macros are evaluated in the JVM (when using the default Clojure based compiler).

A more common approach that people use is to make use of separate `dev`/`prod` source paths.

```auto
[{:id "dev"
  :source-paths ["src" "env/dev"]
  :compiler { ,,, }}

 {:id "prod"
  :source-paths ["src" "env/prod"]
  :compiler { ,,, }}]

```

and then having certain namespaces in there with different function or macro definitions based on `dev` or `prod`. You could even have a generic `when-dev` macro for instance

```auto
;; env/dev/my/macros.clj
(ns my.macros)

(defmacro with-debug [& body]
  body)

```

```auto
;; env/prod/my/macros.clj
(ns my.macros)

(defmacro with-debug [& body]
  nil)

```

So any code you wrap in `(with-debug ,,,)` will be removed from the output when doing a production build.

---

<div class="post-metadata">

### Author: ![thheller](https://clojureverse.org/user_avatar/clojureverse.org/thheller/32/534_2.png) [@thheller](https://clojureverse.org/u/thheller)
#### Post date: [October 28, 2017, 9:59pm UTC](https://clojureverse.org/t/how-to-deal-with-development-code-in-clojurescript/613/3 "2017-10-28T21:59:49Z")

</div>

> [@plexus](#):
>
> This doesn’t stop code from being included in the final build though.

Closure will definitely remove conditional code if the conditional can be resolved at compile time. It sometimes takes a type hint to remove the `cljs.core.truth_` check which CLJS injects to have proper truth semantics.

Take this code:

```clojure
(when js/goog.DEBUG
  (js/console.log "hello world"))

```

Usually this will emit

```js
if(cljs.core.truth_(goog.DEBUG)){
console.log("hello world");
} else {
}

```

Note the `cljs.core.truth_` call. This is not recognized by Closure and will not be removed. However with a little boolean hint this can be removed.

```clojure
(when ^boolean js/goog.DEBUG
  (js/console.log "hello world"))

```

turns into

```js
if(goog.DEBUG){
console.log("hello world");
} else {
}

```

The Closure Compiler does properly recognize this and once you run this through `:advanced` (or even `:simple`) this `if` will the completely removed.

Macros can also work but I generally advise against them since build tools will not be aware of any trickery you do with environment variables and such. Caching will usually become very unreliable if you do this and will often mean that `lein clean` or equivalent is your only option for reliable build output. Not something I would want to trade.

Another option would be reader conditionals but CLJS currently does not support this. It would be pretty easy to add though.

PS: It is unfortunate that the `^boolean` type hint is still required in all cases, we can definitely get rid of some. [[CLJS-1439] - JIRA](https://dev.clojure.org/jira/browse/CLJS-1439) has been open quite a while, maybe some votes would help. 😉

---

<div class="post-metadata">

### Author: ![plexus](https://clojureverse.org/user_avatar/clojureverse.org/plexus/32/6_2.png) [@plexus](https://clojureverse.org/u/plexus)
#### Post date: [October 29, 2017, 10:58am UTC](https://clojureverse.org/t/how-to-deal-with-development-code-in-clojurescript/613/4 "2017-10-29T10:58:46Z")

</div>

That is super interesting and explains why e.g. the re-frame template has this

```auto
(def debug?
  ^boolean goog.DEBUG)

```

I’ve upvoted the ticket!

---

<div class="post-metadata">

### Author: ![system](https://clojureverse.org/uploads/default/original/2X/5/51079bf9e4b7d9466242c06cf1e43b9f8bd6da14.png) [@system](https://clojureverse.org/u/system)
#### Post date: [October 5, 2018, 12:50pm UTC](https://clojureverse.org/t/how-to-deal-with-development-code-in-clojurescript/613/5 "2018-10-05T12:50:41Z")

</div>


