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

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

问题描述

我在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)似乎不重新加载任何更改我做。我必须重新启动与运行服务器,以查看更改。因为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.

仍然,在服务器运行时,必须有一种方法来动态重新载入内容。我应该使用Compojure从REPL来完成我的目标吗?如果我应该,如何重新加载我的东西在那里?

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?

  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服务器的Compojure开发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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