0

I am following guestbook example from the book Web Development With Clojure 3rd edition. I am struggling with including ClojureScript namespace into HTML document. Everything is working fine with example where I have one core.cljs. With that file, only I have to do is to include this piece of code into home.html document:

{% extends "base.html" %}
{% block content %}
<input id="token" type="hidden" value="{{csrf-token}}">
<div id="content"></div>
{% endblock %}
{% block page-scripts %}
{% script "/js/app.js" %}
{% endblock %}

As I mentioned, everything is ok in this situation. But when I created additional ClojureScript file and name it test.cljs and included that in the same way in the new HTML document named test.html I see errors in the console such as "Target container is not a DOM element.". I think that something is wrong with this part:

{% block page-scripts %}
{% script "/js/app.js" %}
{% endblock %}

But I can't figure out how to solve this. Actually, my question maybe should be: How to include ClojureScript into HTML file?. Is the only way this piece of code?

{% block page-scripts %}
{% script "/js/app.js" %}
{% endblock %}

Or, maybe I should change {% script "/js/app.js" %} part of this snippet?

Or even better, when I create simple HTML file without extending any base.html file, how to add clojurescript namespace, how to reference it? You know, like javascript helloworld example

<script src="myscripts.js"></script>

How to do this in ClojureScript? I am using Luminus framework.

1
  • Please edit your question to include as many details as possible: what tool and command line did you use to create your project? How are you building it? Also, try copying and pasting directly any output messages. From the error alone it seems it could be a duplicate of stackoverflow.com/q/47244575/483566 ... the error seemed to be related to a malformed HTML document, not the compiled JavaScript. Commented Mar 21, 2020 at 23:46

1 Answer 1

1

In general, a Luminus project with ClojureScript support will compile all ClojureScript code into a single app.js file, as in this block of the project.clj file (from a project I just created with lein new luminus guestbook +h2 +immutant +cljs, where the +cljs is the important bit):

                  :cljsbuild{:builds
                   {:app
                    {:source-paths ["src/cljs" "src/cljc" "env/dev/cljs"]
                     :figwheel {:on-jsload "guestbook.core/mount-components"}
                     :compiler
                     {:main "guestbook.app"
                      :asset-path "/js/out"
                      :output-to "target/cljsbuild/public/js/app.js" ;; <= THIS
                      :output-dir "target/cljsbuild/public/js/out"
                      :source-map true
                      :optimizations :none
                      :pretty-print true}}}}

That's a very convenient default for single page apps (a la Angular or React), but I think you are thinking of a website with different HTML pages, each one including a different JavaScript file (in this case, everything is compiled to a single JavaScript file).

If you want to call different functions (eg. from different namespaces), you'll need to export them (to make them easily available from JavaScript) and then call each function in their respective HTML file, a bit like the following:

...
<!-- in test.html -->
{% script "/js/app.js" %}
<script>
guestbook.test.init();
</script>
...

in src/cljs/guestbook/test.cljs

(ns guestbook.test)

(defn mount-components []
  (let [content (js/document.getElementById "app")]
    (while (.hasChildNodes content)
      (.removeChild content (.-lastChild content)))
    (.appendChild content (js/document.createTextNode "Welcome to the test page"))))

(defn ^:export init []
  (mount-components))

Also, remember to rebuild your ClojureScript files. You can leave another terminal running the following command to recompile any ClojureScript files when they change: lein cljsbuild auto

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.