【问题标题】:How to properly setup shadow-cljs for hot reload? [closed]如何正确设置 shadow-cljs 以进行热重载? [关闭]
【发布时间】:2021-01-26 18:31:58
【问题描述】:

我一直在尝试让 shadow-cljs 热重载工作,但我没能做到,我在我的 project.clj 文件中尝试了多个设置,但没有一个有效。这就是我的 project.clj 的样子:

:shadow-cljs {:nrepl {:port 8777}
                
                :builds {:app {:target :browser
                               :output-dir "resources/public/js/compiled"
                               :asset-path "/js/compiled"
                               :modules {:app {:init-fn my-app.core/init
                                               :preloads [devtools.preload]}}

                               :devtools {:http-root "resources/public"
                                          :http-port 8080
                                          :http-handler my-app.handler/dev-handler
                                          }}}}

:aliases {"watch"        ["with-profile" "dev" "do"
                          ["shadow" "watch" "app"]]}

:profiles
  {:dev
   {:dependencies [[binaryage/devtools "1.0.2"]]
    :source-paths ["dev"]} ;; <- this is the default from the template pointing to "dev", I've tried chaning it multiple times.
  }

当我运行lein watch 时,我知道它只是在运行shadow-cljs watch app,它应该运行我的“应用程序”构建。这就是我的开发处理程序的样子(在:http-handler 中引用):

(def dev-handler (-> api-routes
                     wrap-params
                     wrap-json-response
                     wrap-keyword-params
                     wrap-json-params
                     wrap-multipart-params
                     wrap-reload
                     (wrap-resource "public")
                     (utils/cors-wrapper utils/cors-policy)
                     (utils/wrap-content-type-security)
                     (wrap-defaults (assoc-in site-defaults [:security :anti-forgery] false))))

我尝试将我的 :dev 配置文件中的源路径更改为 ["src"],甚至尝试将所有内部文件夹包括在 ["src/clj" "src/cljs" "src/cljc"] 中,但没有成功。我什至尝试使用 lein new re-frame 从头开始​​创建一个新应用程序,不做任何更改并运行 lein watch,代码编译并且一切看起来都很好,但是每当我更改 cljs 文件(例如 views.cljs)中的某些内容时,什么都不会重新渲染/重新加载,我已经访问了 localhost:9630,它为您提供了一个 shadow-cljs 仪表板,列出了您的构建,然后单击“强制编译”按钮并在我的应用程序页面中看到一个 clojurescript 动画,但没有重新渲染/重新加载。我注意到当 shadow-cljs 完成编译时,编译了 0 个文件,它是从其他地方获取源路径配置吗?这是我尝试测试时的样子:

编辑:也许值得一提的是,我在 MobaXterm 中使用 xfce 终端和来自 WSL2 的 emacs 运行 ubuntu,这可能与代码/应用程序不热重载有关吗?

【问题讨论】:

    标签: clojure clojurescript hot-reload shadow-cljs


    【解决方案1】:

    一切似乎都按预期顺利进行。可能您唯一缺少的是一个生命周期回调来触发您的页面的实际重新呈现。

    https://shadow-cljs.github.io/docs/UsersGuide.html#_hot_code_reload

    在大多数重组/试剂应用程序中,这将是调用reagent.dom/render(或reagent.core,如果您使用的是旧版本)的函数。

    我还写了更多关于这一切的工作原理here

    ...它是从其他地方获取源路径配置吗?

    shadow-cljs 查看 JVM 类路径,但它是在启动时构建的。您似乎正在使用lein,因此这里只有project.clj 很重要,并且类路径是通过添加所有:source-paths:resource-paths 等来构建的。因此,如果您有 :source-paths ["src/clj" "src/cljs" "src/cljc"] 就足以让它被拾取,当然假设您正在使用的源文件实际上在这些目录中。

    否则无法评论您的设置。我在 WSL2 中很好地使用了它,但是如果在容器(例如 docker)中运行会出现已知问题,所以我不排除这里有一些时髦的东西,它会阻止 shadow-cljs 实际“观察”文件。

    【讨论】:

    • 谢谢!模块配置将命名空间 my-app.core/init 作为其 init-fn,默认情况下在 lein re-frame 模板上配置,该 init 函数确实调用了 reagent.dom/render。至于源路径,我假设我们不必设置源文件的绝对路径,对吗?就像在 src/clj/my-app 中一样,我猜只使用 src 或 src/clj 就足够了。
    • 不,类路径需要适合。任何命名空间都可以直接转换为文件名。所以my-app.core 预计可以在my_app/core.cljs 之一的:source-paths 中找到,方法是将该路径与文件名相结合。因此,如果文件在正确的位置,那就是src/cljs/my_app/core.cljs。如果您改为使用:source-paths ["src"],它将是src/my_app/core.cljs,但不再是另一个。 FWIW 该文件似乎位于正确的位置。否则你会得到一个编译错误。 :init-fn 也没有配置热重载钩子,除非它也有 :dev/after-load
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-05-28
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 2021-05-28
    相关资源
    最近更新 更多