2011-10-20 7 views
21

私のクライアント側* .cljsとサーバー側* .cljの間のいくつかの共通コードを除外したいとします。さまざまなデータ構造と一般的な操作、私はそれを行うことはできますか?それは意味をなさないでしょうか?Clojurescript/Clojureでのサーバーとクライアント間のコード共有

+2

GWTのように、サーバー上とクライアント上でJavaコードを共有することもできます。これについての答えを聞くのはとても涼しいでしょう! –

+0

ここで私が考えることができる唯一の方法は、共有名前をサーバーの名前空間とディレクトリ構造に置き、ファイルをクライアントのソースディレクトリにコピーするためのコンパイルコードに行を追加して、* .cljsという名前に変更することです。 - clojurescriptコンパイラは.cljsという名前のファイルのみを探します – Hendekagon

答えて

13

更新:clojure 1.7以降、Clojure reader conditionals or cljcをチェックしてください。 cljcを使って、サーバーとブラウザの間で多くのコードを非常に簡単に共有できるようになりました。

大きな質問!私は最近これについて多くのことを考えていて、いくつかのアプリを試してみました。

ここであなたが共有したい場合がありますどのような種類のものと、それぞれの長所/短所の私のリストです:

  • は私のクライアントcljsファイルのほとんどは、DOMを操作するコードが含まれています。したがって、それをサーバーと共有することは意味がありません。
  • ほとんどのサーバー側のものはファイルシステムとデータベース呼び出しを処理します。私はあなたがクライアントからデータベースを呼びたいと思うかもしれないと思います(特にjavascript呼び出しをサポートするSQLデータベースがない場合は特にそうです)。しかし、それでもクライアントからdbを呼び出すか、サーバーからdbを呼び出すかのどちらかを選択する必要があり、したがってdbコードを共有するのはあまり意味がありません。
  • 共有がきわめて重要な領域の1つは、クライアントとサーバーの間でクロージャーデータ構造(ネストされたリスト、ベクター、セットなどの組み合わせ)を共有して渡すことができることです。 json(またはxml)に変換して戻す必要はありません。例えば、ドックのヒカップ様式表現を前後に渡すことができることは非常に便利です。 gwtでは、私はgileadを使ってクライアントとサーバーの間でモデルを共有しました。しかし、クロージャーでは、単にデータ構造を渡すことができるので、gwtのようなクラス定義を共有する必要はありません。
  • もっと実験する必要があると感じる領域は、クライアントとサーバーの間で状態を共有することです。私の考えでは、いくつかの戦略があります:クライアント上の状態を保存する(単一ページのajaxタイプのアプリケーション)か、サーバー上に状態を保存する(古いJSPアプリケーションのように)か、両方のコンボです。おそらく、状態を更新する責任を負うコード(原子、リファレンス、エージェントなど)を共有し、状態を2つのティアを同期させるために要求と応答を往復することができますか?これまでは、RESTのベストプラクティスを使用してサーバーを作成し、クライアントに状態を格納するだけで、かなりうまくいくようです。しかし、私は、クライアントとサーバーの間で状態を共有することにどのような利点があるのか​​を知ることができました。
  • まだ定数やプロパティを共有する必要はありませんが、これは再利用するのに適しているかもしれません。あなたのアプリケーションのグローバル定数をcljファイルに入れて、clourescriptをコンパイルするたびにそれをcljsにコピーするスクリプトを書いたら、それはうまくいくはずで、コードの重複を減らすことができます。

これらの考えが役立つことを願って、私はこれまでに他の人が見つけたものに非常に興味があります!

+0

優れた点!私は、サーバーコードでその関数のサブセットをコンパイラに渡すことで、すべてのClojurescriptコードを自動ビルドさせることでプロセスを統一したいと考えています。私はまだコンパイラコードを読んでいませんが、.cljsファイルを使わずに直接式を入力する必要があります。 – Hendekagon

+0

datastrutureの共有に関して、ライブラリ 'fetch'はかなりきれいであるようです! https://github.com/ibdknox/fetch – leontalbot

2

は、建物の前に.cljsとして名前の変更、私のclojurescriptコードの上で、私のサーバーClojureのコードの一部をコピーしたコードの迅速なビットを書いた:

(ns clj-cljs.build 
    (use 
    [clojure.java.io] 
) 
    (require 
    [cljs.closure :as cljsc] 
) 
) 

(defn list-files [path] 
(.listFiles (as-file path)) 
) 

(defn copy-file* [from to] 
;(println " coping " from " to " to) 
(make-parents to) 
(copy from to) 
)  

(defn rename [to-path common-path f] 
(str to-path common-path (.replaceAll (.getName f) ".clj" ".cljs")) 
) 

(defn clj-cljs* [files common-path to-path] 
    (doseq [i (filter #(.endsWith (.getName %) ".clj") files)] 
    (copy-file* i (file (rename to-path common-path i))) 
) 
    (doseq [i (filter #(.isDirectory %) files)] 
    (clj-cljs* (list-files i) (str common-path (.getName i) "/") to-path) 
) 
) 

(defn build [{:keys [common-path clj-path cljs-path js-path module-name]}] 
    (clj-cljs* (list-files (str clj-path common-path)) common-path cljs-path) 
    (cljsc/build 
    cljs-path 
    { 
    :output-dir js-path 
    :output-to (str js-path module-name ".js") 
    } 
) 
) 

(defn build-default [] 
    (build 
    { 
    :clj-path "/home/user/projects/example/code/src/main/clojure/" 
    :cljs-path "/home/user/projects/example/code/src/main/cljs/" 
    :js-path "/home/user/projects/example/code/public/js/cljs/" 
    :common-path "example/common/" ; the root of your common server-client code 
    :module-name "example" 
    } 
) 
) 
10

Leiningenをのための新しいlein-cljsbuildプラグインが組み込まれているsupport純粋なClojureコードを共有するためのものです。

+2

[cljsbuild](https://github.com/emezeske/lein-cljsbuild)の組み込みサポート(クロスオーバー)は廃止されました[cljx](https ://github.com/lynaghk/cljx)、[this](http://stackoverflow.com/a/10369314/1209442)の回答を参照してください。 –

15

私は、ClojureデータビジュアライゼーションライブラリのClojure/ClojureScriptコード共有を扱うために、cljx Leiningenプラグインを作成しました。 host-interop以外のコードの95%が同じように見えます.cljxでは、core.logicを使用して書き換えルールを指定することで、最後の5%を自動的に書き換えることができます。 しかし、ほとんどの場合、単純な記号の置換です。 Clojureのclojure.lang.IFnは、例えばClojureScriptの場合はIFnです。

また、特定のプラットフォーム用にコードが生成されたときに、メタデータを使用してフォームに注釈を付けることも、除外することもできます。

+0

有用なcheerzと思われる – Hendekagon

+1

[cljsbuild](https://github.com/emezeske/lein-cljsbuild)のコード共有ツールとして[cljx](https://github.com/lynaghk/cljx)が採用されました) –

0

この質問は前にcljcですが、私はそれに直面してから、私はClojure reader conditionalsと言いたいと思いました。

関連する問題