Использование каталога 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
должен быть доступен в вашем браузере.