简体   繁体   中英

How to load ClojureScript output from a page with multi-level path?

I'm developing a single-page webapp using Boot. It originally started from the Holy Grail example .

My Compojure routes are defined like this:

(defroutes routes
  ; sente
  (GET  "/chsk"  req ((:ring-ajax-get-or-ws-handshake (:sente system)) req))
  (POST "/chsk"  req ((:ring-ajax-post (:sente system)) req))
  ; everything else
  (GET "/*" [] (-> (resource-response "/index.html")
                   (content-type "text/html")))
  ; vestige of old times
  (route/not-found "Not Found"))

Note the star in the "/*" route: I want all requests to return index.html , with the ClojureScript part handling the actual routes.

I'm running the application in the dev mode, here's a snippet from build.boot :

(deftask dev
  "Run a restartable system in the Repl"
  []
  (comp
   (environ :env {:http-port "3000"})
   (watch :verbose true)
   (system :sys #'dev-system :auto true :files ["handler.clj"])
   (reload :on-jsload 'myapp.core/init!)
   (cljs :source-map true)
   (repl :server true :init-ns 'myapp.user)))

It works well for single-level paths, like localhost:3000/test . It breaks, though, for the pages with mult-level paths, eg localhost:3000/foo/bar .

The part of index.html that loads JavaScript looks like this:

<body>
    <div id="container"></div>
    <script type="text/javascript" src="/main.js"></script>
</body>

Originally it was src="main.js" , but I've added the leading slash so it finds main.js from a multi-level page. Without the slash, the browser probably looks for the file in the directory [somewhere-in-cljs-output]/foo/main.js , assuming the page localhost:3000/foo/bar .

Now, main.js is generated by ClojureScript compiler, and here it is:

var CLOSURE_UNCOMPILED_DEFINES = null;
if(typeof goog == "undefined") document.write('<script src="main.out/goog/base.js"></script>');
document.write('<script src="main.out/cljs_deps.js"></script>');
document.write('<script>if (typeof goog != "undefined") { goog.require("boot.cljs.main26293"); } else { console.warn("ClojureScript could not load :main, did you forget to specify :asset-path?"); };</script>');

When it runs on a page localhost:3000/foo/bar , I see the warning.

Apparently the problem's the same as with the original main.js reference, in that the paths of required JavaScript files are relative, not absolute. How do I get them to be absolute?

I think I have to change the cljs task invocation in build.boot , but not sure how, because my mental model of how Boot works is very spotty.

Any help appreciated.

A little tinkering led to the following change in the dev task of build.boot :

   (cljs :source-map true
         :compiler-options {:asset-path "/main.out"})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM