如何从具有多级路径的页面加载ClojureScript输出?

时间:2016-07-31 18:29:52

标签: clojure clojurescript

我正在使用Boot开发单页webapp。它最初是从Holy Grail example开始的。

我的Compojure路线定义如下:

(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"))

请注意"/*"路线中的星标:我希望所有请求都返回index.html,并且ClojureScript部分处理实际路线。

我在开发模式下运行应用程序,这里是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)))

适用于单级路径,例如localhost:3000/test。但是,对于具有多级路径的页面,它会破坏,例如, localhost:3000/foo/bar

加载JavaScript的index.html部分如下所示:

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

最初它是src="main.js",但我添加了前导斜杠,因此它从多级页面中找到main.js。如果没有斜杠,浏览器可能会在目录[somewhere-in-cljs-output]/foo/main.js中查找该文件,假设页面为localhost:3000/foo/bar

现在,main.js由ClojureScript编译器生成,现在它是:

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>');

当它在页面localhost:3000/foo/bar上运行时,我会看到警告。

显然问题与原始main.js引用相同,因为所需JavaScript文件的路径是相对的,而不是绝对的。我怎样才能让它们变得绝对?

我想我必须在cljs更改build.boot任务调用,但不知道怎么做,因为我的Boot工作原理模型非常不稳定。

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:2)

稍微修补导致dev build.boot (cljs :source-map true :compiler-options {:asset-path "/main.out"}) 任务发生以下变化:

@Injectable()
export class MyService {

  constructor(private _myApiService:MyAPIService) {
  }

  public getCarsData():Observable<Car[]> {
    return this._myApiService.getCurrentCarData().map(res => res.carList);
  }

}