shadow-cljs

https://github.com/thheller/shadow-cljs | https://github.com/sponsors/thheller | https://www.patreon.com/thheller
bringe 2021-02-11T00:46:19.161200Z

I'm still digging into it a bit: https://github.com/thheller/shadow-cljs/issues/841

2021-02-11T09:29:02.162500Z

Is it expected that shadow won't infer an extern and won't produce a warning? I'm seeing a renamed JS property slipped into release build

thheller 2021-02-11T10:00:13.163200Z

@roman01la you need to be a bit more specific. it entirely depends on the code whether externs are generated or not.

2021-02-11T10:02:44.165300Z

I see, here's more context code

(defn get-x []
  ^js/LibraryX @lib-x)

(let [x (get-x)]
  (.methodA x)
  (.methodB x))
manual externs
LibraryX.prototype.methodA = function() {}

2021-02-11T10:03:04.165700Z

for the above setup methodB gets renamed in release build and there's no compiler warning emitted

thheller 2021-02-11T10:04:21.166700Z

(defn get-x ^js []
  @lib-x)

2021-02-11T10:04:24.167100Z

now when I remove manual externs and hint those values with ^js inference seems to work fine in release

thheller 2021-02-11T10:05:05.168400Z

but you should be getting warnings in this case. or automatic externs inference

2021-02-11T10:05:28.169Z

unfortunately I didn't get any

zendevil 2021-02-11T10:05:36.169300Z

I’m running a watch like so:

shadow-cljs watch app
But in the browser app, I’m getting two errors:
Connection closed
and
Stale client
How to fix this error? There are warnings but no errors in the shadow command line

2021-02-11T10:05:57.170Z

why does ^js work but more specific ^js/Lib doesn't?

zendevil 2021-02-11T10:06:42.171200Z

Now I’m only getting Connection closed

thheller 2021-02-11T10:06:55.171500Z

@roman01la both are the same as far as shadow-cljs is concerned. I'm just not sure that the typehint directly on the defer properly propagates to the function return value.

thheller 2021-02-11T10:07:36.172300Z

@ps that means the JS that is being loaded was not produced by the watch you started. that can either happen if you have 2 shadow-cljs isntances running in the same project. or you changed the paths somewhere but still access the "old" JS

zendevil 2021-02-11T10:07:56.172600Z

how to close all shadow-cljs instances?

zendevil 2021-02-11T10:08:05.172900Z

i might have been running two

zendevil 2021-02-11T10:08:29.173100Z

I’ve tried shadow-cljs stop

2021-02-11T10:09:36.174100Z

> both are the same as far as shadow-cljs is concerned. I'm just not sure that the typehint directly on the defer properly propagates to the function return value. interesting, so there two things going on 1. shadow doesn't emit a warning 2. switching to ^js solves the problem, externs inferred correctly

thheller 2021-02-11T10:10:17.174300Z

odd

thheller 2021-02-11T10:13:30.175600Z

@ps stop will only stop the latest one. if you somehow started another you need to kill it manually. you can use the java tools to find the process. just jps or jcmd

2021-02-11T11:44:57.176400Z

@thheller I can verify that adding return type hint solves the above problem, however it doesn't exist in plain cljs

thheller 2021-02-11T12:44:14.176600Z

what does? shadow-cljs doesn't do anything special in that regard?

2021-02-11T12:45:53.177500Z

I mean that in plain cljs property renaming doesn't happen, but in shadow it does happen, even though shadow doesn't emit infer warning

thheller 2021-02-11T12:47:42.179Z

you need to be more precise. I do not have enough information to know what you are referring to. for example the renaming may not happen in regular CLJS because you have some CLJSJS externs that happen to handle it, they are often over-generated so it might even be from a different package or so.

thheller 2021-02-11T12:48:23.179800Z

I'm happy to take a look at reproducible sample code any time (and fix it if there are actual issues)

2021-02-11T12:49:06.181100Z

good point about third party externs, I'll put a minimal repro once I manage to reduce the scope of the problem

thheller 2021-02-11T12:49:19.181400Z

in general shadow-cljs does more externs inference, not less so I'd be very surprised if thats the cause

2021-02-11T12:49:37.181800Z

yeah that's why it seemed weird to me

2021-02-11T12:50:50.182800Z

another interesting case I just hit is that during dev shadow emits an inferring warning, but release build doesn't emit the warning and generated JS looks correct

2021-02-11T12:51:34.183400Z

this is not a problem, since adding a hint to silence the compiler in dev is fine, but still interesting inconsistency

thheller 2021-02-11T12:52:33.184Z

can't say anything without reproducible examples

👍 1
zendevil 2021-02-11T14:11:37.184400Z

I’m trying to run the shadow repl on cursive

zendevil 2021-02-11T14:12:54.184700Z

this is my repl configuration

zendevil 2021-02-11T14:13:14.185200Z

But I’m getting this error:

EOF while trying to sync input stream.

zendevil 2021-02-11T14:13:21.185400Z

when clicking run

thheller 2021-02-11T14:13:31.185600Z

can you see the warning on the bottom? pretty sure you need to add "localhost" to the Host field

thheller 2021-02-11T14:14:33.186400Z

and also select nREPL above, then also select "use port from nrepl file"

thheller 2021-02-11T14:15:54.186600Z

like this

zendevil 2021-02-11T14:22:36.187100Z

@thheller it’s stuck on: Connecting to remote nREPL server...

zendevil 2021-02-11T14:23:00.187200Z

thheller 2021-02-11T14:24:05.188Z

is shadow-cljs running? did you actually configure that port? is it actually running on localhost?

thheller 2021-02-11T14:24:56.188700Z

please use the above setting. you really should not be hardcoding the port ever.

zendevil 2021-02-11T14:25:16.189Z

this is the beginning of the shadow output:

shadow-cljs - HTTP server available at <http://localhost:8021>
shadow-cljs - server version: 2.8.93 running at <http://localhost:9630>
shadow-cljs - nREPL server started on port 7002
shadow-cljs - watching build

thheller 2021-02-11T14:25:54.189600Z

seems fine then. maybe your firewall is blocking the port?

zendevil 2021-02-11T14:26:10.189800Z

how to fix that?

thheller 2021-02-11T14:26:37.190100Z

sorry I cannot help you with macOS questions and note the "maybe". I don't have a clue if that is the cause

zendevil 2021-02-11T14:26:50.190400Z

also I still see shadow-cljs connection closed

zendevil 2021-02-11T14:27:11.191Z

This is the output from jcmd

zendevil 2021-02-11T14:27:14.191300Z

51168 clojure.main -i /private/var/folders/96/df02xppj77g7dx698gtmwmrw0000gn/T/form-init5834689007742471668.clj
53409 clojure.main -i /private/var/folders/96/df02xppj77g7dx698gtmwmrw0000gn/T/form-init6184901872508431686.clj
52882 clojure.main -m leiningen.core.main run -m shadow.cljs.devtools.cli --npm watch app
52885 clojure.main -i /private/var/folders/96/df02xppj77g7dx698gtmwmrw0000gn/T/form-init2867749071698962093.clj
51910 
53993 sun.tools.jcmd.JCmd

thheller 2021-02-11T14:27:51.191800Z

ok that is one shadow-cljs process. the others are lein processes. not sure if you mean to have those.

zendevil 2021-02-11T14:28:12.192200Z

i mean to have one lein process that’s running my app’s server

thheller 2021-02-11T14:29:03.192800Z

ok. but you did not start shadow-cljs in those processes? meaning there is no lein-shadow in your project.clj?

zendevil 2021-02-11T14:30:29.193100Z

I’m not sure:

zendevil 2021-02-11T14:30:29.193200Z

(defproject vendo "0.1.0"

  :description "Main Page. Vendomarch."
  :url "<http://vendomarch.com/>"

  :dependencies [[ch.qos.logback/logback-classic "1.2.3"]
                 [cheshire "5.10.0"]
                 [cljs-ajax "0.8.0"]
                 [clojure.java-time "0.3.2"]
                 [com.cognitect/transit-clj "1.0.324"]
                 [com.fasterxml.jackson.core/jackson-core "2.11.0"]
                 [com.fasterxml.jackson.core/jackson-databind "2.11.0"]
                 [com.google.javascript/closure-compiler-unshaded "v20200504" :scope "provided"]
                 [cprop "0.1.17"]
                 [day8.re-frame/http-fx "0.1.6"]
                 [expound "0.8.4"]
                 [funcool/struct "1.4.0"]
                 [luminus-aleph "0.1.6"]
                 [luminus-transit "0.1.2"]
                 [luminus/ring-ttl-session "0.3.3"]
                 [markdown-clj "1.10.4"]
                 [metosin/jsonista "0.2.6"]
                 [metosin/muuntaja "0.6.7"]
                 [metosin/reitit "0.5.2"]
                 [metosin/ring-http-response "0.9.1"]
                 [mount "0.1.16"]
                 [nrepl "0.7.0"]
                 [org.clojure/clojure "1.10.1"]
                 [org.clojure/clojurescript "1.10.764" :scope "provided"]
                 [org.clojure/core.async "1.1.582"]
                 [org.clojure/google-closure-library "0.0-20191016-6ae1f72f" :scope "provided"]
                 [org.clojure/google-closure-library-third-party "0.0-20191016-6ae1f72f" :scope "provided"]
                 [org.clojure/tools.cli "1.0.194"]
                 [org.clojure/tools.logging "1.1.0"]
                 [org.webjars.npm/bulma "0.8.2"]
                 [org.webjars.npm/material-icons "0.3.1"]
                 [org.webjars/webjars-locator "0.40"]
                 [re-frame "0.12.0"]
                 [reagent "1.0.0-alpha2"]
                 [ring-webjars "0.2.0"]
                 [ring/ring-core "1.8.1"]
                 [ring/ring-defaults "0.3.2"]
                 [selmer "1.12.27"]
                 [thheller/shadow-cljs "2.8.93" :scope "provided"]

                 ;; non-default dependencies
                 [com.novemberain/monger "3.1.0"]
                 [clj-http "3.10.1"]
                 [org.mongodb/mongo-java-driver "3.12.1"]
                 [com.cemerick/url "0.1.1"]
                 [com.draines/postal "2.0.3"]
                 [digest "1.4.9"]


                 ;; cljs
                 [rgm/tailwind-cljs "0.1.0"]
                 [cljs-bean "1.5.0"]

                 [clojurewerkz/elephant "1.0.0-beta18"]
                 ]

  :min-lein-version "2.0.0"
  
  :source-paths ["src/clj" "src/cljs" "src/cljc"]
  :test-paths ["test/clj" "test/cljs"]
  :resource-paths ["resources" "target/cljsbuild"]
  :target-path "target/%s/"
  :main ^:skip-aot vendo.core

  :plugins [[lein-shadow "0.2.0"]] 
  :clean-targets ^{:protect false}
  [:target-path "target/cljsbuild"]
  :shadow-cljs
  {:nrepl {:port 7002}
   :builds
   {:app
    {:target :browser
     :output-dir "target/cljsbuild/public/js"
     :asset-path "/js"
     :modules {:app {:entries [<http://vendo.app|vendo.app>]}}
     :devtools
     {:watch-dir "resources/public" :preloads [re-frisk.preload]}
     :dev
     {:closure-defines {"re_frame.trace.trace_enabled_QMARK_" true}}}
    :test
    {:target :browser-test;;:node-test
     :test-dir  "resources/public/js/test"
     :autorun true
     :ns-regexp ".*"

     :devtools  {:http-port          8021
                 :http-root          "resources/public/js/test"}

     }
    :node-test
    {
     :target :node-test
     :output-to "target/test/test.js"
     }

    :ci
    {
     :target :karma
     :output-to "target/ci.js"
     :ns-regexp ".*"
     }
    
    }}

  :npm-deps [[shadow-cljs "2.8.93"]
             [create-react-class "15.6.3"]
             [react "16.13.0"]
             [react-dom "16.13.0"]]
  :npm-dev-deps [[xmlhttprequest "1.8.0"]]

  :profiles
  {:uberjar {:omit-source true
             :prep-tasks ["compile" ["shadow" "release" "app"]]
             :aot :all
             :uberjar-name "vendo.jar"
             :source-paths ["env/prod/clj"  "env/prod/cljs" ]
             :resource-paths ["env/prod/resources"]}

   :dev           [:project/dev :profiles/dev]
   :test          [:project/dev :project/test :profiles/test]

   :project/dev  {:jvm-opts ["-Dconf=dev-config.edn" ]
                  :dependencies [[binaryage/devtools "1.0.0"]
                                 [cider/piggieback "0.5.0"]
                                 [pjstadig/humane-test-output "0.10.0"]
                                 [prone "2020-01-17"]
                                 [re-frisk "1.3.2"]
                                 [ring/ring-devel "1.8.1"]
                                 [ring/ring-mock "0.4.0"]]
                  :plugins      [[com.jakemccrary/lein-test-refresh "0.24.1"]
                                 [jonase/eastwood "0.3.5"]] 
                  :source-paths ["env/dev/clj"  "env/dev/cljs" "test/cljs" ]
                  :resource-paths ["env/dev/resources"]
                  :repl-options {:init-ns user
                                 :timeout 120000}
                  :injections [(require 'pjstadig.humane-test-output)
                               (pjstadig.humane-test-output/activate!)]}
   :project/test {:jvm-opts ["-Dconf=test-config.edn" ]
                  :resource-paths ["env/test/resources"] 
                  }
   :profiles/dev {}
   :profiles/test {}})

thheller 2021-02-11T14:31:59.194Z

ok, sorry cannot help you with lein-shadow related issues

zendevil 2021-02-11T14:32:37.194700Z

what if I remove the lein-shadow plugin?

thheller 2021-02-11T14:32:48.194900Z

yes, you should do that

thheller 2021-02-11T14:34:06.195600Z

basically what you want is EITHER running everything directly via lein OR running the server parts with lein and the CLJS parts with shadow-cljs

thheller 2021-02-11T14:34:24.196100Z

NOT both. it appears to me that you currently try to do both and them interfering with each other

thheller 2021-02-11T14:34:52.196400Z

I do recommend running things separately always

thheller 2021-02-11T14:35:30.197Z

so in one process you run lein repl or whatever the command there is and in another process you run shadow-cljs watch app

thheller 2021-02-11T14:35:54.197400Z

(I have also never used luminus so I'm not sure how all that works)