shadow-cljs

https://github.com/thheller/shadow-cljs | https://github.com/sponsors/thheller | https://www.patreon.com/thheller
Karol Wójcik 2020-10-03T09:53:56.242700Z

I got some issue while trying to setup https for development. For context I have isomorphic application which I'm porting to shadow. Browser bundle & statics are served from https://example.com and it works perfectly fine, but shadow websocket is unable to connect due to mixed content.

websocket.cljs:12 Mixed Content: The page at '<https://example.com/>' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint '<ws://example.com:9630/api/remote-relay?server-token=44fe5259-462c-40fa-9fdf-9cc475227fb4>'. This request has been blocked; this endpoint must be available over WSS.
Any ideas how to overcome it?

victorb 2020-10-03T10:09:22.242800Z

Try :devtools {:use-document-protocol true}

Karol Wójcik 2020-10-03T11:01:02.243Z

Fixed it by including ssl in shadow!

2020-10-03T12:36:02.244100Z

Hello, If I configured two modules, how can I watch both modules? Thanks.

{:app
    {:target :browser
     :output-dir "target/cljsbuild/public/js"
     :asset-path "/js"
     :modules {:app {:entries [<http://vorstellung.app|vorstellung.app>]}
               :login {:entries [vorstellung.login]}}}

lispers-anonymous 2020-10-03T13:54:32.245400Z

Good morning. https://shadow-cljs.org/ seems to be having some troubles. Firefox is showing me this error.

Warning: Potential Security Risk Ahead

Firefox detected an issue and did not continue to <http://shadow-cljs.org|shadow-cljs.org>. The website is either misconfigured or your computer clock is set to the wrong time.

It's likely the website's certificate is expired, which prevents Firefox from connecting securely. If you visit this site, attackers could try to steal information like your passwords, emails, or credit card details.

thheller 2020-10-03T14:05:26.245800Z

@jiyinyiyong the SSL cert seems to have expired

Karol Wójcik 2020-10-03T18:27:55.247100Z

Any ideas what causes it? It seems that adding the :modules {} broke the build.

base ❯ clj -A:dev:shadow-cljs release browser
[:browser] Compiling ...
npm package "react-transition-group" expected version "react@^15.0.0" but "16.13.1" is installed.
npm package "react-transition-group" expected version "react-dom@^15.0.0" but "16.13.1" is installed.
NullPointerException: 
	com.google.javascript.jscomp.JSModuleGraph.dependsOn (JSModuleGraph.java:371)
	com.google.javascript.jscomp.JSModuleGraph.getDeepestCommonDependencyInclusive (JSModuleGraph.java:467)
	com.google.javascript.jscomp.JSModuleGraph.getDeepestCommonDependencyInclusive (JSModuleGraph.java:482)
	shadow.build.closure.ReplaceCLJSConstants.process (ReplaceCLJSConstants.java:46)
	com.google.javascript.jscomp.Compiler.process (Compiler.java:1066)
	com.google.javascript.jscomp.Compiler.runCustomPasses (Compiler.java:1089)
	com.google.javascript.jscomp.Compiler.check (Compiler.java:1043)
	com.google.javascript.jscomp.Compiler.performChecksAndTranspilation (Compiler.java:855)
	com.google.javascript.jscomp.Compiler.lambda$stage1Passes$0 (Compiler.java:785)
	com.google.javascript.jscomp.CompilerExecutor.runInCompilerThread (CompilerExecutor.java:129)
	com.google.javascript.jscomp.Compiler.runInCompilerThread (Compiler.java:843)
	com.google.javascript.jscomp.Compiler.stage1Passes (Compiler.java:783)
	com.google.javascript.jscomp.Compiler.compileModules (Compiler.java:756)
	sun.reflect.NativeMethodAccessorImpl.invoke0 (NativeMethodAccessorImpl.java:-2)
	sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
	sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
	java.lang.reflect.Method.invoke (Method.java:498)
	clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:167)
	clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:102)
	shadow.build.closure/compile-js-modules (closure.clj:1064)
	shadow.build.closure/compile-js-modules (closure.clj:1053)
	shadow.build.closure/optimize/fn--13180 (closure.clj:1253)
	shadow.build.closure/optimize (closure.clj:1239)
	shadow.build.closure/optimize (closure.clj:1230)
	shadow.build.api/optimize (api.clj:271)
	shadow.build.api/optimize (api.clj:265)
	shadow.build/optimize (build.clj:457)
	shadow.build/optimize (build.clj:449)
	shadow.cljs.devtools.api/release* (api.clj:339)
	shadow.cljs.devtools.api/release* (api.clj:324)
	shadow.cljs.devtools.cli-actual/do-build-command (cli_actual.clj:28)
	shadow.cljs.devtools.cli-actual/do-build-command (cli_actual.clj:25)
	shadow.cljs.devtools.cli-actual/do-build-commands (cli_actual.clj:49)
	shadow.cljs.devtools.cli-actual/do-build-commands (cli_actual.clj:38)
	shadow.cljs.devtools.cli-actual/main/body-fn--17785--auto----18493 (cli_actual.clj:166)
	shadow.cljs.devtools.cli-actual/main (cli_actual.clj:165)
	shadow.cljs.devtools.cli-actual/main (cli_actual.clj:132)
	clojure.core/apply (core.clj:669)
	clojure.core/apply (core.clj:660)
	shadow.cljs.devtools.cli-actual/-main (cli_actual.clj:219)
	shadow.cljs.devtools.cli-actual/-main (cli_actual.clj:217)
	clojure.lang.Var.applyTo (Var.java:705)
	clojure.core/apply (core.clj:665)
	clojure.core/apply (core.clj:660)
	shadow.cljs.devtools.cli/-main (cli.clj:75)
	shadow.cljs.devtools.cli/-main (cli.clj:67)
	clojure.lang.Var.applyTo (Var.java:705)
	clojure.core/apply (core.clj:665)
	clojure.main/main-opt (main.clj:491)
	clojure.main/main-opt (main.clj:487)
	clojure.main/main (main.clj:598)
	clojure.main/main (main.clj:561)
	clojure.lang.Var.applyTo (Var.java:705)
	clojure.main.main (main.java:37)

jplaza 2020-10-03T18:38:58.247900Z

👋 I’m getting a

Cannot infer target type in expression (. (. BigJSHandler -prototype) -rep)
For this deftype
(deftype BigJSHandler []
  Object
  (tag [this v] "bigjs")
  (rep [this ^js/Big v] (.toFixed v))
  (stringRep [this v] nil))

jplaza 2020-10-03T18:39:33.248700Z

I think extern inference is not working as expected, maybe I have to provide an externs file?

Karol Wójcik 2020-10-03T18:43:39.248800Z

@thheller I don't know whether it's common, but I experience about 400kb increase in bundle size when using multiple modules.

thheller 2020-10-03T18:50:36.249Z

thats not normal and not something I have ever seen

thheller 2020-10-03T18:50:44.249200Z

the above I also don't know

thheller 2020-10-03T18:50:52.249400Z

which version is this?

thheller 2020-10-03T18:51:14.249600Z

the errors suggests its something wrong with your :modules setup and their :depends-on config

thheller 2020-10-03T18:52:05.250600Z

@jplaza yeah I don't know what that is about. I thing (deftype ^js BigJSHandler ...) fixes it. otherwise you can also set (set! *warn-on-infer* false) before and true after to silence it for now

jplaza 2020-10-03T18:57:47.251300Z

Thanks @thheller ! ^js worked perfectly. Also this externs worked too

var Object = function() {};
Object.prototype.tag = function() {};
Object.prototype.rep = function() {};
Object.prototype.stringRep = function() {};

thheller 2020-10-03T19:08:32.252200Z

yeah but you don't actually want externs for this

thheller 2020-10-03T19:08:38.252400Z

it is fine if it gets renamed

thheller 2020-10-03T19:09:16.253100Z

but it is fine. it is just some kind of regression. don't yet know why the warning is back.

Karol Wójcik 2020-10-03T19:41:41.253200Z

@thheller Here is how :modules look like for increased build.

Karol Wójcik 2020-10-03T19:41:41.253400Z

Used version is: 2.11.4

{:browser-core                 {:entries    [core.browser]
                                                             :init-fn    core.browser/main}

                              ;; :view-checkout-payment-stage  {:entries    [view.checkout.payment-stage]
                              ;;                                :depends-on #{:browser-core}},
                              :view-ui-cms-tooltip          {:entries    [view.ui.cms-tooltip]
                                                             :depends-on #{:browser-core}}
                              ;; :view-checkout-delivery-stage {:entries    [view.checkout.delivery-stage]
                              ;;                                :depends-on #{:browser-core}}
                              :view-rich-content            {:entries    [view.rich-content]
                                                             :depends-on #{:browser-core}}
                              :view-debug-page              {:entries    [view.debug-page]
                                                             :depends-on #{:browser-core}}
                              :view-ui-hero                 {:entries    [view.ui.hero]
                                                             :depends-on #{:browser-core}}
                              :view-product-lists           {:entries    [view.product-lists]
                                                             :depends-on #{:browser-core}}
                              :view-about-pages             {:entries    [view.about-pages]
                                                             :depends-on #{:browser-core :view-reservation :view-vouchers}}
                              :view-sis                     {:entries    [view.sis]
                                                             :depends-on #{:browser-core :view-action-pages}}
                              :view-lps-pages               {:entries    [view.lps-pages]
                                                             :depends-on #{:browser-core}}
                              :view-help-forum              {:entries    [view.help-forum]
                                                             :depends-on #{:browser-core}}
                              :view-membership-gifts        {:entries    [view.membership.gifts]
                                                             :depends-on #{:browser-core :view-membership-common}}
                              :view-wines-factory           {:entries    [view.wines-factory]
                                                             :depends-on #{:browser-core}}
                              :view-newsletter              {:entries    [view.newsletter]
                                                             :depends-on #{:browser-core}}
                              :view-recipe                  {:entries    [view.recipe]
                                                             :depends-on #{:browser-core}}
                              :view-settings                {:entries    [view.settings]
                                                             :depends-on #{:browser-core :view-checkout-payment}}
                              :view-notification            {:entries    [view.notification]
                                                             :depends-on #{:browser-core}}
                              :view-cards                   {:entries    [view.cards]
                                                             :depends-on #{:browser-core}}
                              :view-action-pages            {:entries    [view.action-pages]
                                                             :depends-on #{:browser-core}}
                              :view-promo-pages             {:entries    [view.promo-pages]
                                                             :depends-on #{:browser-core}}
                              :view-office-page             {:entries    [view.office-page]
                                                             :depends-on #{:browser-core}}
                              :view-lp-affilation-page      {:entries    [view.lp.affilation-page]
                                                             :depends-on #{:browser-core}}
                              :view-new-brand-shop          {:entries    [view.new-brand-shop]
                                                             :depends-on #{:browser-core}}
                              :view-membership-common       {:entries    [view.membership.common]
                                                             :depends-on #{:browser-core}}
                              :view-reservation             {:entries    [view.reservation]
                                                             :depends-on #{:browser-core :view-vouchers}}
                              :view-membership-rebate       {:entries    [view.membership.rebate]
                                                             :depends-on #{:browser-core :view-product-lists :view-membership-common}}
                              :view-rodo                    {:entries    [view.rodo]
                                                             :depends-on #{:browser-core}}
                              :view-brand-shops             {:entries    [view.brand-shops]
                                                             :depends-on #{:browser-core}}
                              :view-brandbank               {:entries    [view.brandbank]
                                                             :depends-on #{:browser-core}}
                              :view-membership-banner       {:entries    [view.membership.banner]
                                                             :depends-on #{:browser-core :view-membership-common}}
                              :view-lp-membership           {:entries    [view.lp.membership]
                                                             :depends-on #{:browser-core :view-ui-hero :view-lps-pages :view-membership-common :view-membership-banner}}
                              :view-checkout                {:entries    [view.checkout]
                                                             :depends-on #{:browser-core :view-product-lists :view-settings}}
                              :view-importer                {:entries    [view.importer]
                                                             :depends-on #{:browser-core}}
                              :view-survey                  {:entries    [view.survey]
                                                             :depends-on #{:browser-core}}
                              ;; :view-lp-fruits-and-vegs      {:entries    [view.lp.fruits-and-vegs]
                              ;;                                :depends-on #{:browser-core}}
                              :view-cart                    {:entries    [view.cart]
                                                             :depends-on #{:browser-core :view-product-lists}}
                              :view-page-logged-in          {:entries    [view.page.logged-in]
                                                             :depends-on #{:browser-core}}
                              :view-checkout-payment        {:entries    [view.checkout.payment]
                                                             :depends-on #{:browser-core}}
                              :view-login                   {:entries    [view.login]
                                                             :depends-on #{:browser-core}}
                              ;; :view-checkout-products-stage {:entries    [view.checkout.products-stage]
                              ;;                                :depends-on #{:browser-core}}
                              :view-mailing                 {:entries    [view.mailing]
                                                             :depends-on #{:browser-core}}
                              :view-ui-video-player         {:entries    [view.ui.video-player]
                                                             :depends-on #{:browser-core}}
                              :view-cart-promotions         {:entries    [view.cart-promotions]
                                                             :depends-on #{:browser-core :view-vouchers}}
                              :view-shopping-lists          {:entries    [view.shopping-lists]
                                                             :depends-on #{:browser-core :view-product-lists}}
                              :view-products-product-page   {:entries    [view.products.product-page]
                                                             :depends-on #{:browser-core}}
                              :view-contest                 {:entries    [view.contest]
                                                             :depends-on #{:browser-core}}
                              :view-lp-ready-meals-page     {:entries    [view.lp.ready-meals-page]
                                                             :depends-on #{:browser-core :view-ui-hero :view-product-lists :view-lps-pages :view-settings :view-reservation :view-checkout :view-checkout-payment}}
                              :view-email-preview           {:entries    [view.email-preview]
                                                             :depends-on #{:browser-core}}
                              :view-lp-business-page        {:entries    [view.lp.business-page]
                                                             :depends-on #{:browser-core :view-ui-hero :view-rodo}}
                              :view-vouchers                {:entries    [view.vouchers]
                                                             :depends-on #{:browser-core}}}

Karol Wójcik 2020-10-03T19:45:49.253900Z

And that configuration was used which ended up with error:

Karol Wójcik 2020-10-03T19:45:49.254100Z

{:browser-core                 {:entries    [core.browser]
                                                             :init-fn    core.browser/main}
                              :shared {:depends-on #{:browser-core}}

                              ;; :view-checkout-payment-stage  {:entries    [view.checkout.payment-stage]
                              ;;                                :depends-on #{:browser-core}},
                              :view-ui-cms-tooltip          {:entries    [view.ui.cms-tooltip]
                                                             :depends-on #{:shared}
                                                             }
                              ;; :view-checkout-delivery-stage {:entries    [view.checkout.delivery-stage]
                              ;;                                :depends-on #{:shared}}
                              :view-rich-content            {:entries    [view.rich-content]
                                                             :depends-on #{:shared}}
                              :view-debug-page              {:entries    [view.debug-page]
                                                             :depends-on #{:shared}}
                              :view-ui-hero                 {:entries    [view.ui.hero]
                                                             :depends-on #{:shared}}
                              :view-product-lists           {:entries    [view.product-lists]
                                                             :depends-on #{:shared}}
                              :view-about-pages             {:entries    [view.about-pages]
                                                             :depends-on #{:shared :view-reservation :view-vouchers}}
                              :view-sis                     {:entries    [view.sis]
                                                             :depends-on #{:shared :view-action-pages}}
                              :view-lps-pages               {:entries    [view.lps-pages]
                                                             :depends-on #{:shared}}
                              :view-help-forum              {:entries    [view.help-forum]
                                                             :depends-on #{:shared}}
                              :view-membership-gifts        {:entries    [view.membership.gifts]
                                                             :depends-on #{:shared :view-membership-common}}
                              :view-wines-factory           {:entries    [view.wines-factory]
                                                             :depends-on #{:shared}}
                              :view-newsletter              {:entries    [view.newsletter]
                                                             :depends-on #{:shared}}
                              :view-recipe                  {:entries    [view.recipe]
                                                             :depends-on #{:shared}}
                              :view-settings                {:entries    [view.settings]
                                                             :depends-on #{:shared :view-checkout-payment}}
                              :view-notification            {:entries    [view.notification]
                                                             :depends-on #{:shared}}
                              :view-cards                   {:entries    [view.cards]
                                                             :depends-on #{:shared}}
                              :view-action-pages            {:entries    [view.action-pages]
                                                             :depends-on #{:shared}}
                              :view-promo-pages             {:entries    [view.promo-pages]
                                                             :depends-on #{:shared}}
                              :view-office-page             {:entries    [view.office-page]
                                                             :depends-on #{:shared}}
                              :view-lp-affilation-page      {:entries    [view.lp.affilation-page]
                                                             :depends-on #{:shared}}
                              :view-new-brand-shop          {:entries    [view.new-brand-shop]
                                                             :depends-on #{:shared}}
                              :view-membership-common       {:entries    [view.membership.common]
                                                             :depends-on #{:shared}}
                              :view-reservation             {:entries    [view.reservation]
                                                             :depends-on #{:shared :view-vouchers}}
                              :view-membership-rebate       {:entries    [view.membership.rebate]
                                                             :depends-on #{:shared :view-product-lists :view-membership-common}}
                              :view-rodo                    {:entries    [view.rodo]
                                                             :depends-on #{:shared}}
                              :view-brand-shops             {:entries    [view.brand-shops]
                                                             :depends-on #{:shared}}
                              :view-brandbank               {:entries    [view.brandbank]
                                                             :depends-on #{:shared}}
                              :view-membership-banner       {:entries    [view.membership.banner]
                                                             :depends-on #{:shared :view-membership-common}}
                              :view-lp-membership           {:entries    [view.lp.membership]
                                                             :depends-on #{:shared :view-ui-hero :view-lps-pages :view-membership-common :view-membership-banner}}
                              :view-checkout                {:entries    [view.checkout]
                                                             :depends-on #{:shared :view-product-lists :view-settings}}
                              :view-importer                {:entries    [view.importer]
                                                             :depends-on #{:shared}}
                              :view-survey                  {:entries    [view.survey]
                                                             :depends-on #{:shared}}
                              ;; :view-lp-fruits-and-vegs      {:entries    [view.lp.fruits-and-vegs]
                              ;;                                :depends-on #{:shared}}
                              :view-cart                    {:entries    [view.cart]
                                                             :depends-on #{:shared :view-product-lists}}
                              :view-page-logged-in          {:entries    [view.page.logged-in]
                                                             :depends-on #{:shared}}
                              :view-checkout-payment        {:entries    [view.checkout.payment]
                                                             :depends-on #{:shared}}
                              :view-login                   {:entries    [view.login]
                                                             :depends-on #{:shared}}
                              ;; :view-checkout-products-stage {:entries    [view.checkout.products-stage]
                              ;;                                :depends-on #{:browser-core}}
                              :view-mailing                 {:entries    [view.mailing]
                                                             :depends-on #{:browser-core}}
                              :view-ui-video-player         {:entries    [view.ui.video-player]
                                                             :depends-on #{:browser-core}}
                              :view-cart-promotions         {:entries    [view.cart-promotions]
                                                             :depends-on #{:browser-core :view-vouchers}}
                              :view-shopping-lists          {:entries    [view.shopping-lists]
                                                             :depends-on #{:browser-core :view-product-lists}}
                              :view-products-product-page   {:entries    [view.products.product-page]
                                                             :depends-on #{:browser-core}}
                              :view-contest                 {:entries    [view.contest]
                                                             :depends-on #{:browser-core}}
                              :view-lp-ready-meals-page     {:entries    [view.lp.ready-meals-page]
                                                             :depends-on #{:browser-core :view-ui-hero :view-product-lists :view-lps-pages :view-settings :view-reservation :view-checkout :view-checkout-payment}}
                              :view-email-preview           {:entries    [view.email-preview]
                                                             :depends-on #{:browser-core}}
                              :view-lp-business-page        {:entries    [view.lp.business-page]
                                                             :depends-on #{:browser-core :view-ui-hero :view-rodo}}
                              :view-vouchers                {:entries    [view.vouchers]
                                                             :depends-on #{:browser-core}}}

thheller 2020-10-03T19:59:58.254300Z

yikes. splits like that are completely pointless

thheller 2020-10-03T20:00:42.254500Z

well not completely but very unlikely to be optimal

thheller 2020-10-03T20:01:10.254700Z

don't you get a bazillion really small files and then a couple really large ones?

thheller 2020-10-03T20:16:42.254900Z

totally possible that something in the system breaks with this many modules. never seen this many before 😛

Karol Wójcik 2020-10-03T20:45:03.255100Z

Well actually this is what I get.

Karol Wójcik 2020-10-03T21:20:18.255300Z

Actually even if I split to two modules I can see about 200kb increase in build size.

Karol Wójcik 2020-10-03T21:23:27.255500Z

What is $APP?

thheller 2020-10-03T22:08:52.255800Z

the only global variable so modules can access shared code

thheller 2020-10-03T22:09:49.256Z

what does the build report look like? where are the 200kb coming from?