如何部署 clojurescript 试剂应用程序?

How do you deploy a clojurescript reagent app?

将问题简化为最简单的形式:

$ lein new reagent experiment
$ cd experiment
$ lein do clean, uberjar
$ cat >index.html <<EOF
<html>
  <head>
    <meta charset="utf-8">
    <meta content="width=device-width, initial-scale=1" name="viewport">
    <link href="resources/public/css/site.css" rel="stylesheet" type="text/css">
  </head>
  <body class="body-container">
    Hello World
    <div id="app">
      <script src="target/cljsbuild/public/js/app.js" type="text/javascript"></script>
    </div>
  </body>
</html>
EOF

将浏览器指向 localhost:5000 在使用 'foreman start' 时有效,但在使用 nginx 时无效。 (意思是把这个目录放在nginx服务的目录下会加载css和js,会显示"Hello World",但是javascript有错误。)浏览器的出现如下两个错误控制台:

app.js:451 Error rendering component (in Vn)
(anonymous) @ app.js:451
app.js:471 Uncaught Error: Assert failed: Invalid Hiccup form: [nil]
 (in Vn)
(valid-tag? tag)
    at Mk (app.js:471)
    at Jk (app.js:473)
    at Dk (app.js:475)
    at Ik (app.js:470)
    at Mk (app.js:472)
    at Jk (app.js:473)
    at bk (app.js:449)
    at app.js:451
    at uj (app.js:428)
    at vj (app.js:429)
    at Tj (app.js:448)
    at t.render (app.js:451)
    at p._renderValidatedComponentWithoutOwnerOrContext (app.js:25)
    at p._renderValidatedComponent (app.js:25)
    at performInitialMount (app.js:25)
    at p.mountComponent (app.js:25)
    at Object.mountComponent (app.js:27)
    at performInitialMount (app.js:25)
    at p.mountComponent (app.js:25)
    at Object.mountComponent (app.js:27)
    at i (app.js:26)
    at r.perform (app.js:27)
    at u (app.js:26)
    at r.perform (app.js:27)
    at Object.batchedUpdates (app.js:26)
    at Object.a [as batchedUpdates] (app.js:27)
    at Object._renderNewRootComponent (app.js:26)
    at Object._renderSubtreeIntoContainer (app.js:26)
    at Sk (app.js:476)
    at app.js:554
    at app.js:554
    at app.js:555

好的,我相信您的 nginx 配置有问题破坏了客户端秘书路由。正如您所指出的,如果您从文件系统 (file://.../index.html).

加载文件,则会发生类似的错误

默认试剂模板没有提供的一件事是“.../index.html”的默认路径。我怀疑这可能对 nginx 案例有所帮助。我会将以下内容添加到 src/cljs/experiment/core.cljs 并重建:

(secretary/defroute "/index.html" []
  (session/put! :current-page #'home-page))

通过该更改,我能够通过使用标准 nginx docker 容器(然后浏览到 localhost:5001)来成功加载页面:

docker run --name nginx -v `pwd`:/usr/share/nginx/html:ro -d -p 5001:80 nginx

您可能希望将该 nginx docker 映像的默认配置与您自己的配置进行比较,以确定问题的根本原因。

这里有两个问题,kanaka 的帮助有助于找出这两个问题。

  1. 来自nginx的传入url包括“/index.html”,没有秘书路由。见上面kanaka的解决方案。
  2. 秘书路由假设 urls 是 root。就我而言,这个应用程序是众多应用程序之一,因此它位于 https://www.murphydye.com/experiment/index.html.
  3. 的子文件夹中

一个解决方案是修改#'current-page:

(defn current-page []
  [:div (or (session/get :current-page) #'home-page)])

这会让我们在没有匹配项时进入主页,并且还解决了问题 #1(我们不再需要额外的 defroute "/index.html")。

我说 "one solution" 是因为当您单击 links 时,url 栏将再次假定它已脱离 root,例如,单击 about link 和 url 栏将显示 /about,而不是 /experiment/about。一切正常,因为它不会去服务器加载错误的 url,但将其添加为书签将不起作用。肯定有另一种方法来处理这个问题,但这暂时足以解决这两个问题。

再次感谢加中!