2015-04-04 37 views
0

我有一个clojure网络应用程序(标准环形处理程序和码头服务器上的组合路径),为此我启用了作为中间件实时资产重新编译的功能,该功能非常方便发展。当我们接近生产时,我想找到一种方法,不要在生产中加载该代码,而是阅读预编译的资产(我可以将其作为lein任务生成)。我如何在clojure网络应用程序中有条件地加载功能

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

另一个问题是,我使用的是一种资产编译工具,导致应用程序在初始化时无法加载,如果使用了uberjar,因为它使用了v8的本地绑定,不需要)当预编译资产可用时。

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

+0

看看[Environ](https://github.com/weavejester/environ)以及添加'dev'和'uberjar'配置文件的选项。 – sbensu 2015-04-04 22:11:08

+0

谢谢 - 我已经在使用environ进行配置管理,所以noisesmith的回答很简单。 – flightlessbird 2015-04-04 23:42:54

回答

2

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

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

; 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配置文件下的可选命名空间中的相应功能,否则为空操作。

相关问题