やろーじだい

ブログと技術メモです。なにかあればより詳細に書こうということで最初は雑に書くようにしています。質問・要望等あれば Twitter かコメントに下さい。

cider refresh で存在しないはずの名前空間を探しに行ってしまいエラーが出る

Could not locate foo/bar/hoge__init.class or
   foo/bar/hoge.clj on classpath.

確かに以前そのような require 文を書いた覚えはあるが現在はどこのコードにも書かれていないはず。 しかし cider refresh をすると指定の名前空間が見つからない。というようなことが起こった。

原因と解決

結果として ClojureScript からコンパイルされた古い JavaScript ファイルが原因だった。(以下にこれについて追記) ClojureScript の仕様なのか cider の仕様なのかわからないが Clojure(Script) の中で cider refresh がリロードする必要がある場所を探す際にコンパイルして出力した js ファイルまで参照しているようで、 現在の ClojureScript と JavaScript ファイルの統合性が取れずエラーが出ていたらしい。 resources/pubilc/out 等のファイルを削除してクリーンな状態にすることで解決できた。 lein clean をするクセなり自動化するなりするようにする。

追記 2018/08/04

You do a lein uberjar to test your build locally. This will create AOT compiled classes and put them on the classpath (under target/ to be precise). Next time you try to (reset) it will tell you it can’t find certain Clojure source files, even though they’re right there.

Reloading Woes

これが原因だった可能性が非常に高い。紹介されている stackoverflow でも言われているが target/ 以下は消すようにした方が良いようだ。

追記 2018/09/06

jar だけに限らず、やはりコンパイルして出力した js が原因で cider refresh 時にエラーが出ることがあるようだ。 毎回 lein clean したかどうかを気にするのは面倒なので、以下のように cider-ns-refresh にフックすることにした。

;; hook-cider.clj
(ns hookcider
  (:require [clojure.java.shell :as sh]))

(defn lein-clean []
  (sh/sh "lein" "clean"))
;; .dir-locals.el
((nil
  (cider-ns-refresh-before-fn . "hookcider/lein-clean")))

備考

Cider 0.18 から cider-refresh (を含む様々な関数) の名前やショートカットが変わったりしている。

https://github.com/clojure-emacs/cider/blob/master/CHANGELOG.md