0

我有一个 clojure Web 应用程序(码头服务器上的标准环处理程序和组合路由),我为此启用了实时资产重新编译作为中间件,这在开发中非常方便。随着我们越来越接近生产,我想找到一种方法不在生产中加载该代码,而是读取预编译的资产(我可以将其作为 lein 任务生成)。

目前,资产编译机制存在于项目代码中——它可以使用 eval-in-project 从 lein 任务中加载,因此我可以在两个地方重用相同的代码。然而,这意味着不需要的文件被编译并包含在生产应用程序中。

另一个问题是我正在使用一个资产编译工具,如果 uberjar'ed 导致应用程序无法在初始化时加载,因为它使用到 v8 的本机绑定,当预编译的资产可用。

如何避免在生产 uberjar 中加载此代码,但仍受益于开发和测试期间运行时的动态重新编译?

4

1 回答 1

2

:source-paths在 Leiningen 中的密钥决定了检查 Clojure 源代码的目录。使用每个环境的设置,:source-paths您可以防止不需要的名称空间包含在您部署的 uberjar 中。

下一个难题是确保您的代码不依赖于生产实例上的开发代码。这可以在environlib 的帮助下完成。

; excerpt of project.clj
(defproject your-org/your-project "version"
   :source-paths ["src"] ; the main source location
   :profiles {:dev {:source-paths ["dev-src"] ; added directory
                    :env {:dev "true"}}}
 ...)

; excerpt of project code for src/your_org/your_project.clj
(ns your-org.your-project
  (:require environ.core :refer [env]))

(def maybe-launch-optional-thing
  (if (= (env :dev) "true") ; checking a profile specific value
   (do (require 'dev-only-dep.core)
       (resolve 'dev-only-dep/launch))
   (constantly nil))

...

(defn -main
  [& args]  
  (maybe-launch-optional-thing)
  ...)

if包装的require和 的使用resolve确保此代码有效,无论是否dev-only-dep.core可用。maybe-launch-optional-thing绑定到:dev配置文件下可选命名空间中的适当函数,否则为无操作。

于 2015-04-04T22:20:10.787 回答