Skip to content

Commit 9c80de8

Browse files
committed
CLJS-1111: browser REPL should have no side effects until -setup
refactor bREPL so all side-effecting setup logic is in -setup. remove useless loaded library tracking logic
1 parent 4e9b619 commit 9c80de8

File tree

1 file changed

+43
-97
lines changed

1 file changed

+43
-97
lines changed

src/clj/cljs/repl/browser.clj

Lines changed: 43 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
(atom {:return-value-fn nil
2424
:client-js nil}))
2525

26-
(def loaded-libs (atom #{}))
27-
28-
(def preloaded-libs (atom #{}))
29-
3026
(defn- set-return-value-fn
3127
"Save the return value function which will be called when the next
3228
return value is received."
@@ -123,7 +119,6 @@
123119
(def ordering (agent {:expecting nil :fns {}}))
124120

125121
(defmethod handle-post :ready [_ conn _]
126-
(reset! loaded-libs @preloaded-libs)
127122
(send ordering (fn [_] {:expecting nil :fns {}}))
128123
(send-for-eval conn
129124
(cljsc/-compile
@@ -187,13 +182,7 @@
187182
if any of the namespaces have not already been loaded from the
188183
ClojureScript REPL."
189184
[repl-env provides url]
190-
(let [missing (remove #(contains? @loaded-libs %) provides)]
191-
(when (seq missing)
192-
(browser-eval (slurp url))
193-
(swap! loaded-libs (partial apply conj) missing))))
194-
195-
(defn setup [repl-env opts]
196-
(server/start repl-env))
185+
(browser-eval (slurp url)))
197186

198187
;; =============================================================================
199188
;; Stracktrace parsing
@@ -473,6 +462,36 @@ goog.events.getProxy/f<@http://localhost:9000/out/goog/events/events.js:276:16"
473462
;; =============================================================================
474463
;; BrowserEnv
475464

465+
(defn compile-client-js [opts]
466+
(cljsc/build
467+
'[(ns clojure.browser.repl.client
468+
(:require [goog.events :as event]
469+
[clojure.browser.repl :as repl]))
470+
(defn start [url]
471+
(event/listen js/window
472+
"load"
473+
(fn []
474+
(repl/start-evaluator url))))]
475+
{:optimizations (:optimizations opts)
476+
:output-dir (:working-dir opts)}))
477+
478+
(defn create-client-js-file [opts file-path]
479+
(let [file (io/file file-path)]
480+
(when (not (.exists file))
481+
(spit file (compile-client-js opts)))
482+
file))
483+
484+
(defn setup [{:keys [working-dir] :as repl-env} opts]
485+
(println "Compiling client js ...")
486+
(swap! browser-state
487+
(fn [old]
488+
(assoc old :client-js
489+
(create-client-js-file
490+
repl-env (io/file working-dir "client.js")))))
491+
(println "Waiting for browser to connect ...")
492+
opts
493+
(server/start repl-env))
494+
476495
(defrecord BrowserEnv []
477496
repl/IJavaScriptEnv
478497
(-setup [this opts]
@@ -497,88 +516,18 @@ goog.events.getProxy/f<@http://localhost:9000/out/goog/events/events.js:276:16"
497516
(reset! server/state {})
498517
(reset! browser-state {})))
499518

500-
(defn compile-client-js [opts]
501-
(cljsc/build
502-
'[(ns clojure.browser.repl.client
503-
(:require [goog.events :as event]
504-
[clojure.browser.repl :as repl]))
505-
(defn start [url]
506-
(event/listen js/window
507-
"load"
508-
(fn []
509-
(repl/start-evaluator url))))]
510-
{:optimizations (:optimizations opts)
511-
:output-dir (:working-dir opts)}))
512-
513-
(defn create-client-js-file [opts file-path]
514-
(let [file (io/file file-path)]
515-
(when (not (.exists file))
516-
(spit file (compile-client-js opts)))
517-
file))
518-
519-
(defn- provides-and-requires
520-
"Return a flat list of all provided and required namespaces from a
521-
sequence of IJavaScripts."
522-
[deps]
523-
(flatten (mapcat (juxt :provides :requires) deps)))
524-
525-
;; TODO: the following is questionable as it triggers compilation
526-
;; this code should other means to determine the dependencies for a
527-
;; namespace - David
528-
529-
(defn- always-preload
530-
"Return a list of all namespaces which are always loaded into the browser
531-
when using a browser-connected REPL.
532-
533-
Uses the working-dir (see repl-env) to output intermediate compilation."
534-
[& [{:keys [working-dir]}]]
535-
(let [opts (if working-dir {:output-dir working-dir}
536-
{})
537-
cljs (provides-and-requires
538-
(cljsc/cljs-dependencies opts ["clojure.browser.repl"]))
539-
goog (provides-and-requires
540-
(cljsc/js-dependencies opts cljs))]
541-
(disj (set (concat cljs goog)) nil)))
542-
543-
;; NOTE: REPL evaluation environment designers do not replicate the behavior
544-
;; of the browser REPL. The design is outdated, refer to the Node.js, Rhino or
545-
;; Nashorn REPLs.
546-
547-
(defn repl-env* [opts]
548-
(let [ups-deps (cljsc/get-upstream-deps)
549-
opts (assoc opts
550-
:ups-libs (:libs ups-deps)
551-
:ups-foreign-libs (:foreign-libs ups-deps))
552-
compiler-env (cljs.env/default-compiler-env opts)
553-
opts (merge (BrowserEnv.)
554-
{:port 9000
555-
:optimizations :simple
556-
:working-dir (or (:output-dir opts)
557-
(->> [".repl" (util/clojurescript-version)]
558-
(remove empty?) (string/join "-")))
559-
:serve-static true
560-
:static-dir (cond-> ["." "out/"]
561-
(:output-dir opts) (conj (:output-dir opts)))
562-
:preloaded-libs []
563-
:src "src/"
564-
::env/compiler compiler-env
565-
:source-map false}
566-
opts)]
567-
(cljs.env/with-compiler-env compiler-env
568-
(reset! preloaded-libs
569-
(set (concat
570-
(always-preload opts)
571-
(map str (:preloaded-libs opts)))))
572-
(reset! loaded-libs @preloaded-libs)
573-
(println "Compiling client js ...")
574-
(swap! browser-state
575-
(fn [old]
576-
(assoc old :client-js
577-
(create-client-js-file
578-
opts
579-
(io/file (:working-dir opts) "client.js")))))
580-
(println "Waiting for browser to connect ...")
581-
opts)))
519+
(defn repl-env*
520+
[{:keys [output-dir] :as opts}]
521+
(merge (BrowserEnv.)
522+
{:port 9000
523+
:working-dir (->> [".repl" (util/clojurescript-version)]
524+
(remove empty?) (string/join "-"))
525+
:serve-static true
526+
:static-dir (cond-> ["." "out/"] output-dir (conj output-dir))
527+
:preloaded-libs []
528+
:optimizations :simple
529+
:src "src/"}
530+
opts))
582531

583532
(defn repl-env
584533
"Create a browser-connected REPL environment.
@@ -593,9 +542,6 @@ goog.events.getProxy/f<@http://localhost:9000/out/goog/events/events.js:276:16"
593542
Defaults to true.
594543
static-dir: List of directories to search for static content. Defaults to
595544
[\".\" \"out/\"].
596-
preloaded-libs: List of namespaces that should not be sent from the REPL server
597-
to the browser. This may be required if the browser is already
598-
loading code and reloading it would cause a problem.
599545
optimizations: The level of optimization to use when compiling the client
600546
end of the REPL. Defaults to :simple.
601547
src: The source directory containing user-defined cljs files. Used to

0 commit comments

Comments
 (0)