Fork me on GitHub
#shadow-cljs
<
2020-09-24
>
thheller07:09:57

@daemianmack you can just run shadow-cljs watch build1 build2 build3 and then shadow-cljs cljs-repl build1 and so on (or nrepl) to talk to a specific REPL for a given build

thheller07:09:35

you can have as many REPLs as you want but most editors don't do session management very well

andre09:09:35

hi, when upgrading from 2.9.2 to the latest version, there is an error on Android, but works fine on ios , react native project

andre09:09:30

and it seems work fine with hermes engine disabled

andre09:09:31

so something has been changed after 2.9.2 and it won't work in hermes engine

thheller09:09:47

hmm no clue. would help to know what that statement was 😛

yenda10:09:06

@thheller there is an instant crash with shadow-cljs on react-native when using the hermes engine "Property Long doesn't exist" related to goog.math.long.js . I bisected through shadow-cljs versions and it looks like 2.9.4 is clean, 2.9.5 is not on npm, and 2.9.6 has the bug

yenda10:09:19

we are not using goog.math.long anywhere directly, but it looks like transit does indirectly

yenda10:09:04

since it works fine in release I wonder if that could be related to this commit https://github.com/thheller/shadow-cljs/commit/c5ce449c5749c9a7dd7ed0f9d58ec5f78b826e03

thheller10:09:17

I don't have a clue. goog.math.Long is used by cljs.core. sounds like a bug in hermes to me though?

thheller10:09:07

I assume you tested with 2.11.4 too?

yenda10:09:10

It can't be a bug in hermes because there is no bug in shadow-cljs 2.9.4, and no bug in release

yenda10:09:43

yes I tried 2.11.4 as well

yenda10:09:55

any version above 2.9.4 has the bug

yenda10:09:06

(2.9.5 is not on npm for some reason though)

thheller10:09:56

just set :version "2.9.5" in shadow-cljs.edn (assuming you use neither project.clj nor deps.edn)

thheller10:09:56

is there more to the "Property Long doesn't exist" error though? I can't do much without knowing what the actual code is that crashes

thheller10:09:11

I mean just run a shadow-cljs compile build and load it

thheller10:09:18

if it crashes the code should be easy to find

yenda10:09:42

no compilation is fine as I said release works with any version

thheller10:09:45

it might be a bug in hermes because of eval

thheller10:09:59

release builds don't eval

yenda10:09:06

and the crash doesn't give much info

yenda10:09:39

in the phone logs it's even less

thheller10:09:46

run shadow-cljs compile build

thheller10:09:03

then the app/index.js is self-contained and won't connect to the REPL

thheller10:09:11

you can edit that file

thheller10:09:26

it will have a bunch of evalLoad calls

thheller10:09:59

env.evalLoad = function(name, code) {
        goog.globalEval(code);
    };

thheller10:09:11

should be in the code somewhere in the beginning

yenda10:09:17

yenda@desktop:~/clash-mobile$ shadow-cljs compile app
shadow-cljs - config: /home/yenda/clash-mobile/shadow-cljs.edn  cli version: 2.8.76  node: v12.16.1
[:app] Compiling ...
Failed writing cache for taoensso.encore: java.lang.Exception: Not supported: class shadow.build.compiler$analyze$fn__11740
[:app] Build completed. (271 files, 270 compiled, 0 warnings, 11.07s)

thheller10:09:23

maybe try adding console.log("loading", name, code) or so

thheller10:09:46

just to find the code that actually fails

yenda10:09:12

when I run the code generated by shadow-cljs compile build I have no error

thheller10:09:54

then do the same with a running watch

thheller10:09:06

just don't make any other changes or your mod will be overwritten

thheller10:09:33

also make sure to test with 2.11.4 please

thheller10:09:42

no point in testing with 2.9.6

yenda10:09:33

shadow-cljs - server version: 2.11.4 running at http://localhost:3449

yenda10:09:13

the last statement I see in the log is loading goog.math.long.js goog.loadModule(function(exports) and then the whole module code

yenda10:09:56

@thheller If you want more details:

thheller10:09:12

that file isn't rewritten at all?

thheller10:09:52

ah hmm I guess the problem might be the :output-feature-set

thheller10:09:01

that prevents it from rewriting the class Long and that maybe confuses Hermes?

thheller10:09:17

hmm although that should also fail in compile builds

yenda10:09:29

there is a SHADOW_ENV.evalLoad in the file

SHADOW_ENV.evalLoad("goog.math.long.js", "goog.loadModule(function(exports) {\n  \x22use strict\x22;\n  goog.module(\x22goog.math.Long\x22);\n  goog.module.declareLegacyNamespace();\n  const asserts \x3d goog.require(\x22goog.asserts\x22);\n  const reflect \x3d goog.require(\x22goog.reflect\x22);\n  class Long {\n    constructor(low, high) {\n      this.low_ \x3d low | 0;\n      this.high_ \x3d high | 0;\n    }\n    toInt() {\n      return this.low_;\n    }\n    toNumber() {\n      return this.high_ * TWO_PWR_32_DBL_ + this.getLowBitsUnsigned();\n    }\n    isSafeInteger() {\n      var top11Bits \x3d this.high_ \x3e\x3e 21;\n      return top11Bits \x3d\x3d 0 || top11Bits \x3d\x3d -1 \x26\x26 !(this.low_ \x3d\x3d 0 \x26\x26 this.high_ \x3d\x3d (4292870144 | 0));\n    }\n    toString(opt_radix) {\n      var radix \x3d opt_radix || 10;\n      if (radix \x3c 2 || 36 \x3c radix) {\n        throw new Error(\x22radix out of range: \x22 + radix);\n      }\n      if (this.isSafeInteger()) {\n        var asNumber \x3d this.toNumber();\n        return radix \x3d\x3d 10 ? \x22\x22 + asNumber : asNumber.toString(radix);\n      }\n      var safeDigits \x3d 14 - (radix \x3e\x3e 2);\n      var radixPowSafeDigits \x3d Math.pow(radix, safeDigits);\n      var radixToPower \x3d Long.fromBits(radixPowSafeDigits, radixPowSafeDigits / TWO_PWR_32_DBL_);\n      var remDiv \x3d this.div(radixToPower);\n      var val \x3d Math.abs(this.subtract(remDiv.multiply(radixToPower)).toNumber());\n      var digits \x3d radix \x3d\x3d 10 ? \x22\x22 + val : val.toString(radix);\n      if (digits.length \x3c safeDigits) {\n        digits \x3d \x220000000000000\x22.substr(digits.length - safeDigits) + digits;\n      }\n      val \x3d remDiv.toNumber();\n      return (radix \x3d\x3d 10 ? val : val.toString(radix)) + digits;\n    }\n    getHighBits() {\n      return this.high_;\n    }\n    getLowBits() {\n      return this.low_;\n    }\n    getLowBitsUnsigned() {\n      return this.low_ \x3e\x3e\x3e 0;\n    }\n    getNumBitsAbs() {\n      if (this.isNegative()) {\n        if (this.equals(Long.getMinValue())) {\n          return 64;\n        } else {\n          return this.negate().getNumBitsAbs();\n        }\n      } else {\n        var val \x3d this.high_ !\x3d 0 ? this.high_ : this.low_;\n        for (var bit \x3d 31; bit \x3e 0; bit--) {\n          if ((val \x26 1 \x3c\x3c bit) !\x3d 0) {\n            break;\n          }\n   ...

thheller10:09:53

yeah all that looks exactly like it should

thheller10:09:07

not a clue why it works in compile but not watch?

thheller10:09:36

I mean watch loads more (and connects websocket) but all of that comes after goog.math.Long

yenda10:09:28

(it loads the rest afterward)

yenda10:09:52

@thheller if you look at the module it looks like they are not the same, not sure if that matters but for instance /** @const */ var reflect in 2.9.4 vs const reflect in 2.11.4

yenda10:09:07

so maybe you were write and it has something to do with feature set?

thheller10:09:45

yes, if you set :output-feature-set :es5 that should change the rewriting

thheller10:09:09

but again .. that sounds like a bug in hermes to me then

yenda10:09:36

I'm not very familiar with these feature set so what changed between 2.9.4 and now?

yenda10:09:27

Hermes is compiling js into bytecode

yenda10:09:59

{:target :react-native
           :init-fn app.core/init
           :output-dir "app"
           :dev {:devtools {
                            :autoload true
                            :reload-strategy :full
                            :after-load app.core/reload
                            :compiler-options {:source-map false
                                               :output-feature-set :es5}}
                 :local-ip #shadow/env "SHADOW_HOST"}
           :release {:compiler-options {:output-feature-set :es6
                                        :warnings-as-errors true
                                        :infer-externs :auto
                                        :optimizations :advanced
                                        :js-options {:js-provider :closure}}}}

yenda10:09:04

I still have the error with this config

yenda11:09:31

and the modules still have the const reflect syntax in index.js

SHADOW_ENV.evalLoad("goog.math.long.js", "goog.loadModule(function(exports) {\n  \x22use strict\x22;\n  goog.module(\x22goog.math.Long\x22);\n  goog.module.declareLegacyNamespace();\n  const asserts \x3d goog.require(\x22goog.asserts\x22);\n  const reflect \x3d goog.require(\x22goog.reflect\x22);\n  class Long {\n    constructor(low, high) {\n      this.low_ \x3d low | 0;\n      this.high_ \x3d high | 0;\n    }\n    toInt() {\n      return this.low_;\n    }\n    toNumber() {\n      return this.high_ * TWO_PWR_32_DBL_ + this.getLowBitsUnsigned();\n    }\n    isSafeInteger() {\n      var top11Bits \x3d this.high_ \x3e\x3e 21;\n      return top11Bits \x3d\x3d 0 || top11Bits \x3d\x3d -1 \x26\x26 !(this.low_ \x3d\x3d 0 \x26\x26 this.high_ \x3d\x3d (4292870144 | 0));\n    }\n    toString(opt_radix) {\n      var radix \x3d opt_radix || 10;\n      if (radix \x3c 2 || 36 \x3c radix) {\n        throw new Error(\x22radix out of range: \x22 + radix);\n      }\n      if (this.isSafeInteger()) {\n        var asNumber \x3d this.toNumber();\n        return radix \x3d\x3d 10 ? \x22\x22 + asNumber : asNumber.toString(radix);\n      }\n      var safeDigits \x3d 14 - (radix \x3e\x3e 2);\n      var radixPowSafeDigits \x3d Math.pow(radix, safeDigits);\n      var radixToPower \x3d Long.fromBits(radixPowSafeDigits, radixPowSafeDigits / TWO_PWR_32_DBL_);\n      var remDiv \x3d this.div(radixToPower);\n      var val \x3d Math.abs(this.subtract(remDiv.multiply(radixToPower)).toNumber());\n      var digits \x3d radix \x3d\x3d 10 ? \x22\x22 + val : val.toString(radix);\n      if (digits.length \x3c safeDigits) {\n        digits \x3d \x220000000000000\x22.substr(digits.length - safeDigits) + digits;\n      }\n      val \x3d remDiv.toNumber();\n      return (radix \x3d\x3d 10 ? val : val.toString(radix)) + digits;\n    }\n    getHighBits() {\n      return this.high_;\n    }\n    getLowBits() {\n      return this.low_;\n    }\n    getLowBitsUnsigned() {\n   

yenda11:09:21

2.9.4:

SHADOW_ENV.evalLoad("goog.math.long.js", "goog.loadModule(function(exports) {\n  \x22use strict\x22;\n  goog.module(\x22goog.math.Long\x22);\n  goog.module.declareLegacyNamespace();\n  /** @const */ var asserts \x3d goog.require(\x22goog.asserts\x22);\n  /** @const */ var reflect \x3d goog.require(\x22goog.reflect\x22);\n  /** @final @constructor */ var Long \x3d function(low, high) {\n    /** @private @const @type {number} */ this.low_ \x3d low | 0;\n    /** @private @const @type {number} */ this.high_ \x3d high | 0;\n  };\n  /**\n   * @return {number}\n   */\n  Long.prototype.toInt \x3d function() {\n    return this.low_;\n  };\n  /**\n   * @return {number}\n   */\n  Long.prototype.toNumber \x3d function() {\n    return this.high_ * TWO_PWR_32_DBL_ + this.getLowBitsUnsigned();\n  };\n  /**\n   * @return {boolean}\n   */\n  Long.prototype.isSafeInteger \x3d function() {\n    var top11Bits \x3d this.high_ \x3e\x3e 21;\n    return top11Bits \x3d\x3d 0 || top11Bits \x3d\x3d -1 \x26\x26 !(this.low_ \x3d\x3d 0 \x26\x26 this.high_ \x3d\x3d (4292870144 | 0));\n  };\n  /**\n   * @param {number\x3d} opt_radix\n   * @return {string}\n   * @override\n   */\n  Long.prototype.toString \x3d function(opt_radix) {\n    var radix \x3d opt_radix || 10;\n    if (radix \x3c 2 || 36 \x3c radix) {\n      throw new Error(\x22radix out of range: \x22 + radix);\n    }\n    if (this.isSafeInteger()) {\n      var asNumber \x3d this.toNumber();\n      return radix \x3d\x3d 10 ? \x22\x22 + asNumber : asNumber.toString(radix);\n    }\n    var safeDigits \x3d 14 - (radix \x3e\x3e 2);\n    var radixPowSafeDigits \x3d Math.pow(radix, safeDigits);\n    var radixToPower \x3d Long.fromBits(radixPowSafeDigits, radixPowSafeDigits / TWO_PWR_32_DBL_);\n    var remDiv \x3d this.div(radixToPower);\n    var val \x3d Math.abs(this.subtract(remDiv.multiply(radixToPower)).toNumber());\n    var digits \x3d radix \x3d\x3d 10 ? \x22\x22 + val : val.toString(radix);\n    if (digits.length \x3c safeDigits) {\n      digits \x3d \x220000000000000\x22.substr(digits.length - safeDigits) + digits;\n    }\n    val \x3d remDiv.toNumber();\n    return (radix \x3d\x3d 10 ? val : val.toString(radix)) + digits;\n  };\n  /**\n   * @return {number}\n   */\n  Long.prototype.getHighBits \x3d function() {\n    return this.high_;\n  };\n  /**\n   * @return {number}\n   */\n  Long.prototype.getLowBits \x3d function() {\n    return this.low_;\n  };\n  /**\n 

yenda11:09:39

@thheller ok looks like it works when I put compiler options at the top level of my build

yenda11:09:03

@thheller so the fix for now is to have :compiler-options {:output-feature-set :es5} at the top level of your build config map when you want to use hermes on react-native target

grounded_sage11:09:52

Anyone have experience with doing the :target :karma and it not launching the headless chrome when running npx karma start --single-run?

victorb11:09:23

Hello everyone! Seems when I sometimes reload my browser window, vim-fireplace is loosing the connection with the page and cannot re-establish it. Trying to send commands after this happens show the following error:

[2020-09-24 13:16:06.847 - WARNING] :shadow.cljs.devtools.server.util/handle-ex - {:msg {:op :cljs-load-sources, :sources [[:shadow.build.classpath/resource "cljs/spec/gen/alpha.cljs"] [:shadow.build.classpath/resource "cljs/spec/alpha.cljs"] [:shadow.build.classpath/resource "cljs/repl.cljs"] [:shadow.cljs.repl/resource "cljs/user.cljs"]], :call-id 1, :from 24}}
ExceptionInfo no output for id: [:shadow.cljs.repl/resource "cljs/user.cljs"] {:resource-id [:shadow.cljs.repl/resource "cljs/user.cljs"]}
        shadow.build.data/get-output! (data.clj:197)
        shadow.build.data/get-output! (data.clj:193)
        shadow.cljs.devtools.server.worker.impl/fn--15169/fn--15172 (impl.clj:813)
        clojure.core/map/fn--5866 (core.clj:2753)
        clojure.lang.LazySeq.sval (LazySeq.java:42)
        clojure.lang.LazySeq.seq (LazySeq.java:51)
        clojure.lang.RT.seq (RT.java:535)
        clojure.core/seq--5402 (core.clj:137)
        clojure.core.protocols/seq-reduce (protocols.clj:24)
        clojure.core.protocols/fn--8146 (protocols.clj:75)
        clojure.core.protocols/fn--8146 (protocols.clj:75)
        clojure.core.protocols/fn--8088/G--8083--8101 (protocols.clj:13)
My config currently looks like this, basically the minimal one I could get my hands on.
;; shadow-cljs configuration
{:source-paths
 ["src/dev"
  "src/main"
  "src/test"]

 :dependencies
 [[reagent "1.0.0-alpha2"]]

 :dev-http {8081 "public"}
 
 :nrepl {:port 8082}

 :builds
 {:frontend
  {:target :browser
   :modules {:main {:init-fn app/init}}}}}
I come from using figwheel and figwheel-main for a long time, first time using shadow-cljs for a project, so probably I'm doing something wrong here. Using neovim, vim-fireplace. Running shadow-cljs by running npx shadow-cljs watch frontend , connecting my repl by doing :Connect 8082 and then :Piggieback :frontend . Everything works except until I reload the page, then starting to get that error above and the only thing I can do to make it work is restarting shadow-cljs watch again, then it starts working.

thheller11:09:51

@victorbjelkholm429 which version is this? this should have been fixed a while ago.

victorb11:09:47

@thheller 2.11.4, think the project was bootstrapped from create-cljs-project so got the version from there

victorb11:09:46

hm, could be the vim-fireplace version maybe? I'll check those out too

thheller11:09:51

weird. anything in particular you are doing with the REPL?

victorb11:09:34

no, just calling println's and alike, nothing extreme

thheller11:09:36

not sure why you reloading the page affects anything on the compiler side

victorb11:09:25

@thheller was behind a few commits in vim-fireplace. Upgraded and now not getting the error again... But will keep trying to reproduce, but seems fixed now. Well, thanks for the rubberducking @thheller 🙂

👍 3
thheller11:09:32

@andre why would it? its not supposed to? it is supposed to be identical in dev/release?

thheller11:09:06

I say again ... this very much sounds like a bug in hermes to me if it works in other engines

thheller11:09:30

given that chrome, firefox, etc have no issues with this whatsoever

thheller11:09:16

and again .. I suspect eval to be the cause here. release builds will not eval and instead load the code directly.

thheller11:09:47

I do not have any necessary setup to test hermes so can't say much more

thheller11:09:04

the code shadow-cljs produces looks exactly like it should, :es5 should not be a required setting but if it makes hermes happy then fine just set it

thheller11:09:32

you can set :dev {:compiler-options {:output-feature-set :es5}} if you only want it in dev

yenda12:09:15

it doesn't work if you set it in dev @thheller, I had to set it in the top level of the build map

yenda12:09:51

Is there a way to write jsx file alongside cljs and import the components in cljs files? It works with js but I don't understand the stack enough to figure out how to make sure the jsx stuff gets transpiled

simongray13:09:44

Not having any luck attempting to use oz via shadow-cljs. At first I just tried going by the instructions in the Oz github readme, but kept running into an error with a missing file. Shadow-cljs was looking for a .js file, but in the folder only .min.js, .node.js and .module.js were available. Then I found this template project and the exact same error occurs: https://github.com/ivanminutillo/reagent-shadow-oz-example

[:app] Build failure:
override to file that doesn't exist
{:tag :shadow.build.npm/invalid-override, :require-from #object[java.io.File 0x4d68156d "/Users/rqf595/Code/temp/reagent-shadow-oz-example/node_modules/vega-dataflow/build/vega-dataflow.js"], :require "vega-loader", :file #object[java.io.File 0x41ebcb92 "/Users/rqf595/Code/temp/reagent-shadow-oz-example/node_modules/vega-loader/build/vega-loader.node.js"], :override "./build/vega-loader.js", :override-file #object[java.io.File 0x5d156b61 "/Users/rqf595/Code/temp/reagent-shadow-oz-example/node_modules/vega-loader/build/vega-loader.js"]}
ExceptionInfo: override to file that doesn't exist
	shadow.build.npm/find-resource (npm.clj:735)
	shadow.build.npm/find-resource (npm.clj:661)
	shadow.build.resolve/find-npm-resource (resolve.clj:123)
	shadow.build.resolve/find-npm-resource (resolve.clj:94)

JAtkins19:09:18

wow, this is the first time I've seen that message in my builds and you already asked about it 🙂. Quite a coincidence

JAtkins19:09:38

I would almost say that there is some new version of vega, and since package.json usually imports "^version", we both got upgraded at the same time

simongray13:09:18

So now I’m wondering what to do? The packages are installed, but shadow-cljs is looking for e.g. vega-loader.js when only files like vega-loader.min.js is available in that folder.

thheller15:09:35

@simongray not a clue. the package is linking to a file that it does not itself contain. likely just a bad config entry on their part. you can fix it by editing https://github.com/vega/vega/blob/master/packages/vega-loader/package.json#L41 to link to the correct file

simongray15:09:44

Thanks Thomas. I'll attempt that. It just seems odd that a setup that presumably worked at one time using those same versions now doesn't to seem any longer.

thheller15:09:25

I'm guessing that the bundling was just changed in recent versions

thheller15:09:18

current seems to be 4.3.3 but 4.3.2 still had the non-min file https://unpkg.com/browse/[email protected]/build/vega-loader.js

thheller15:09:26

so blame them ...

😬 3
simongray16:09:45

Thanks a lot. That got me on the right track. I managed to get it to compile by adding these two explicit dependencies to the package.json

"vega-loader": "4.3.2",
"vega-canvas": "1.2.4"
apparently, version 1.2.5 of the vega-canvas package suffered from the same issue.

🙂 3
simongray16:09:57

@U01BL8MKU7K Jeg fandt ud af hvad problemet var med lidt hjælp fra Thomas.