无需重新启动 Web 服务器的 Compoju 开发 [英] Compojure development without web server restarts

查看:15
本文介绍了无需重新启动 Web 服务器的 Compoju 开发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之前在 Clojure 中编写了一个小型 Swing 应用程序,现在我想创建一个 Ajax 风格的 Web 应用程序.Compojure 现在看起来是最好的选择,所以这就是我要尝试的.

I've written a small Swing App before in Clojure and now I'd like to create an Ajax-style Web-App. Compojure looks like the best choice right now, so that's what I'm going to try out.

我想要一个真正的小编辑/尝试反馈循环,所以我不想在每次做小改动后重新启动网络服务器.

I'd like to have a real tiny edit/try feedback-loop, so I'd prefer not to restart the web server after each small change I do.

实现这一目标的最佳方法是什么?默认情况下,我的 Compojure 设置(带有 ant deps/ant 和 Jetty 的标准内容)似乎不会重新加载我所做的任何更改.我必须使用 run-server 重新启动才能看到更改.由于 Java 遗产和系统启动方式等原因.这可能是完全正常的,也是我从命令行启动系统时应该采用的方式.

What's the best way to accomplish this? By default my Compojure setup (the standard stuff with ant deps/ant with Jetty) doesn't seem to reload any changes I do. I'll have to restart with run-server to see the changes. Because of the Java-heritage and the way the system is started etc. This is probably perfectly normal and the way it should be when I start the system from command-line.

不过,必须有一种方法可以在服务器运行时动态重新加载内容.我应该使用 REPL 的 Compojure 来实现我的目标吗?如果我应该,我如何在那里重新加载我的东西?

Still, there must be a way to reload stuff dynamically while the server is running. Should I use Compojure from REPL to accomplish my goal? If I should, how do I reload my stuff there?

推荐答案

这是一个很老的问题,最近有一些更改使这变得更容易.

This is quite an old question, and there have been some recent changes that make this much easier.

您需要做的主要有两件事:

There are two main things that you want:

  1. 控制应返回到 REPL,以便您可以继续与服务器进行交互.这是通过添加 {:join?false} 启动 Jetty 服务器时的选项.
  2. 您希望在文件更改时自动获取某些命名空间中的更改.这可以通过 Ring 的wrap-reload"中间件来完成.

一个玩具应用程序看起来像这样:

A toy application would look like this:

(ns demo.core
  (:use webui.nav
    [clojure.java.io]
    [compojure core response]
    [ring.adapter.jetty :only [run-jetty]]
    [ring.util.response]
    [ring.middleware file file-info stacktrace reload])
  (:require [compojure.route :as route] view)
  (:gen-class))

; Some stuff using Fleet omitted.    

(defroutes main-routes
  (GET "/" [] (view/layout {:body (index-page)})
  (route/not-found (file "public/404.html"))
)

(defn app
  []
  (-> main-routes
      (wrap-reload '(demo.core view))
      (wrap-file "public")
      (wrap-file-info)
      (wrap-stacktrace)))

(defn start-server
  []
  (run-jetty (app) {:port 8080 :join? false}))

(defn -main [& args]
  (start-server))

wrap-reload 函数使用检测列出的命名空间中的更改的函数来修饰您的应用程序路由.处理请求时,如果这些命名空间在磁盘上发生了更改,则会在进一步处理请求之前重新加载它们.(我的视图"命名空间是由 Fleet 动态创建的,因此每当我的模板发生变化时,它也会自动重新加载我的模板.)

The wrap-reload function decorates your app routes with a function that detects changes in the listed namespaces. When processing a request, if those namespaces have changed on disk, they are reloaded before further request processing. (My "view" namespace is dynamically created by Fleet, so this auto-reloads my templates whenever they change, too.)

我添加了其他一些我发现一直有用的中间件.wrap-file 处理静态资产.wrap-file-info 在这些静态资产上设置 MIME 类型.wrap-stacktrace 有助于调试.

I added a few other pieces of middleware that I've found consistently useful. wrap-file handles static assets. wrap-file-info sets the MIME type on those static assets. wrap-stacktrace helps in debugging.

在 REPL 中,您可以通过使用命名空间并直接调用 start-server 来启动此应用程序.:gen-class 关键字和 -main 函数意味着该应用程序也可以打包为 uberjar,以便从 REPL 外部启动.(REPL 之外还有世界吗?好吧,反正有人要求它...)

From the REPL, you could start this app by using the namespace and calling start-server directly. The :gen-class keyword and -main function mean that the app can also be packaged as an uberjar for startup from outside the REPL, too. (There's a world outside the REPL? Well, some people have asked for it anyway...)

这篇关于无需重新启动 Web 服务器的 Compoju 开发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆