bhauman / lein-figwheel

Figwheel builds your ClojureScript code and hot loads it into the browser as you are coding!
Eclipse Public License 1.0
2.88k stars 210 forks source link

Unable to load the core Node.js libraries using cider/figwheel. #711

Closed FieryCod closed 6 years ago

FieryCod commented 6 years ago

Step to reproduce:

  1. Clone https://github.com/FieryCod/core-library-require-minimal-repro
  2. Use cider figwheel
  3. cider-eval-last-sexp on ns form

Error: Figwheel: message from client couldn't be read! Eval timed out! No stacktrace available.

Stacktrace:

1. Unhandled clojure.lang.ExceptionInfo
   Eval timed out!
   {:type :js-eval-exception,
    :error
    {:status :exception,
     :value "Eval timed out!",
     :stacktrace "No stacktrace available."},
    :form (ns figwheel-node-req-repro.core (:require fs)),
    :js
    "goog.provide('figwheel_node_req_repro.core');\ngoog.require('cljs.core');\nfigwheel_node_req_repro.core.node$module$fs = require('fs');\n"}

                  core.clj: 4739  clojure.core/ex-info
                  core.clj: 4739  clojure.core/ex-info
                 repl.cljc:  577  cljs.repl$evaluate_form/invokeStatic
                 repl.cljc:  498  cljs.repl$evaluate_form/invoke
            piggieback.clj:  209  cider.piggieback/eval-cljs
            piggieback.clj:  208  cider.piggieback/eval-cljs
            piggieback.clj:  235  cider.piggieback/do-eval
            piggieback.clj:  216  cider.piggieback/do-eval
            piggieback.clj:  258  cider.piggieback/evaluate
            piggieback.clj:  256  cider.piggieback/evaluate
                  Var.java:  381  clojure.lang.Var/invoke
            piggieback.clj:  287  cider.piggieback/wrap-cljs-repl/fn/fn/fn
            piggieback.clj:  191  cider.piggieback/enqueue/fn
    interruptible_eval.clj:  190  clojure.tools.nrepl.middleware.interruptible-eval/run-next/fn
                  AFn.java:   22  clojure.lang.AFn/run
   ThreadPoolExecutor.java: 1149  java.util.concurrent.ThreadPoolExecutor/runWorker
   ThreadPoolExecutor.java:  624  java.util.concurrent.ThreadPoolExecutor$Worker/run
               Thread.java:  748  java.lang.Thread/run

When trying to evaluate the whole buffer then the evaluation succeeds.

Everything works as it should using the figwheel-main.

FieryCod commented 6 years ago
/Users/karol/workspace/clojure/lein-figwheel/sidecar/src/figwheel_sidecar/components/figwheel_server.clj 

read-msg method receives something like {:value {#js {:prop1 blabla}} when using cider-eval-last-sexp. Therefore parsing that string returns an error. What I think is that I should just regexp the string and remove #js. What do you think @bhauman?

EDIT: This is what read-msg method really receives

"{:figwheel-event "callback", :callback-name "figwheel_callback_37403", :content {:status :success, :out "", :ua-product :chrome, :value #js {:_toBuf #object[toBuf], :createCipher #object[createCipher], :createCipheriv #object[createCipheriv], :createDecipher #object[createDecipher], :createDecipheriv #object[createDecipheriv], :createDiffieHellman #object[createDiffieHellman], :createDiffieHellmanGroup #object[createDiffieHellmanGroup], :createECDH #object[createECDH], :createHash #object[createHash], :createHmac #object[createHmac], :createSign #object[createSign], :createVerify #object[createVerify], :getCiphers #object[Function], :getCurves #object[Function], :getDiffieHellman #object[createDiffieHellmanGroup], :getHashes #object[Function], :pbkdf2 #object[pbkdf2], :pbkdf2Sync #object[pbkdf2Sync], :privateDecrypt #object[Function], :privateEncrypt #object[Function], :prng #object[randomBytes], :pseudoRandomBytes #object[randomBytes], :publicDecrypt #object[Function], :publicEncrypt #object[Function], :randomBytes #object[randomBytes], :randomFill #object[randomFill], :randomFillSync #object[randomFillSync], :rng #object[randomBytes], :setEngine #object[setEngine], :timingSafeEqual #object[timingSafeEqual], :Certificate #object[Certificate], :Cipher #object[Cipher], :Cipheriv #object[Cipheriv], :Decipher #object[Decipher], :Decipheriv #object[Decipheriv], :DiffieHellman #object[DiffieHellman], :DiffieHellmanGroup #object[DiffieHellmanGroup], :ECDH #object[ECDH], :Hash #object[Hash], :Hmac #object[Hmac], :Sign #object[Sign], :Verify #object[Verify], :DEFAULT_ENCODING "buffer", :constants #object[Object], :createCredentials #object[createSecureContext], :Credentials #object[SecureContext]}}}"
bhauman commented 6 years ago

Splitting on the #js is unfortunately not a solution to consider here. Reading errors need to be fixed by changing the reader so that it reads better.

And I'm not sure this is a reading error neccessarily because figwheel.main has the exact same code for reading responses from the client.

FieryCod commented 6 years ago

read-msg is not a reader stuff?

(defn- replace-unparsable-js
  "Replaces #js in msg with 'nil to avoid read error when importing built-in Node.js libraries (CLJS 1.10)"
  [msg]
  (string/replace msg #"(#js \{[:#\w\[\]\", ]*\})" "nil"))

(defn read-msg [data]
  (try
    (println (replace-unparsable-js data))
    (let [msg (edn/read-string (replace-unparsable-js data))]
      (if (and (map? msg) (:figwheel-event msg))
        msg
        {}))
    (catch Exception e
      (println "Figwheel: message from client couldn't be read!")
      {})))

This is what solves the problem. If it doesn't satisfy you please point me where in code should I look for the problem.