(compile 'my.namespace) ;; writes .class files to *compile-path*
ご存知でしたか?
ほとんどのライブラリはソースとして配布され、何度もコンパイルされます
compile
を使って、名前空間を明示的にコンパイルできます
名前空間のコンパイルは推移的です
compile
はこれらのファイルをディスクに書き込み、require
はそれらを使用します
開発開始時にロードする名前空間、またはuser.clj
、またはサーバーとして実行するメインの名前空間に対してcompile
を使用すると、起動時間を改善できます
compile
関数は、名前空間のシンボルを受け取り、その名前空間と、それがrequire
しているすべての名前空間を*compile-path*
(デフォルトはclasses
)にコンパイルします。そのディレクトリは存在し、クラスパスにある必要があります
(compile 'my.namespace) ;; writes .class files to *compile-path*
その後、それらのコンパイル済み名前空間のいずれかがrequire
されると、元の.clj
ファイルではなく、クラスファイルがロードされます。ソースファイルが更新された(つまり新しい)場合、代わりにロードされます。新しい依存関係やコードの変更に対応するには、定期的に再コンパイルする必要があります。
コンパイルはロードの副作用であるため、すでにロードされている名前空間には影響しないことに注意してください。特に、Clojureランタイムによって自動的にロードされるuser.clj
ファイルは特殊なケースです。開発でuser.clj
を使用している(またはすでにコンパイルされている名前空間をコンパイルする必要がある)場合は、コンパイル中に強制的にリロードすることで実行できます
(binding [*compile-files* true] ;; compile during load
(require 'user :reload-all)) ;; reload this and all transitively loaded namespaces
以上です!この手法は、特にロードする依存関係の数が増えるにつれて、開発中の起動時間を大幅に短縮できます。
deps.ednプロジェクトでは、classes
ディレクトリを含む開発エイリアス(:dev
など)を作成する必要があります
{:deps { ... }
:aliases
{:dev {:extra-paths ["classes"]}}}
また、classes
ディレクトリが存在することを確認する必要があります。空のclasses
ディレクトリをバージョン管理されたプロジェクト構造の一部として含めることが役立つ場合があります(コンパイル済みの.classファイルは無視して含めないようにしてください)。
その後、エイリアスを使用してREPLを起動し、compile
を実行してclasses
ディレクトリにデータを入力すると、メリットが得られます。
$ clj -A:dev
Clojure 1.10.1
user=> (compile 'my.namespace)
自動的にロードされるuser.cljを使用したい場合は、ソースパスdev
を追加して、開発エイリアスに組み込む必要があります
{:deps { ... }
:aliases
{:dev {:extra-paths ["dev" "classes"]}}}
そしてdev/user.clj
を作成します
(ns user
(:require ... ))
;; dev-only functions, etc
user.cljには修正されたコンパイルプロセスを使用することを忘れないでください
$ clj -A:dev
Clojure 1.10.1
user=> (binding [*compile-files* true] (require 'user :reload-all))
オリジナル著者:アレックス・ミラー