Foo.bar;
従来のJavaScriptクライアント(ウェブブラウザ)をターゲットにしている場合、最初から高度なコンパイルについて考えることが重要です。そうでないと、少しの事前準備で簡単に回避できた問題に遭遇することになります。一般的に、高度なビルドを試すのを待つべきではありません。問題を早期に検出するために、常に定期的に本番ビルドを生成する必要があります。
Google Closure Libraryまたは既存のClojureScriptライブラリにソリューションが存在する場合は、外部ライブラリを単に回避するのが最善です。高度なコンパイルを確実に動作させるには、外部ライブラリはexternsを提供する必要があります。
もちろん、場合によっては外部ライブラリを回避できないこともあります。
CLJSJSで提供されているものなど、キュレーションされた外部ライブラリを使用する必要があります。これらはexternsと共にパッケージ化されているため、自分で提供する必要はありません。
時折、事前にパッケージ化されていない外部ライブラリが必要になる場合があります。
externsを提供しない外部ライブラリを使用する場合は、使用するAPIのexternsファイルを作成する時間を取りましょう。Externsファイルは驚くほど簡単に提供できます。たとえば、外部ライブラリにアクセスしたいFoo.barというプロパティがある場合、externsファイルには次のエントリが必要です。
Foo.bar;
外部ライブラリに呼び出したいFoo.bazというメソッドがある場合、externsファイルには次のエントリが必要です。
Foo.baz = function() {};
トップレベルAPIではなく、ある種のメソッド命名規則、つまりアドホックインターフェース/プロトコルがある場合があります。これらの場合は、Objectを使用してexternsを定義します。
Object.foo = function() {};
Object.bar = function() {};
もちろん、externsのエントリを見逃すことがあり、本番ファイルが難解なエラーを生成することがあります。いくつかのClosureコンパイラオプションのおかげで、これらの問題はもはやデバッグが難しくなくなりました。
JavaScriptからClojureScriptコードにアクセスしたい場合は、高度なコンパイルによってVar名のJavaScript表現が変更されるという事実に対処する必要があります。これは、JavaScriptから使用できるVarに:exportメタデータを追加することで簡単に解決できます。
たとえば、square関数がある場合、次のように^:exportで注釈を付けることができます。
(ns my-math.core)
(defn ^:export square [x]
(* x x))
これにより、JavaScriptから次のようにsquare関数を呼び出すことができます。
my_math.core.square(3);
これは、:exportメタデータがVarに関連付けられている場所に、出力されたJavaScriptにgoog.exportSymbol呼び出しを含めることで機能します。
|
エクスポートされた各Varに対して、Closureで変更された名前にポイントする追加の非名前変更エイリアスが確立されます。変更された名前は、最適化されたコード内では引き続き内部的に使用されます。
|
プロトコルメソッドに関連付けられたVarを個別にエクスポートできます。この例では、barとquuxがエクスポートされます。
(defprotocol IFoo
(^:export bar [this])
(baz [this x])
(^:export quux [this x y]))
本番ビルドを、追加の2つのオプション:pseudo-names trueと:pretty-print trueを使用して変更します。これで、エラーは元のソースの名前と一致する名前を表示します。この見逃したケースのexternsエントリを追加します。
:foreign-libsコンパイラオプション構文の詳細については、依存関係を参照してください。