Giter VIP home page Giter VIP logo

re-frame-template's Introduction

Clojars Project GitHub issues GitHub

re-frame-template

This is a Leiningen template for creating a re-frame application scaffold (client only) with a shadow-cljs build.
It will take you 60 seconds to create your first re-frame app and start to edit it.

You can pick and choose what "extras" you'd like included into the scaffold - "extras" like libraries to do routing, debugging and CSS.

Before You Start

You'll need to install Leiningen (a build tool) by following these instructions.

You'll also need Node.js.

Basic Usage

The base template includes:

To create an application with just the base template, use this commandline:

$ lein new re-frame <app-name>

When using this command, you'll need to substitute in your own <app-name> - perhaps my-killer-app or an-early-masterpiece.

Troubleshooting note: for <app-name> don't use cljs. That name will confuse the compiler (long story) and you will later see errors like cljs.core.init is not a function.

Extras

The following "extras" can be nominated on the commandline when you create the template:

To add an extra to the base template, append its name to the commandline, with a leading +. Here's an example of adding re-com:

lein new re-frame <app-name> +re-com

Note: it is +re-com, not just re-com.

Any combination of extras can be added at once:

lein new re-frame <app-name> +garden +re-com +routes +test +10x

Note: to assist debugging, you'll want to include either +10x or +re-frisk

Start Cider from Emacs (if using +cider):

Refer to the shadow-cljs Emacs / CIDER documentation.

The mentioned dir-local.el file is created by this template.

Connect Calva from VS Code:

Calva has built-in support for shadow-cljs projects (that's why there is no +calva option for creating this project).

  1. npm install
  2. From VS Code, issue the command Calva: Start a Project REPL and Connect (a.k.a Jack-in), ctrl+alt+c ctrl+alt+j.
    • Calva will auto-detect that this is a shadow-cljs project and ask for which build to compile.
    • Calva's output window will open and log some progress information.
  3. When prompted for which build to start, select :app.
    • :app is the only configured build, but the VS Code menu for this is a bit strange so make sure the :app checkbox is really ticked before proceeding.
    • This will start the app, so in this workflow you don't do the Run application steps outlined below.
  4. When prompted for which build to connect to, select :app.
    • In the View menu of VS Code, you can tell it to show the Terminal view, where you see which command the jack-in process is started with, and it's output. Ctrl+C in this pane will kill your app and free up all resources it has allocated.
  5. When the app is compiled
    1. Open http://localhost:8280 in your browser.
    2. Confirm that it says Hello from re-frame. (Depending on how long the app takes to compile, you might need to reload the page a few times.)
  6. Open the views.cljs file from src/<your-project-name> and issue Calva: Load Current File and Dependencies. ctrl+alt+c enter.
    1. Confirm that you are connected by adding evaluating (js/alert "Hello from Calva") (alt+enter and ctrl+enter are your friends).
    2. Confirm that Shadow is hot reloading by changing the greeting message.

See https://calva.io for more on how to use Calva.

Run application:

npm install
npm run watch

or

npm install
npx shadow-cljs watch app browser-test karma-test

Wait a bit, perhaps 20 seconds, keeping an eye out for a sign the compile has finished, then browse to http://localhost:8280.

To see the other available shadow-cljs commands run:

npx shadow-cljs --help

Setting Up Your Browser

So, you now have the application running.

Before you start developing, you should tweak two settings within your browser's devtools. These are one-time actions (for each browser and laptop you use). I'll assume Chrome for the purposes of further explanation:

  1. Open devtools. Press press F12 or Ctrl-Shift-i (actually there's a variety of ways)
  2. Open the devtools "Settings" panel. Press F1. (Careful. Not the settings panel for Chrome itself!! The settings panel for devtools)
  3. Under the "Network" heading, tick the option "Disable cache (while DevTools is open)". You don't want shadow-clj's attempts at reloading to be defeated by caching.
  4. Under the "Console" heading, tick the option "Enable custom formatters". This allows cljs-devtools to perform its magic.
  5. Close Settings. Close Devtools.
  6. Reopen Devtools

settings

Open 10x Panel (if using +10x):

To use re-frame-10x for debugging your app:

  1. click on the application, minimal through it is, to give it "input focus" (you want to be sure that any key presses are going to your new app)
  2. press Ctrl-Shift-X and you should see the re-frame-10x panel appear on the right side of the window

Sometimes achieving Step 1 on a really simple app - one without widgets - can be fiddly, because the browser itself hogs "input focus" and grabs all the keystrokes (like Ctrl-Shift-X) which don't then make it through to your app. You may need to be determined and creative with Step 1. I have every confidence in you.

Hot Reloading Is Now Go

If you now edit files, shadow-cljs will automatically recompile your changes and "hot load" them into your running app, without your app needing to be re-started. The resulting fast, iterative workflow tends to make you very productive, and is cherished by those lucky enough to experience it.

Start by editing this file: /src/cljs/<app-name>/views.cljs.

debug?:

In the namespace app-name.config, there is a var called debug?, which defaults to true in the dev build, and false in the prod build.

If, for example, you wrap your printlns with a when block as shown below, then you will get logs printed to the browser's console for the dev build and not the prod build.

(when config/debug?
  (println "dev mode"))

Run tests (if using +test):

Run your tests

npm install
npm run watch

And in another terminal:

karma start

GitHub Actions

After a push, head to the actions section of GitHub repo to see the pipeline processing.

Production Build

To compile clojurescript to javascript:

npm run release

How to Add Dependencies

Your new application is built by a tool chain controlled by shadow-cljs (a modern CLJS compiler).

There are two files of interest:

  • shadow-cljs.edn - edit this file if you want to add Clojure and ClojureScript dependency as you would for a normal Leiningen project.
  • package.json - edit this file if you want to add a JavaScript and NPM dependency.

Other Templates

Backend Options

This template does NOT include a backend. You may want to look at the following for backend options:

More re-frame

Looking for more re-frame inspiration, templates or example applications? See the external resources docs page.

Contributing

Contributions are welcomed! To add a new profile, this is what I'd recommend:

  1. Add a file with the name of the profile here
  2. Look at the existing options in that folder for inspiration for what to include in that file
  3. Update re_frame.clj with the profile
  4. Add any new files here and use the {{ var-name }} syntax as needed
  5. Update the README that will result when the template is used, as well as the top-level README for re-frame-template itself
  6. In a terminal, at the root of re-frame-template, run lein install
  7. Locally test that your profile works, lein new re-frame <app-name> +<profile-name>
  8. Add your profile to create-templates and run the script to make sure the other profiles didn't break.

License

The MIT License (MIT)

Copyright © 2015-2018 Matthew Jaoudi
Copyright © 2015 Dylan Paris
Copyright © 2015 Michael Thompson
Copyright © 2015 Markku Rontu
Copyright © 2016 Daniel Compton
Copyright © 2019-2021 Isaac Johnston

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

re-frame-template's People

Contributors

agorgl avatar calebmacdonaldblack avatar danielappelt avatar danielcompton avatar deg avatar dominem avatar dparis avatar ducky427 avatar dundalek avatar ertugrulcetin avatar flexsurfer avatar gadfly361 avatar iku000888 avatar jelmerderonde avatar kimo-k avatar maacl avatar macroz avatar matthieu-beteille avatar mike-thompson-day8 avatar mikos avatar nikolap avatar paulbutcher avatar pez avatar sose avatar stevejmp avatar stumitchell avatar sunng87 avatar superstructor avatar thheller avatar wencesllobet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

re-frame-template's Issues

Watch Clojure (backend) files for changes and reload?

Sorry, this isn't necessarily a re-frame-specific issue but reflects my ignorance of the broader lein workflows. I understand that figwheel shouldn't be held responsible for reloading my Clojure .clj files if they change, since that handles the front-end. However, is there a recommended way to watch for changes in /src/clj and reload them? Specifically, as I add endpoints to handler.clj (made with +handler), I'm finding that lein figwheel dev won't see them until I restart lein.

Add sente

lein new re-frame +sente +re-com +re-frisk +routes

Use namespaced keywords for events, subscriptions, db (, routes, ...) for greater readability

Hi,
I am new to re-frame and I was playing around to learn the technology. I was confused because of the similar looking non-namespaced keywords and the resulting errors. I decided to namespace all of them and found out that the namespaced keywords perfectly match the dominos and makes it perfectly clear where to use which keyword. Also it makes modularization of the app very natural.

For example :set-active-panel will result in :my-app.events/set-active-panel (or ::events/set-active-panel).

Sounds totally trivial but this helped me a lot. Maybe also interesting for the todo example.

All ClojureScript build config :output-dir parameters should be unique

Upon cider-jack-in-clojurescript I get:

All ClojureScript build config :output-dir parameters should be unique

param for :output-dir in both the dev and min profile appears to be the same. Param for dev is eual to the default value ie. resources/public/js/compiled/out which is causing the issue.

Confirm @Robsteranium below that changing to unique params fixes issue.

Unhandled java.io.FileNotFoundException Could not locate figwheel_sidecar/repl_api__init.class or figwheel_sidecar/repl_api.clj on classpath.

Hi, I lein new re-frame wechat-reframe1 +routes +test +less +re-frisk a new re-frame project and C-c M-J and got the following error:

   Could not locate figwheel_sidecar/repl_api__init.class or
   figwheel_sidecar/repl_api.clj on classpath. Please check that namespaces with
   dashes use underscores in the Clojure file name.

I found there is no [figwheel-sidecar "0.5.9"] [com.cemerick/piggieback "0.2.1"] in the dev dependencies in the generated project by re-frame-template, add those to the dev dependencies solved this problem.

Race Condition in App Bootstrap

I believe there's a race condition in the way the application bootstrap is written:
https://github.com/Day8/re-frame-template/blob/master/src/leiningen/new/re_frame/resources/public/index.html#L15-L16

app.js must be fully loaded before init() can be called. If it isn't, then there'll be an Reference Error (because the necessary js just isn't loaded yet). And yet the current code doesn't guarantee this fully-loaded-before-call requirement.

The solution is easy - change the script part to be:

<script>
   window.onload = function () { 
       {{sanitized}}.core.init(); 
   }
</script>

Now init() doesn't happen before app.js is fully loaded.

So ...

I'm completely shocked that this hasn't come up before now. How has this not failed all the time before now? I'm Baffled. I must be missing something - which accounts for me not doing a PR. (Was just reported as a problem in Clojurians)

Deploying to Heroku

I've just written a toy app using this template, and I'd like to deploy it to Heroku.
I followed the usual steps but hit a failure:

...
2016-08-02T09:41:59.777243+00:00 heroku[slug-compiler]: Slug compilation started
2016-08-02T09:41:59.777249+00:00 heroku[slug-compiler]: Slug compilation finished
2016-08-02T09:42:04.537917+00:00 heroku[web.1]: Starting process with command `lein with-profile production trampoline run`
2016-08-02T09:42:06.800054+00:00 app[web.1]: Setting JAVA_TOOL_OPTIONS defaults based on dyno size. Custom settings will override them.
2016-08-02T09:42:06.813188+00:00 app[web.1]: Picked up JAVA_TOOL_OPTIONS: -Xmx350m -Xss512k -Dfile.encoding=UTF-8
2016-08-02T09:42:45.664277+00:00 app[web.1]: Compiling ClojureScript...
2016-08-02T09:42:46.963767+00:00 app[web.1]: Picked up JAVA_TOOL_OPTIONS: -Xmx350m -Xss512k -Dfile.encoding=UTF-8
2016-08-02T09:42:48.681490+00:00 app[web.1]:    at clojure.lang.Compiler.load(Compiler.java:7391)
2016-08-02T09:42:48.681325+00:00 app[web.1]: Exception in thread "main" java.io.FileNotFoundException: Could not locate cljsbuild/compiler__init.class or cljsbuild/compiler.clj on classpath., compiling:(/tmp/form-init9197767631145422317.clj:1:73)
2016-08-02T09:42:48.681536+00:00 app[web.1]:    at clojure.lang.Compiler.loadFile(Compiler.java:7317)
2016-08-02T09:42:48.681592+00:00 app[web.1]:    at clojure.main$load_script.invokeStatic(main.clj:275)
...

I see in this project's README.md the note Desired profiles: +Heroku, so I assume it is known that some magic is needed to make this work. But, I don't know what the next step is, or even exactly what the error means. Help? Thanks!

lein uberjar fails on default project

I'm starting out with re-frame and discovered that lein uberjar fails from a fresh project via

lein new re-frame thetest +10x +cider +handler +garden +routes
cd thetest/
lein uberjar

Compiling ClojureScript...
Compiling "resources/public/js/compiled/app.js" from ["src/cljs"]...
Compiling "resources/public/js/compiled/app.js" failed.
clojure.lang.ExceptionInfo: failed compiling
...
...
Caused by: clojure.lang.ExceptionInfo: No such namespace: day8.re-frame.tracing, could not locate day8/re_frame/tracing.cljs, day8/re_frame/tracing.cljc, or JavaScript source providing "day8.re-frame.tracing"

... clj/thetest/src/cljs/thetest/events.cljs {:tag :cljs/analysis-error}
    at clojure.core$ex_info.invokeStatic(core.clj:4617)
    at clojure.core$ex_info.invoke(core.clj:4617)
    at cljs.analyzer$error.invokeStatic(analyzer.cljc:697)
    at cljs.analyzer$error.invoke(analyzer.cljc:693)
    at cljs.analyzer$error.invokeStatic(analyzer.cljc:695)
    at cljs.analyzer$error.invoke(analyzer.cljc:693)
    at cljs.analyzer$analyze_deps.invokeStatic(analyzer.cljc:2122)
    at cljs.analyzer$analyze_deps.invoke(analyzer.cljc:2096)
    at cljs.analyzer$ns_side_effects.invokeStatic(analyzer.cljc:3461)
    at cljs.analyzer$ns_side_effects.invoke(analyzer.cljc:3456)
    at cljs.analyzer$analyze_STAR_$fn__3036.invoke(analyzer.cljc:3580)
    at clojure.lang.PersistentVector.reduce(PersistentVector.java:341)
    at clojure.core$reduce.invokeStatic(core.clj:6544)
    at clojure.core$reduce.invoke(core.clj:6527)
    at cljs.analyzer$analyze_STAR_.invokeStatic(analyzer.cljc:3580)
    at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:3570)
    at cljs.analyzer$analyze.invokeStatic(analyzer.cljc:3604)
    at cljs.analyzer$analyze.invoke(analyzer.cljc:3587)
    at cljs.compiler$emit_source.invokeStatic(compiler.cljc:1358)
    at cljs.compiler$emit_source.invoke(compiler.cljc:1337)
    at cljs.compiler$compile_file_STAR_$fn__4174.invoke(compiler.cljc:1437)
    at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1252)
    at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1241)
    at cljs.compiler$compile_file_STAR_.invokeStatic(compiler.cljc:1422)
    at cljs.compiler$compile_file_STAR_.invoke(compiler.cljc:1415)
    at cljs.compiler$compile_file$fn__4205.invoke(compiler.cljc:1519)
    ... 58 more
Uberjar aborting because jar failed: Subprocess failed

Any ideas on how to fix to get an uberjar?

Thank-you kindly

Idea: Scaffolding for re-frame generators

Just some ideas for how to build large projects built on domain models and standardised patterns/vocabulary, structure etc. WIP

Create todo domain model with basic scaffolding:

re-frame new todo

File structure

+ todo
  todo-views.cljs
  todo-handlers.cljs
  todo-subscribers.cljs
  todo-utils.cljs

Scaffolding using conventions

(ns todo.views
    (:require [re-frame.core :refer [subscribe dispatch]]))

;; todo-views

(defn todo-actions [id]
  [:div {:class "actions"}
    [:button "Update" #(dispatch [:update-todo item])]
    [:button "Delete" #(dispatch [:del-todo item])]
  ]

(defn todo-item [item]
  [let item (subscribe [:get-todo-item item])
    [:li (:name item)] (todo-actions item)])

(defn todo-list []
  [let list (subscribe [:get-todo-list])
    [:div
      [:ul
        (for [item list]
          (todo-item item))
      ]
      [:button "Create new Todo" #(dispatch [:new-todo])]
    ]
   ])
(ns todo.handlers
    (:require [re-frame.core :refer [register-handler]]))

;; todo handlers

(defn new-todo []
  (fn [db, [id]]
    ;; ...
    ))

(defn edit-todo []
  (fn [db, [id]]
    ;; ...
    ))

(defn del-todo []
  (fn [db, [id]]
    ;; ...
    ))

(register-handler :new-todo new-todo)
(register-handler :edit-todo edit-todo)
(register-handler :del-todo del-todo)

```cljs
(ns todo.subscribers
    (:require-macros [reagent.ratom :refer [reaction]])

;; todo subscribers
;; use reactions

return single item record
(defn get-todo-item [db, [id]] {id: 1 name: "Todo item"})

;; return list of item ids
(defn get-todo-list [db, []] [1])

These scaffolding templates could (naturally) be customised on a per project or technology stack level

Heroku push error with `+10x +re-frisk`

To reproduce:

lein new re-frame heroku-re-frame-test +handler +routes +10x +re-frisk
git init
git add
git commit
heroku create
git push heroku master

Error while pushing to Heroku:

...
remote:        Retrieving clj-stacktrace/clj-stacktrace/0.2.5/clj-stacktrace-0.2.5.jar from clojars
remote:        Compiling ["resources/public/js/compiled/app.js"] from ["src/cljs"]...
remote:        Compiling ["resources/public/js/compiled/app.js"] failed.
remote:        clojure.lang.ExceptionInfo: failed compiling file:/tmp/build_36e8072aaa71ae7de395006ed38900e2/src/cljs/heroku_re_frame_test/events.cljs {:file #object[java.io.File 0x7f69a16b "/tmp/build_36e8072aaa71ae7de395006ed38900e2/src/cljs/heroku_re_frame_test/events.cljs"]}
remote:        	at clojure.core$ex_info.invokeStatic(core.clj:4617)
remote:        	at clojure.core$ex_info.invoke(core.clj:4617)
remote:        	at cljs.compiler$compile_file$fn__3702.invoke(compiler.cljc:1562)
remote:        	at cljs.compiler$compile_file.invokeStatic(compiler.cljc:1522
remote:        	at cljs.compiler$compile_file.invoke(compiler.cljc:1498)
remote:        	at cljs.closure$compile_file.invokeStatic(closure.clj:573)
remote:        	at cljs.closure$compile_file.invoke(closure.clj:564)
remote:        	at cljs.closure$fn__5124.invokeStatic(closure.clj:653)
remote:        	at cljs.closure$fn__5124.invoke(closure.clj:647)
remote:        	at cljs.closure$fn__5052$G__5045__5059.invoke(closure.clj:521
remote:        	at cljs.closure$fn__5128.invokeStatic(closure.clj:662)
remote:        	at cljs.closure$fn__5128.invoke(closure.clj:647)
remote:        	at cljs.closure$fn__5052$G__5045__5059.invoke(closure.clj:521
remote:        	at cljs.closure$compile_sources$iter__5250__5254$fn__5255.invoke(closure.clj:1011)
remote:        	at clojure.lang.LazySeq.sval(LazySeq.java:40)
remote:        	at clojure.lang.LazySeq.seq(LazySeq.java:49)
remote:        	at clojure.lang.Cons.next(Cons.java:39)
remote:        	at clojure.lang.RT.next(RT.java:688)
remote:        	at clojure.core$next__4341.invokeStatic(core.clj:64)
remote:        	at clojure.core$dorun.invokeStatic(core.clj:3033)
remote:        	at clojure.core$doall.invokeStatic(core.clj:3039)
remote:        	at clojure.core$doall.invoke(core.clj:3039)
remote:        	at cljs.closure$compile_sources.invokeStatic(closure.clj:1007
remote:        	at cljs.closure$compile_sources.invoke(closure.clj:996)
remote:        	at cljs.closure$build.invokeStatic(closure.clj:2817)
remote:        	at cljs.closure$build.invoke(closure.clj:2718)
remote:        	at cljs.build.api$build.invokeStatic(api.clj:208)
remote:        	at cljs.build.api$build.invoke(api.clj:189)
remote:        	at cljs.build.api$build.invokeStatic(api.clj:195)
remote:        	at cljs.build.api$build.invoke(api.clj:189)
remote:        	at cljsbuild.compiler$compile_cljs$fn__550.invoke(compiler.clj:61)
remote:        	at cljsbuild.compiler$compile_cljs.invokeStatic(compiler.clj:60)
remote:        	at cljsbuild.compiler$compile_cljs.invoke(compiler.clj:48)
remote:        	at cljsbuild.compiler$run_compiler.invokeStatic(compiler.clj:168)
remote:        	at cljsbuild.compiler$run_compiler.invoke(compiler.clj:129)
remote:        	at user$eval665$iter__701__705$fn__706$fn__724.invoke(form-init617459368045006442.clj:1)
remote:        	at user$eval665$iter__701__705$fn__706.invoke(form-init617459368045006442.clj:1)
remote:        	at clojure.lang.LazySeq.sval(LazySeq.java:40)
remote:        	at clojure.lang.LazySeq.seq(LazySeq.java:49)
remote:        	at clojure.lang.RT.seq(RT.java:521)
remote:        	at clojure.core$seq__4357.invokeStatic(core.clj:137)
remote:        	at clojure.core$dorun.invokeStatic(core.clj:3024)
remote:        	at clojure.core$doall.invokeStatic(core.clj:3039)
remote:        	at clojure.core$doall.invoke(core.clj:3039)
remote:        	at user$eval665.invokeStatic(form-init617459368045006442.clj:1)
remote:        	at user$eval665.invoke(form-init617459368045006442.clj:1)
remote:        	at clojure.lang.Compiler.eval(Compiler.java:6927)
remote:        	at clojure.lang.Compiler.eval(Compiler.java:6917)
remote:        	at clojure.lang.Compiler.load(Compiler.java:7379)
remote:        	at clojure.lang.Compiler.loadFile(Compiler.java:7317)
remote:        	at clojure.main$load_script.invokeStatic(main.clj:275)
remote:        	at clojure.main$init_opt.invokeStatic(main.clj:277)
remote:        	at clojure.main$init_opt.invoke(main.clj:277)
remote:        	at clojure.main$initialize.invokeStatic(main.clj:308)
remote:        	at clojure.main$null_opt.invokeStatic(main.clj:342)
remote:        	at clojure.main$null_opt.invoke(main.clj:339)
remote:        	at clojure.main$main.invokeStatic(main.clj:421)
remote:        	at clojure.main$main.doInvoke(main.clj:384)
remote:        	at clojure.lang.RestFn.invoke(RestFn.java:421)
remote:        	at clojure.lang.Var.invoke(Var.java:383)
remote:        	at clojure.lang.AFn.applyToHelper(AFn.java:156)
remote:        	at clojure.lang.Var.applyTo(Var.java:700)
remote:        	at clojure.main.main(main.java:37)
remote:        Caused by: clojure.lang.ExceptionInfo: No such namespace: day8.re-frame.tracing, could not locate day8/re_frame/tracing.cljs, day8/re_frame/tracing.cljc, or JavaScript source providing "day8.re-frame.tracing" in file /tmp/build_36e8072aaa71ae7de395006ed38900e2/src/cljs/heroku_re_frame_test/events.cljs {:tag :cljs/analysis-error}
remote:        	at clojure.core$ex_info.invokeStatic(core.clj:4617)
remote:        	at clojure.core$ex_info.invoke(core.clj:4617)
remote:        	at cljs.analyzer$error.invokeStatic(analyzer.cljc:697)
remote:        	at cljs.analyzer$error.invoke(analyzer.cljc:693)
remote:        	at cljs.analyzer$error.invokeStatic(analyzer.cljc:695)
remote:        	at cljs.analyzer$error.invoke(analyzer.cljc:693)
remote:        	at cljs.analyzer$analyze_deps.invokeStatic(analyzer.cljc:2129
remote:        	at cljs.analyzer$analyze_deps.invoke(analyzer.cljc:2103)
remote:        	at cljs.analyzer$ns_side_effects.invokeStatic(analyzer.cljc:3476)
remote:        	at cljs.analyzer$ns_side_effects.invoke(analyzer.cljc:3471)
remote:        	at cljs.analyzer$analyze_STAR_$fn__2510.invoke(analyzer.cljc:3596)
remote:        	at clojure.lang.PersistentVector.reduce(PersistentVector.java:341)
remote:        	at clojure.core$reduce.invokeStatic(core.clj:6544)
remote:        	at clojure.core$reduce.invoke(core.clj:6527)
remote:        	at cljs.analyzer$analyze_STAR_.invokeStatic(analyzer.cljc:3596)
remote:        	at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:3586)
remote:        	at cljs.analyzer$analyze.invokeStatic(analyzer.cljc:3616)
remote:        	at cljs.analyzer$analyze.invoke(analyzer.cljc:3598)
remote:        	at cljs.compiler$emit_source.invokeStatic(compiler.cljc:1386)
remote:        	at cljs.compiler$emit_source.invoke(compiler.cljc:1365)
remote:        	at cljs.compiler$compile_file_STAR_$fn__3672.invoke(compiler.cljc:1467)
remote:        	at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1285)
remote:        	at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1274)
remote:        	at cljs.compiler$compile_file_STAR_.invokeStatic(compiler.cljc:1451)
remote:        	at cljs.compiler$compile_file_STAR_.invoke(compiler.cljc:1444
remote:        	at cljs.compiler$compile_file$fn__3702.invoke(compiler.cljc:1547)
remote:        	... 60 more
remote:        Uberjar aborting because jar failed: Subprocess failed
remote:  !     Failed to build.
remote:  !     Push rejected, failed to compile Clojure (Leiningen 2) app.
remote: 
remote:  !     Push failed
...

debug? not defined correctly

I'm not sure we have the following code right for achieving Dead Code Elimination (DCE):
https://github.com/Day8/re-frame-template/blob/master/src/leiningen/new/re_frame/src/cljs/config.cljs#L3

It currently reads:

(def debug?
  ^boolean js/goog.DEBUG)

But I think it should instead be:

(def debug?
   "@const {boolean}"      ;;   <---- tells Closure compiler the value doesn't change
  ^boolean goog.DEBUG)     ;;   <---- removed js/  ... David Nolen says not to

But both my assertion of DCE failure and the proposed fix are untested. I'm just quickly dropping this in here so I don't forget.

re-frame template based apps with docker?

I need an example/template/option that helps/hints/generates needed files to make re-frame-template generated app run inside a docker container.

I'm currently running figwheel in a container, but
1: cannot communicate with it from my host mac (port mapping?), and
2: of course I shouldn’t use figwheel in production but cljsbuild once, and
3: I should probably use uberjar, but cannot find a project.clj that has both nice figwheel for re-frame and profiles for uberjar (and never understood leiningen project.cjl deeply enough to know exactly what to do myself)

Thanks! :)

run time error after create a project using the template

I first run

lein new re-frame re-frame +re-com

then it has the following error:
oracle@SomeHost ~/clojure/lein/re-frame $ lein clean
oracle@SomeHost ~/clojure/lein/re-frame $ lein figwheel dev
Figwheel: Starting server at http://localhost:3449
Focusing on build ids: dev
Compiling "resources/public/js/compiled/app.js" from ["src/cljs"]...
Compiling "resources/public/js/compiled/app.js" failed.
clojure.lang.ExceptionInfo: failed compiling file:src/cljs/re_frame/views.cljs
at clojure.core$ex_info.invoke (core.clj:4403)
Caused by: clojure.lang.ExceptionInfo: Assert failed: Circular dependency detected [re-frame.views re-frame.core](every? %28fn* [p1__1802#] %28not %28contains? cljs-dep-set p1__1802#%29%29%29 deps) at line 1 /home/oracle/clojure/lein/re-frame/src/cljs/re_frame/core.cljs
at clojure.core$ex_info.invoke (core.clj:4403)
Caused by: java.lang.AssertionError: Assert failed: Circular dependency detected [re-frame.views re-frame.core](every? %28fn* [p1__1802#] %28not %28contains? cljs-dep-set p1__1802#%29%29%29 deps)
at cljs.analyzer$analyze_deps.invoke (analyzer.clj:1255)

clojure.lang.ExceptionInfo: Assert failed: Circular dependency detected [re-frame.views re-frame.core](every? %28fn* [p1__1802#] %28not %28contains? cljs-dep-set p1__1802#%29%29%29 deps) at line 1 /home/oracle/clojure/lein/re-frame/src/cljs/re_frame/core.cljs {:tag :cljs/analysis-error, :file "/home/oracle/clojure/lein/re-frame/src/cljs/re_frame/core.cljs", :line 1, :column 1}
at clojure.core$ex_info.invoke(core.clj:4403)
at cljs.analyzer$error.invoke(analyzer.clj:380)
at cljs.analyzer$analyze_seq.invoke(analyzer.clj:1859)
at cljs.analyzer$analyze$fn__2170.invoke(analyzer.clj:1953)
at cljs.analyzer$analyze.invoke(analyzer.clj:1946)
at cljs.analyzer$analyze_file$fn__2221.invoke(analyzer.clj:2190)
at cljs.analyzer$analyze_file.invoke(analyzer.clj:2185)
at cljs.analyzer$analyze_deps.invoke(analyzer.clj:1262)
at cljs.analyzer$eval1922$fn__1924.invoke(analyzer.clj:1516)
at clojure.lang.MultiFn.invoke(MultiFn.java:249)
at cljs.analyzer$analyze_seq.invoke(analyzer.clj:1861)
at cljs.analyzer$analyze$fn__2170.invoke(analyzer.clj:1953)
at cljs.analyzer$analyze.invoke(analyzer.clj:1946)
at cljs.analyzer$analyze_file$fn__2221.invoke(analyzer.clj:2190)
at cljs.analyzer$analyze_file.invoke(analyzer.clj:2185)
at figwheel_sidecar.repl$analyze_build.invoke(repl.clj:252)
at figwheel_sidecar.repl$analyze_builds.invoke(repl.clj:257)
at figwheel_sidecar.repl$run_autobuilder_helper.invoke(repl.clj:305)
at figwheel_sidecar.repl$start_autobuild.invoke(repl.clj:376)
at figwheel_sidecar.repl$run_autobuilder.invoke(repl.clj:535)
at user$eval17935.invoke(form-init8107703929753713336.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6703)
at clojure.lang.Compiler.eval(Compiler.java:6693)
at clojure.lang.Compiler.load(Compiler.java:7130)
at clojure.lang.Compiler.loadFile(Compiler.java:7086)
at clojure.main$load_script.invoke(main.clj:274)
at clojure.main$init_opt.invoke(main.clj:279)
at clojure.main$initialize.invoke(main.clj:307)
at clojure.main$null_opt.invoke(main.clj:342)
at clojure.main$main.doInvoke(main.clj:420)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: java.lang.AssertionError: Assert failed: Circular dependency detected [re-frame.views re-frame.core](every? %28fn* [p1__1802#] %28not %28contains? cljs-dep-set p1__1802#%29%29%29 deps)
at cljs.analyzer$analyze_deps.invoke(analyzer.clj:1255)
at cljs.analyzer$eval1922$fn__1924.invoke(analyzer.clj:1516)
at clojure.lang.MultiFn.invoke(MultiFn.java:249)
at cljs.analyzer$analyze_seq.invoke(analyzer.clj:1861)
... 32 more
Subprocess failed

ClassNotFoundException with Java 9

Hi!

I was trying to check out Re-Frame using this template, however I ended up with this error:

Figwheel: Cutting some fruit, just a sec ...
Exception in thread "main" java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter, compiling:(cljs/util.cljc:1:1)
	at clojure.lang.Compiler.load(Compiler.java:7391)
	at clojure.lang.RT.loadResourceScript(RT.java:372)
	at clojure.lang.RT.loadResourceScript(RT.java:363)
	at clojure.lang.RT.load(RT.java:453)
	at clojure.lang.RT.load(RT.java:419)
	at clojure.core$load$fn__5677.invoke(core.clj:5893)
	at clojure.core$load.invokeStatic(core.clj:5892)
	at clojure.core$load.doInvoke(core.clj:5876)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5697)
	at clojure.core$load_one.invoke(core.clj:5692)
	at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
	at clojure.core$load_lib.invokeStatic(core.clj:5736)
	at clojure.core$load_lib.doInvoke(core.clj:5717)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$load_libs.invokeStatic(core.clj:5774)
	at clojure.core$load_libs.doInvoke(core.clj:5758)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$require.invokeStatic(core.clj:5796)
	at clojure.core$require.doInvoke(core.clj:5796)
	at clojure.lang.RestFn.invoke(RestFn.java:805)
	at cljs.analyzer$eval219$loading__5569__auto____220.invoke(analyzer.cljc:9)
	at cljs.analyzer$eval219.invokeStatic(analyzer.cljc:9)
	at cljs.analyzer$eval219.invoke(analyzer.cljc:9)
	at clojure.lang.Compiler.eval(Compiler.java:6927)
	at clojure.lang.Compiler.eval(Compiler.java:6916)
	at clojure.lang.Compiler.load(Compiler.java:7379)
	at clojure.lang.RT.loadResourceScript(RT.java:372)
	at clojure.lang.RT.loadResourceScript(RT.java:363)
	at clojure.lang.RT.load(RT.java:453)
	at clojure.lang.RT.load(RT.java:419)
	at clojure.core$load$fn__5677.invoke(core.clj:5893)
	at clojure.core$load.invokeStatic(core.clj:5892)
	at clojure.core$load.doInvoke(core.clj:5876)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5697)
	at clojure.core$load_one.invoke(core.clj:5692)
	at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
	at clojure.core$load_lib.invokeStatic(core.clj:5736)
	at clojure.core$load_lib.doInvoke(core.clj:5717)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$load_libs.invokeStatic(core.clj:5774)
	at clojure.core$load_libs.doInvoke(core.clj:5758)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$require.invokeStatic(core.clj:5796)
	at clojure.core$require.doInvoke(core.clj:5796)
	at clojure.lang.RestFn.invoke(RestFn.java:457)
	at figwheel_sidecar.utils$eval213$loading__5569__auto____214.invoke(utils.clj:1)
	at figwheel_sidecar.utils$eval213.invokeStatic(utils.clj:1)
	at figwheel_sidecar.utils$eval213.invoke(utils.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6927)
	at clojure.lang.Compiler.eval(Compiler.java:6916)
	at clojure.lang.Compiler.load(Compiler.java:7379)
	at clojure.lang.RT.loadResourceScript(RT.java:372)
	at clojure.lang.RT.loadResourceScript(RT.java:363)
	at clojure.lang.RT.load(RT.java:453)
	at clojure.lang.RT.load(RT.java:419)
	at clojure.core$load$fn__5677.invoke(core.clj:5893)
	at clojure.core$load.invokeStatic(core.clj:5892)
	at clojure.core$load.doInvoke(core.clj:5876)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5697)
	at clojure.core$load_one.invoke(core.clj:5692)
	at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
	at clojure.core$load_lib.invokeStatic(core.clj:5736)
	at clojure.core$load_lib.doInvoke(core.clj:5717)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$load_libs.invokeStatic(core.clj:5774)
	at clojure.core$load_libs.doInvoke(core.clj:5758)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$require.invokeStatic(core.clj:5796)
	at clojure.core$require.doInvoke(core.clj:5796)
	at clojure.lang.RestFn.invoke(RestFn.java:1523)
	at figwheel_sidecar.config$eval21$loading__5569__auto____22.invoke(config.clj:1)
	at figwheel_sidecar.config$eval21.invokeStatic(config.clj:1)
	at figwheel_sidecar.config$eval21.invoke(config.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6927)
	at clojure.lang.Compiler.eval(Compiler.java:6916)
	at clojure.lang.Compiler.load(Compiler.java:7379)
	at clojure.lang.RT.loadResourceScript(RT.java:372)
	at clojure.lang.RT.loadResourceScript(RT.java:363)
	at clojure.lang.RT.load(RT.java:453)
	at clojure.lang.RT.load(RT.java:419)
	at clojure.core$load$fn__5677.invoke(core.clj:5893)
	at clojure.core$load.invokeStatic(core.clj:5892)
	at clojure.core$load.doInvoke(core.clj:5876)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5697)
	at clojure.core$load_one.invoke(core.clj:5692)
	at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
	at clojure.core$load_lib.invokeStatic(core.clj:5736)
	at clojure.core$load_lib.doInvoke(core.clj:5717)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$load_libs.invokeStatic(core.clj:5774)
	at clojure.core$load_libs.doInvoke(core.clj:5758)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$require.invokeStatic(core.clj:5796)
	at clojure.core$require.doInvoke(core.clj:5796)
	at clojure.lang.RestFn.invoke(RestFn.java:436)
	at figwheel_sidecar.build_utils$eval15$loading__5569__auto____16.invoke(build_utils.clj:1)
	at figwheel_sidecar.build_utils$eval15.invokeStatic(build_utils.clj:1)
	at figwheel_sidecar.build_utils$eval15.invoke(build_utils.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6927)
	at clojure.lang.Compiler.eval(Compiler.java:6916)
	at clojure.lang.Compiler.load(Compiler.java:7379)
	at clojure.lang.RT.loadResourceScript(RT.java:372)
	at clojure.lang.RT.loadResourceScript(RT.java:363)
	at clojure.lang.RT.load(RT.java:453)
	at clojure.lang.RT.load(RT.java:419)
	at clojure.core$load$fn__5677.invoke(core.clj:5893)
	at clojure.core$load.invokeStatic(core.clj:5892)
	at clojure.core$load.doInvoke(core.clj:5876)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5697)
	at clojure.core$load_one.invoke(core.clj:5692)
	at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
	at clojure.core$load_lib.invokeStatic(core.clj:5736)
	at clojure.core$load_lib.doInvoke(core.clj:5717)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$load_libs.invokeStatic(core.clj:5774)
	at clojure.core$load_libs.doInvoke(core.clj:5758)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$require.invokeStatic(core.clj:5796)
	at clojure.core$require.doInvoke(core.clj:5796)
	at clojure.lang.RestFn.invoke(RestFn.java:930)
	at figwheel_sidecar.repl_api$eval9$loading__5569__auto____10.invoke(repl_api.clj:1)
	at figwheel_sidecar.repl_api$eval9.invokeStatic(repl_api.clj:1)
	at figwheel_sidecar.repl_api$eval9.invoke(repl_api.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6927)
	at clojure.lang.Compiler.eval(Compiler.java:6916)
	at clojure.lang.Compiler.load(Compiler.java:7379)
	at clojure.lang.RT.loadResourceScript(RT.java:372)
	at clojure.lang.RT.loadResourceScript(RT.java:363)
	at clojure.lang.RT.load(RT.java:453)
	at clojure.lang.RT.load(RT.java:419)
	at clojure.core$load$fn__5677.invoke(core.clj:5893)
	at clojure.core$load.invokeStatic(core.clj:5892)
	at clojure.core$load.doInvoke(core.clj:5876)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.core$load_one.invokeStatic(core.clj:5697)
	at clojure.core$load_one.invoke(core.clj:5692)
	at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
	at clojure.core$load_lib.invokeStatic(core.clj:5736)
	at clojure.core$load_lib.doInvoke(core.clj:5717)
	at clojure.lang.RestFn.applyTo(RestFn.java:142)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$load_libs.invokeStatic(core.clj:5774)
	at clojure.core$load_libs.doInvoke(core.clj:5758)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:648)
	at clojure.core$require.invokeStatic(core.clj:5796)
	at clojure.core$require.doInvoke(core.clj:5796)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at user$eval5.invokeStatic(form-init2907598702794002906.clj:1)
	at user$eval5.invoke(form-init2907598702794002906.clj:1)
	at clojure.lang.Compiler.eval(Compiler.java:6927)
	at clojure.lang.Compiler.eval(Compiler.java:6916)
	at clojure.lang.Compiler.load(Compiler.java:7379)
	at clojure.lang.Compiler.loadFile(Compiler.java:7317)
  1 (defproject reframe-todo "0.1.0-SNAPSHOT"
	at clojure.main$load_script.invokeStatic(main.clj:275)
	at clojure.main$init_opt.invokeStatic(main.clj:277)
	at clojure.main$init_opt.invoke(main.clj:277)
	at clojure.main$initialize.invokeStatic(main.clj:308)
	at clojure.main$null_opt.invokeStatic(main.clj:342)
	at clojure.main$null_opt.invoke(main.clj:339)
	at clojure.main$main.invokeStatic(main.clj:421)
	at clojure.main$main.doInvoke(main.clj:384)
	at clojure.lang.RestFn.invoke(RestFn.java:421)
	at clojure.lang.Var.invoke(Var.java:383)
	at clojure.lang.AFn.applyToHelper(AFn.java:156)
	at clojure.lang.Var.applyTo(Var.java:700)
	at clojure.main.main(main.java:37)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:466)
	at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:69)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:563)
	at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:375)
	at clojure.lang.RT.classForName(RT.java:2168)
	at clojure.lang.RT.classForNameNonLoading(RT.java:2181)
	at cljs.util$eval225$loading__5569__auto____226.invoke(util.cljc:9)
	at cljs.util$eval225.invokeStatic(util.cljc:9)
	at cljs.util$eval225.invoke(util.cljc:9)
	at clojure.lang.Compiler.eval(Compiler.java:6927)
	at clojure.lang.Compiler.eval(Compiler.java:6916)
	at clojure.lang.Compiler.load(Compiler.java:7379)
	... 181 more
Subprocess failed

It seems it's identical to bhauman/lein-figwheel#612

I managed to fix it by adding :jvm-opts ["--add-modules" "java.xml.bind"] to my project.clj but maybe it's worth to fix in the template? There is a fix to lein-figwheel here: bhauman/figwheel-template@627fa1d

How do I remove #?

Hello again.

It seems like this boilerplate uses hash router. The '#' is always present at the address bar. I have considered todomvc example that uses proper routing (without '#'), but when I try to use it with figwheel, it doesn't work and it says "Keep on figwheelin'".

So how do I remove # for both dev mode and production, the right way?

You added some of your temp files to the repo

It looks like a couple files were added that shouldn't have been, correct me if I'm wrong and they actually do server a purpose - I haven't written lein templates before.
src/leiningen/new/re-frame/test/cljs contains 2 extra files with a "~" suffix

Move to re-com 0.6.1

There's a new version of re-com out. It has new CSS and fonts.

Perhaps also switch to reagent 0.5.1 when it comes out too.

re-frisk Issue

Please see day8/re-frame#365 for original issue reported.

So using +re-frisk option and then lein cljsbuild once min (prod build) seems to do three things:

  1. Introduce a warning
  2. Cause the compile time to blow out significantly (15sec to 132sec on my machine)
  3. Apparently cause a lot of "metadata" to be added to the outputed js, where the OP describes "metadata" to be strings from his dev environment. Paths in strings.

I have replicated points 1 and 2, but not investigated 3, yet.

Couldn't find artifact on freshly created project

Hello!

I'm new to Clojurescript and I'm facing the strange issue. It seems like the re-frame\examples\simple and re-frame-template's dependencies are mostly similar, and simple runs just fine. But when I try to lein dev at freshly generated re-frame template, I get the following:

Figwheel: Cutting some fruit, just a sec ...
Compiling Garden...
Could not find artifact org.clojure:clojure:jar:1.8.0
Could not find artifact org.clojure:clojurescript:jar:1.9.908
Could not find artifact reagent:reagent:jar:0.7.0
Could not find artifact re-frame:re-frame:jar:0.10.2
Could not find artifact secretary:secretary:jar:1.2.3
Could not find artifact garden:garden:jar:1.3.2
Could not find artifact org.clojure:tools.nrepl:jar:0.2.12
Could not find artifact clojure-complete:clojure-complete:jar:0.2.4
Could not find artifact binaryage:devtools:jar:0.9.4
This could be due to a typo in :dependencies, file system permissions, or network issues.
If you are behind a proxy, try setting the 'http_proxy' environment variable.

I generated the project with aliases, garden and routes.

I run Elementary (ubuntu) with sudo, and simple example runs just fine.
I removed ~/.m2 and did lein dev again, with same result (it didn't worked)

Thank you in advance!

Use lein doo for testing

doo is a good test runner for ClojureScript testing. It would be good to add this to the re-frame template to get others set up with it easily.

compatibility with elixir phoenix

Hi! Thank you for re-frame.
This is not so much an issue as an offer to help.

I think it would be pretty easy to make a version of this lein template that was compatible with http://www.phoenixframework.org/

Basically, there's no need for:
resources/public/index.html
and the clj/cljs directories need to be rooted in web/static
and the build output dir is priv/static/js/cljs

Like this:

(defproject my-example "0.1.0-SNAPSHOT"
  clj.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.8.51"]
                 [reagent "0.5.1"]
                 [binaryage/devtools "0.6.1"]
                 [re-frame "0.7.0"]]

  :plugins [[lein-cljsbuild "1.1.3"]]

  :min-lein-version "2.5.3"

  :source-paths ["web/static/clj"]

  :clean-targets ^{:protect false} ["priv/static/js/cljs" "priv/static/js/cljs-adv" "target"]

  :figwheel {:css-dirs ["priv/static/css"]}

  :profiles
  {:dev
   {:dependencies []

    :plugins      [[lein-figwheel "0.5.4-3"]]
    }}

  :cljsbuild
  {:builds
   [{:id           "dev"
     :source-paths ["web/static/cljs"]
     :figwheel     {:on-jsload "my-example.core/mount-root"}
     :compiler     {:main                 my-example.core
                    :output-to            "priv/static/js/cljs/app.js"
                    :output-dir           "priv/static/js/cljs"
                    :asset-path           "js/cljs"
                    :source-map-timestamp true}}

    {:id           "min"
     :source-paths ["web/static/cljs"]
     :compiler     {:main            my-example.core
                    :output-to       "priv/static/js/cljs/app.js"
                    :optimizations   :advanced
                    :closure-defines {goog.DEBUG false}
                    :pretty-print    false}}

    ]}

  )

I could make a version of this template that did all that (and presumably there would be a way to share it), but I'm not precisely sure how best to do it. This template has all of re-frame in, near as I can tell... Not sure what to do about that... And then even if it were duplicated (assuming that were remotely kosher), how to reliably keep it up to date.

Once these changes are done and the generated code is moved to the correct directory, everything is grand. When you run lein figwheel dev while the phoenix server is running it all connects and you get a live repl even without any of the stuff in the resources directory. Swell!

Anyway, with a little guidance, I'm happy to put something together that others can use and that has a good out of box with phoenix. People are excited about phoenix and for good reason. Some people are using Elm, but I'm not one of them currently :). I think supporting re-frame/clojurescript on phoenix could potentially be a popular and sensible option. It'd be great if people could try it without the fussing around.

Thanks, again.

cljs-devtools not working

Hi Day8 team,

First off thanks for the wonderful work with the template here 👍

I'd like to report that I am using latest chromium on macOS High Sierra and I'm unable to see cljs-devtools console in my development envrionment. I have followed the instructions carefully and made the necessary changes in the devTools settings

screen shot 2018-12-01 at 10 40 21

Could you please guide me here a bit ?

Add useful aliases

I use following aliases to make development easier, to build all assets by a single lein command:

  :aliases {"dev" ["do" "clean"
                        ["pdo" ["figwheel" "dev"]
                               ["less" "auto"]]]
            "build" ["do" "clean"
                          ["cljsbuild" "once" "min"]
                          ["less" "once"]]}

Would you be interested to add these into the template?

Update dependencies

Had an issue when using this template and running lein figwheel dev.

Figwheel: Cutting some fruit, just a sec ...
Exception in thread "main" java.lang.RuntimeException: Reader tag must be a symbol, compiling:(/tmp/form-init16732808283675063374.clj:1:1444)

I used lein ancient upgrade :check-clojure to update dependencies and that sorted it.

-  :dependencies [[org.clojure/clojure "1.8.0"]
-                 [org.clojure/clojurescript "1.10.238"]
-                 [reagent "0.7.0"]
-                 [re-frame "0.10.5"]]
+  :dependencies [[org.clojure/clojure "1.10.0"]
+                 [org.clojure/clojurescript "1.10.520"]
+                 [reagent "0.8.1"]
+                 [re-frame "0.10.6"]]

Add Dirac as Optional Profile

Dirac goes beyond cljs-devtools with a full REPL and debugging etc.

Should be an optional profile, not required, as it is not a beginner tool.

Missing `.gitignore` file

I can't generate a new project with versions 0.3.18 nor 0.3.19 while I could with version 0.3.17. Lein complains about missing .gitignore:

/tmp/tmp.pSuoH3t7VH 
❯ lein new re-frame my-proj                                               
Retrieving re-frame/lein-template/0.3.19/lein-template-0.3.19.pom from clojars
Retrieving re-frame/lein-template/0.3.19/lein-template-0.3.19.jar from clojars
Generating re-frame project.
Template resource 'leiningen/new/re_frame/.gitignore' not found.

/tmp/tmp.pSuoH3t7VH 
❯ ls -ahl
total 0

/tmp/tmp.pSuoH3t7VH 
❯ lein new re-frame my-proj --template-version "0.3.18"                          
Retrieving re-frame/lein-template/0.3.18/lein-template-0.3.18.pom from clojars
Retrieving re-frame/lein-template/0.3.18/lein-template-0.3.18.jar from clojars
Generating re-frame project.
Template resource 'leiningen/new/re_frame/.gitignore' not found.

/tmp/tmp.pSuoH3t7VH 
❯ ls -ahl
total 0

/tmp/tmp.pSuoH3t7VH 
❯ lein new re-frame my-proj --template-version "0.3.17"
Generating re-frame project.

/tmp/tmp.pSuoH3t7VH 
❯ ls -ahl
total 0
drwxr-xr-x 4 galaux users 140 Mar 11 14:52 my-proj

Inspecting the tarballs shows they do not have the .gitignore file.

lein-figwheel 0.5.3 fails to start

re-frame-template currently configures a new project with lein-figwheel 0.5.3 but there seems to be a problem with that version.

Replacing the version of lein-figwheel in the generated project with the latest version (0.5.4-3) fixes the problem.

Please consider updating re-frame-template to the latest version of lein-figwheel.

Steps to recreate

Follow usual steps to create a new project:
lein new re-frame <project-name>

Change to project folder, then:
lein clean
lein figwheel dev

This fails with exception:
clojure.lang.Compiler$CompilerException: java.io.FileNotFoundException: Could not locate fipp/visit__init.class or fipp/visit.clj on classpath., compiling:(figwheel_sidecar/config_check/type_check.clj:1:1)
stacktrace.txt

Workaround

Open project.clj and replace [lein-figwheel "0.5.3"] with [lein-figwheel "0.5.4-3"]

Do
lein clean
lein figwheel dev

Deploy to heroku doesn't work with +10x profile generated project.

I get this exception:

remote:        Compiling ["resources/public/js/compiled/app.js"] failed.
remote:        clojure.lang.ExceptionInfo: failed compiling file:/tmp/build_deac098dd63d4bfb3506640e8f2dad2f/src/cljs/ccsoli2/events.cljs {:file #object[java.io.File 0x225fc6a2 "/tmp/build_deac098dd63d4bfb3506640e8f2dad2f/src/cljs/ccsoli2/events.cljs"]}
remote:        	at clojure.core$ex_info.invokeStatic(core.clj:4617)
remote:        	at clojure.core$ex_info.invoke(core.clj:4617)
remote:        	at cljs.compiler$compile_file$fn__3702.invoke(compiler.cljc:1562)
remote:        	at cljs.compiler$compile_file.invokeStatic(compiler.cljc:1522)
remote:        	at cljs.compiler$compile_file.invoke(compiler.cljc:1498)
remote:        	at cljs.closure$compile_file.invokeStatic(closure.clj:573)
remote:        	at cljs.closure$compile_file.invoke(closure.clj:564)
remote:        	at cljs.closure$fn__5124.invokeStatic(closure.clj:653)
remote:        	at cljs.closure$fn__5124.invoke(closure.clj:647)
remote:        	at cljs.closure$fn__5052$G__5045__5059.invoke(closure.clj:521)
remote:        	at cljs.closure$fn__5128.invokeStatic(closure.clj:662)
remote:        	at cljs.closure$fn__5128.invoke(closure.clj:647)
remote:        	at cljs.closure$fn__5052$G__5045__5059.invoke(closure.clj:521)
remote:        	at cljs.closure$compile_sources$iter__5250__5254$fn__5255.invoke(closure.clj:1011)
remote:        	at clojure.lang.LazySeq.sval(LazySeq.java:40)
remote:        	at clojure.lang.LazySeq.seq(LazySeq.java:49)
remote:        	at clojure.lang.Cons.next(Cons.java:39)
remote:        	at clojure.lang.RT.next(RT.java:688)
remote:        	at clojure.core$next__4341.invokeStatic(core.clj:64)
remote:        	at clojure.core$dorun.invokeStatic(core.clj:3033)
remote:        	at clojure.core$doall.invokeStatic(core.clj:3039)
remote:        	at clojure.core$doall.invoke(core.clj:3039)
remote:        	at cljs.closure$compile_sources.invokeStatic(closure.clj:1007)
remote:        	at cljs.closure$compile_sources.invoke(closure.clj:996)
remote:        	at cljs.closure$build.invokeStatic(closure.clj:2817)
remote:        	at cljs.closure$build.invoke(closure.clj:2718)
remote:        	at cljs.build.api$build.invokeStatic(api.clj:208)
remote:        	at cljs.build.api$build.invoke(api.clj:189)
remote:        	at cljs.build.api$build.invokeStatic(api.clj:195)
remote:        	at cljs.build.api$build.invoke(api.clj:189)
remote:        	at cljsbuild.compiler$compile_cljs$fn__550.invoke(compiler.clj:61)
remote:        	at cljsbuild.compiler$compile_cljs.invokeStatic(compiler.clj:60)
remote:        	at cljsbuild.compiler$compile_cljs.invoke(compiler.clj:48)
remote:        	at cljsbuild.compiler$run_compiler.invokeStatic(compiler.clj:168)
remote:        	at cljsbuild.compiler$run_compiler.invoke(compiler.clj:129)
remote:        	at user$eval665$iter__701__705$fn__706$fn__724.invoke(form-init641934052571790955.clj:1)
remote:        	at user$eval665$iter__701__705$fn__706.invoke(form-init641934052571790955.clj:1)
remote:        	at clojure.lang.LazySeq.sval(LazySeq.java:40)
remote:        	at clojure.lang.LazySeq.seq(LazySeq.java:49)
remote:        	at clojure.lang.RT.seq(RT.java:521)
remote:        	at clojure.core$seq__4357.invokeStatic(core.clj:137)
remote:        	at clojure.core$dorun.invokeStatic(core.clj:3024)
remote:        	at clojure.core$doall.invokeStatic(core.clj:3039)
remote:        	at clojure.core$doall.invoke(core.clj:3039)
remote:        	at user$eval665.invokeStatic(form-init641934052571790955.clj:1)
remote:        	at user$eval665.invoke(form-init641934052571790955.clj:1)
remote:        	at clojure.lang.Compiler.eval(Compiler.java:6927)
remote:        	at clojure.lang.Compiler.eval(Compiler.java:6917)
remote:        	at clojure.lang.Compiler.load(Compiler.java:7379)
remote:        	at clojure.lang.Compiler.loadFile(Compiler.java:7317)
remote:        	at clojure.main$load_script.invokeStatic(main.clj:275)
remote:        	at clojure.main$init_opt.invokeStatic(main.clj:277)
remote:        	at clojure.main$init_opt.invoke(main.clj:277)
remote:        	at clojure.main$initialize.invokeStatic(main.clj:308)
remote:        	at clojure.main$null_opt.invokeStatic(main.clj:342)
remote:        	at clojure.main$null_opt.invoke(main.clj:339)
remote:        	at clojure.main$main.invokeStatic(main.clj:421)
remote:        	at clojure.main$main.doInvoke(main.clj:384)
remote:        	at clojure.lang.RestFn.invoke(RestFn.java:421)
remote:        	at clojure.lang.Var.invoke(Var.java:383)
remote:        	at clojure.lang.AFn.applyToHelper(AFn.java:156)
remote:        	at clojure.lang.Var.applyTo(Var.java:700)
remote:        	at clojure.main.main(main.java:37)
remote:        Caused by: clojure.lang.ExceptionInfo: No such namespace: day8.re-frame.tracing, could not locate day8/re_frame/tracing.cljs, day8/re_frame/tracing.cljc, or JavaScript source providing "day8.re-frame.tracing" in file /tmp/build_deac098dd63d4bfb3506640e8f2dad2f/src/cljs/ccsoli2/events.cljs {:tag :cljs/analysis-error}
remote:        	at clojure.core$ex_info.invokeStatic(core.clj:4617)
remote:        	at clojure.core$ex_info.invoke(core.clj:4617)
remote:        	at cljs.analyzer$error.invokeStatic(analyzer.cljc:697)
remote:        	at cljs.analyzer$error.invoke(analyzer.cljc:693)
remote:        	at cljs.analyzer$error.invokeStatic(analyzer.cljc:695)
remote:        	at cljs.analyzer$error.invoke(analyzer.cljc:693)
remote:        	at cljs.analyzer$analyze_deps.invokeStatic(analyzer.cljc:2129)
remote:        	at cljs.analyzer$analyze_deps.invoke(analyzer.cljc:2103)
remote:        	at cljs.analyzer$ns_side_effects.invokeStatic(analyzer.cljc:3476)
remote:        	at cljs.analyzer$ns_side_effects.invoke(analyzer.cljc:3471)
remote:        	at cljs.analyzer$analyze_STAR_$fn__2510.invoke(analyzer.cljc:3596)
remote:        	at clojure.lang.PersistentVector.reduce(PersistentVector.java:341)
remote:        	at clojure.core$reduce.invokeStatic(core.clj:6544)
remote:        	at clojure.core$reduce.invoke(core.clj:6527)
remote:        	at cljs.analyzer$analyze_STAR_.invokeStatic(analyzer.cljc:3596)
remote:        	at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:3586)
remote:        	at cljs.analyzer$analyze.invokeStatic(analyzer.cljc:3616)
remote:        	at cljs.analyzer$analyze.invoke(analyzer.cljc:3598)
remote:        	at cljs.compiler$emit_source.invokeStatic(compiler.cljc:1386)
remote:        	at cljs.compiler$emit_source.invoke(compiler.cljc:1365)
remote:        	at cljs.compiler$compile_file_STAR_$fn__3672.invoke(compiler.cljc:1467)
remote:        	at cljs.compiler$with_core_cljs.invokeStatic(compiler.cljc:1285)
remote:        	at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1274)
remote:        	at cljs.compiler$compile_file_STAR_.invokeStatic(compiler.cljc:1451)
remote:        	at cljs.compiler$compile_file_STAR_.invoke(compiler.cljc:1444)
remote:        	at cljs.compiler$compile_file$fn__3702.invoke(compiler.cljc:1547)
remote:        	... 60 more
remote:        Uberjar aborting because jar failed: Subprocess failed
remote:  !     Failed to build.
remote:  !     Push rejected, failed to compile Clojure (Leiningen 2) app.
remote:
remote:  !     Push failed

When i create a fresh project using this:

lein new re-frame ccsoli2 +less +10x +test +aliases +handler +routes +re-pressed +re-com

However when i create a project without +10x:

lein new re-frame ccsoli3 +less +re-frisk +test +aliases +handler +routes +re-pressed +re-com

It works correctly.

My guess is

Caused by: clojure.lang.ExceptionInfo: No such namespace: day8.re-frame.tracing, could not locate day8/re_frame/tracing.cljs, day8/re_frame/tracing.cljc, or JavaScript source providing "day8.re-frame.tracing" in file /tmp/build_deac098dd63d4bfb3506640e8f2dad2f/src/cljs/ccsoli2/events.cljs {:tag :cljs/analysis-error}

Is because of the day8.re-frame/tracing-stubs replacing the tracing.cljc in the

:prod { :dependencies [[day8.re-frame/tracing-stubs "0.5.1"]]}

Part of the project.clj.

Easy repro steps.
lein new re-frame ccsoli3 +less +10x +test +aliases +handler +routes +re-pressed +re-com
heroku create
git push heroku master

Then just remove the +10x for a new project and it works.

Use .dir-locals?

The README says

Put this in your Emacs config file:

(setq cider-cljs-lein-repl "(do (use 'figwheel-sidecar.repl-api) (start-figwheel!) (cljs-repl))")

Instead of making users manually set cider-cljs-lein-repl and manage conflicts between projects that require different values for that variable, what do you think about adding a .dir-locals.el file, like the chestnut template does?

Besides avoiding conflicts, it would also mean one less manual step is required before being able to use the generated project.

Sente option?

Feel like sente fits into this picture like a glove on a hand. Would be nice to have that as an option.

Why not add garden :prep-task to compile CSS on first lein startup?

When starting a re-frame-template project for the first time browser is unable to find screen.css since it hasn't yet been compiled producing this error to be shown in browser console:

GET http://localhost:3449/css/compiled/screen.css 

Adding

:prep-tasks [["garden" "once"]]

to project.clj could resolve this.

Figwheel Client and Server have different versions!!

Error message:

Figwheel Client Version 0.5.9 is not equal to Figwheel Sidecar Version 0.5.13. Shutting down Websocket Connection!
To fix try:
Reload this page and make sure you are not getting a cached version of the client.
You may have to clean (delete compiled assets) and rebuild to make sure that the new client code is being used.
Also, make sure you have consistent Figwheel dependencies.

binaryage/devtools compiled to min code

core.cljs has some devtools code , min compile file size 580kb

I comment out devtools related code , min compile file size 340kb

(ns re-frame-app.core
    (:require [reagent.core :as reagent]
              [re-frame.core :as re-frame]
              ;; [devtools.core :as devtools]
              [re-frame-app.handlers]
              [re-frame-app.subs]
              [re-frame-app.views :as views]
              [re-frame-app.config :as config]))

;; (defn dev-setup []
;;   (when config/debug?
;;     (enable-console-print!)
;;     (println "dev mode")
;;     (devtools/install!)))

(defn mount-root []
  (reagent/render [views/main-panel]
                  (.getElementById js/document "app")))

(defn ^:export init []
  (re-frame/dispatch-sync [:initialize-db])
  ;; (dev-setup)
  (mount-root))

a better way to include devtools would be:

{:id           "dev"
     :source-paths ["src/cljs"]
     :figwheel     {:on-jsload "re-frame-app.core/mount-root"}
     :compiler     {:main                 re-frame-app.core
                    :preloads             [devtools.preload]
                    :external-config      {:devtools/config {:features-to-install :all}}
                    :output-to            "resources/public/js/compiled/app.js"
                    :output-dir           "resources/public/js/compiled/out"
                    :asset-path           "js/compiled/out"
                    :source-map-timestamp true}}

NullPointerException on 'lean new re-frame foo'

I get a NullPointerException when trying to create a new reframe project. See stack trace, below.

Davids-MacBook-Pro:clojure dave$ lein new re-frame foo
java.lang.NullPointerException: null
 at clojure.core$apply.invokeStatic (core.clj:648)
    clojure.core$apply.invoke (core.clj:641)
    leiningen.new$create.invokeStatic (new.clj:81)
    leiningen.new$create.doInvoke (new.clj:57)
    clojure.lang.RestFn.invoke (RestFn.java:425)
    clojure.lang.AFn.applyToHelper (AFn.java:156)
    clojure.lang.RestFn.applyTo (RestFn.java:132)
    clojure.core$apply.invokeStatic (core.clj:650)
    clojure.core$apply.invoke (core.clj:641)
    leiningen.new$new.invokeStatic (new.clj:204)
    leiningen.new$new.doInvoke (new.clj:134)
    clojure.lang.RestFn.invoke (RestFn.java:439)
    clojure.lang.Var.invoke (Var.java:388)
    clojure.lang.AFn.applyToHelper (AFn.java:160)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.core$apply.invokeStatic (core.clj:648)
    clojure.core$apply.invoke (core.clj:641)
    leiningen.core.main$partial_task$fn__4667.doInvoke (main.clj:284)
    clojure.lang.RestFn.applyTo (RestFn.java:139)
    clojure.lang.AFunction$1.doInvoke (AFunction.java:29)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:648)
    clojure.core$apply.invoke (core.clj:641)
    leiningen.core.main$apply_task.invokeStatic (main.clj:334)
    leiningen.core.main$apply_task.invoke (main.clj:320)
    leiningen.core.main$resolve_and_apply.invokeStatic (main.clj:340)
    leiningen.core.main$resolve_and_apply.invoke (main.clj:336)
    leiningen.core.main$_main$fn__4734.invoke (main.clj:420)
    leiningen.core.main$_main.invokeStatic (main.clj:411)
    leiningen.core.main$_main.doInvoke (main.clj:408)
    clojure.lang.RestFn.invoke (RestFn.java:436)
    clojure.lang.Var.invoke (Var.java:388)
    clojure.lang.AFn.applyToHelper (AFn.java:160)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.core$apply.invokeStatic (core.clj:646)
    clojure.main$main_opt.invokeStatic (main.clj:314)
    clojure.main$main_opt.invoke (main.clj:310)
    clojure.main$main.invokeStatic (main.clj:421)
    clojure.main$main.doInvoke (main.clj:384)
    clojure.lang.RestFn.invoke (RestFn.java:482)
    clojure.lang.Var.invoke (Var.java:401)
    clojure.lang.AFn.applyToHelper (AFn.java:171)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.main.main (main.java:37)

Adding posh option

Tried to add posh as an option.

After installing lein install from target folder of template build output

^C✘-INT ~/repos/clojure-projs/fun 
10:11 $ lein new re-frame +posh
clojure.lang.ExceptionInfo: Attempt to close section out of order: re-com? at line 7, column 44
 at stencil.parser$parse_tag.invoke (parser.clj:258)
(defproject {{ns-name}} "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [org.clojure/clojurescript "1.7.170"]
                 [reagent "0.6.0-alpha"]
                 [re-frame "0.7.0-alpha"]{{#re-com?}}
                 [posh "0.3.4"]{{#posh?}}
---> line 7 [re-com "0.8.0"]{{/re-com?}}{{#routes?}}
                 [secretary "1.2.3"]{{/routes?}}{{#garden?}}
                 [garden "1.3.1"]{{/garden?}}{{#handler?}}
                 [compojure "1.4.0"]
                 [ring "1.4.0"]{{/handler?}}]

I'm just guessing here... what does {{#posh?}} do? how do I fix it?
This is my posh options file:

(ns leiningen.new.options.posh
  (:require [leiningen.new.options.helpers :as helpers]))

(def option "posh")

(defn files [data]
  [["src/clj/{{sanitized}}/conn.clj" (helpers/render "src/cljs/conn.cljs" data)]
   ["src/clj/{{sanitized}}/queries.clj" (helpers/render "src/cljs/queries.cljs" data)]])

println doesn't work out of the box

The other day I had to quickly run up a test, and I turned to this template ... but my printlns didn't work.
Easily fixed, of course, just add this to core.cljs:

(enable-console-print!)

But I wondered, for the sake of cljs newbies, should we make that happen by default??

Happy to be shouted down, but wondered.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.