2015-04-04 33 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配置文件下的可選命名空間中的相應功能,否則爲空操作。

相關問題