Использование каталога resources/public в проекте boot-clj

Я пытаюсь настроить загрузочный проект, который использует каталог ресурсов, содержащий публичный подкаталог. Последний должен содержать, например, весь веб-контент, скомпилированный сценарий clojurescript и т. Д.

Это имеет смысл для случая, когда вы хотите хранить ресурсы, которые не предназначены для публичного показа.

Он отлично работает, когда делает это без дополнительного публичного каталога. При попытке использовать дополнительный подкаталог я получаю ошибки. Вот соответствующие конфигурации:

В build.boot:

(set-env! :resource-paths #{"resources"} ...)

...

(deftask dev
  []
  (comp
   (serve
    :handler 'myapp.server/handler
    :reload true
    :port 3000)
   (watch)
   (reload)
   (cljs-repl)
   (cljs)
   (target :dir #{"resources/public"})))

Из каталога ресурсов:

bash-4.3$ tree
└── public
    ├── index.html
    └── js
        └── main.cljs.edn

Тогда как main.cljs.edn выглядит так:

{:require [{{name}}.core]
 :compiler-options {:asset-path "js/main.out"}}

При вызове boot dev происходит следующее: ClojureScript продолжает компиляцию с ошибками, пока процесс не будет остановлен вручную. Это похоже на рекурсивную ошибку, связанную с некоторыми относительными путями.

Compiling ClojureScript...
• public/js/main.js
Writing target dir(s)...
java.util.concurrent.ExecutionException: java.nio.file.NoSuchFileException: resources/public/public/public/js/main.out/goog/deps.js

в то время как чем дольше он продолжает работать public/public/public/.. расширяется.

Кто-нибудь предлагает, где это можно исправить?


Обновить

Вот обновленная версия вопроса:

Рассмотрим следующую структуру папки ресурсов:

bash-4.3$ tree
└── private_file.txt
└── public
    ├── index.html
    └── js
        └── main.cljs.edn

И следующие части из build.boot:

   (set-env! :resource-paths #{"resources"} ...)

   (deftask dev
      []
      (comp
       (serve
        :handler 'myapp.server/handler
        :reload true
        :port 3000)
       (watch)
       (reload)
       (cljs-repl)
       (cljs)
       (target)))

'myapp.server / handler знает, что нужно просто обслуживать файлы из ресурсов / public (реализовано wrap-resource или эквивалентный состав resources, Позднее даже по умолчанию "частный".

Но проблема возникает еще раньше: при запуске boot dev весь каталог ресурсов воспроизводится в целевом каталоге, включая private_file.txt конечно. (это предполагаемое поведение? Я имею в виду, что файл может быть довольно большим, и тогда он будет занимать вдвое больше места на диске)

На данный момент я не уверен, как: asset-path изнутри main влияет на это. В этом примере я сохранил его как "js/main.out", что может быть неверно.

1 ответ

Решение

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

(target :dir #{"resources/public"})

Я бы оставил его по умолчанию:

(target :dir #{"target"})

что эквивалентно просто

(target)

Как вы используете serve задача с предоставлением собственного обработчика звонков ('myapp.server/handler) вы также должны убедиться, что ваш обработчик будет обслуживать ресурсы из вашего classpath, указав правильный корневой каталог в вашем classpath ("public"). Вероятно, вы уже используете ring.middleware.resource/wrap-resourceкак это:

(wrap-resource handler "public")

Последняя вещь твояmain.cljs.ednфайл. это:asset-path должен быть установлен вjs как это должно быть относительный путь к файлам JS, обслуживаемым вашим сервером / обработчиком (файлы из target/public/js будет подан http://localhost:xxxx/js).

С помощью этой настройки ваши исходные файлы (HTML, CSS и другие файлы из resources/public) а также файлы, сгенерированные такими задачами, как cljs в target/public должен быть доступен в вашем браузере.

Другие вопросы по тегам