Как включить ClojureScript в страницу HTML? - PullRequest
0 голосов
/ 22 марта 2020

Я следую примеру гостевой книги из книги Веб-разработка с Clojure, 3-е издание. Я борюсь с включением пространства имен ClojureScript в документ HTML. Все работает нормально с примером, где у меня есть один core.cl js. С этим файлом нужно только включить этот фрагмент кода в дом. 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 %}

Как я уже говорил, в этой ситуации все в порядке. Но когда я создал дополнительный файл ClojureScript и назвал его test.cl js и включил его таким же образом в новый документ HTML с именем test. html Я вижу ошибки в консоли, такие как «Целевой контейнер не является Элемент DOM. " Я думаю, что с этой частью что-то не так:

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

Но я не могу понять, как это решить. На самом деле, мой вопрос может быть следующим: как включить ClojureScript в файл HTML? Является ли единственным способом этот фрагмент кода?

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

Или, может быть, мне следует изменить {% script "/js/app.js"%} часть этого фрагмента?

Или даже лучше, когда я создаю простой файл HTML без расширения базового файла. html, как добавить пространство имен clojurescript, как ссылаться на него? Вы знаете, как javascript пример helloworld

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

Как это сделать в ClojureScript? Я использую Luminus Framework.

1 Ответ

1 голос
/ 22 марта 2020

В общем, проект Luminus с поддержкой ClojureScript будет компилировать весь код ClojureScript в один файл app.js, как в этом блоке файла project.clj (из проекта, который я только что создал с lein new luminus guestbook +h2 +immutant +cljs, где +cljs - важный бит):

                  :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}}}}

Это очень удобное значение по умолчанию для одностраничных приложений (например, Angular или React), но я думаю, что вы думаете о веб-сайте с другим HTML страниц, каждая из которых включает в себя отдельный файл JavaScript (в этом случае все скомпилировано в один файл JavaScript).

Если вы хотите вызывать разные функции (например, из разных пространств имен), вы Вам нужно будет их экспортировать (чтобы они были легко доступны из JavaScript), а затем вызывать каждую функцию в соответствующем файле HTML, примерно так:

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

в 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))

Кроме того, не забудьте перестроить файлы ClojureScript. Вы можете оставить другой терминал, выполняющий следующую команду, чтобы перекомпилировать любые файлы ClojureScript при их изменении: lein cljsbuild auto

...