Fork me on GitHub
#shadow-cljs
<
2020-03-26
>
hkrish03:03:33

@thheller, that solved the problem Thank you so much. On my deps.edn, I added the following:

org.clojure/clojurescript                       {:mvn/version "1.10.597"
                                                 :exclusions
                                                              [com.google.javascript/closure-compiler-unshaded
                                                               org.clojure/google-closure-library
                                                               org.clojure/google-closure-library-third-party]}
com.google.javascript/closure-compiler-unshaded {:mvn/version "v20191027"}
org.clojure/google-closure-library              {:mvn/version "0.0-20191016-6ae1f72f"
                                                 :scope       "provided"}
org.clojure/google-closure-library-third-party {:mvn/version "0.0-20191016-6ae1f72f"}

teawaterwire09:03:02

is it possible that the build generated by shadow-cljs release can include different versions of npm libs than the one generated by shadow-cljs watch ? (it sounds impossible just writing it 😅 but want to be sure as i'm having a weird bug between in my release build, and it's not a typical extern missing bug, more like a js library outdated and thus returning an error)

thheller09:03:00

like what? it will definitely use the same node_modules/lib files

teawaterwire09:03:38

yeah that makes sense :thumbsup:

teawaterwire09:03:34

like i get this error (when sending a eth transaction) with the release bundle and nothing with the dev bundle

teawaterwire09:03:10

and it seems it's because the "value" i'm passing is a BigNumber and the library (encoding parameter for the eth transaction) should accept it, which it does in dev but not in release mode

teawaterwire10:03:54

but could be then the dynamic require issue

teawaterwire13:03:34

i finally understand what is going on: the js library has a function to check if an object is a BigNumber, it does so by getting object.constructor.name which returns "BigNumber" in dev but a u in prod, because i'm requiring the bignumber.js lib in one of my cljs file it gets optimized. can i fix that with this method? https://shadow-cljs.github.io/docs/UsersGuide.html#_simplified_externs

thheller15:03:16

it'll prevent the rename yes

thheller15:03:17

you can also turn off the renaming completely via :js-options {:property-renaming :off}

teawaterwire15:03:01

ah nice didn't know about that ! if i use the externs/app.txt i go with just the line "BigNumber" or i need smth different because it's a constructor?

teawaterwire15:03:51

it doesn't seem to be working when i write :

# externs/app.txt
BigNumber

thheller16:03:06

hmm those externs might not apply to node_modules code

thheller16:03:28

why is the lib checking the name? that seems dumb 😛

teawaterwire16:03:10

can i type hint smth here?

(ns my-ns
  (:require ["bignumber.js" :as BigNumber]))

(defn to-big-number [num]
  (BigNumber num))

thheller16:03:21

I'm not actually sure the extrerns are applied at all to node_modules dependencies. usually they don't need any since they only run through :simple

thheller16:03:28

open an issue, I can take a look later

thheller17:03:38

actually try :js-options {:variable-renaming false}

thheller17:03:45

it isn't a property after all

teawaterwire08:03:01

it works! thanks :thumbsup: hopefully it doesn't increase the size of the bundle too much 🙂

teawaterwire08:03:27

fyi (in terms of bundle size) before:

thheller08:03:43

yeah it does make things quite a bit larger

thheller08:03:07

maybe you should try to find out why the eth lib doens't just use instanceof? seems rather weird to me to be checking a name

teawaterwire08:03:58

yeah good point i think it's because they're not including the actual BigNumber package but looking a bit further they're only calling isBigNumber once so i can find a work-around in my code :thumbsup:

teawaterwire08:03:51

maybe too complex - i'll just go with the workaround 🙂

teawaterwire08:03:46

i found that overriding the isBigNumber method seems to be working as well 🤓

thheller09:03:12

but sometimes those files do conditional stuff for development

thheller09:03:05

like the dynamic require stuff

martinklepsch12:03:55

@thheller Not sure if you remember but I’ve had some issues with source maps for node-library and node-script . After I earlier thought that everything is actually working I now created a repro case that exhibits the same problems I’m seeing in a larger code base: https://github.com/martinklepsch/shadow-cljs-broken-node-source-maps

martinklepsch12:03:00

Let me know if this is helpful, if there’s any more things that should be tested before considering this a bug

thheller12:03:16

why is that using :simple?

martinklepsch12:03:03

No particular reason but verified similar behavior when not setting a custom :optimizations value

martinklepsch12:03:48

Will also give :whitespace a try

thheller12:03:14

whitespace isn't supported

martinklepsch12:03:35

yup, just saw that 😅

thheller12:03:45

just wondering why its simple. not something I ever tested with source maps

martinklepsch12:03:35

I think it might be an artifact from before using shadow

thheller12:03:26

it seems to be working ok-ish for me with :advanced. it just moving code all over the place so the actual source-maps.core ns/file doesn't exist anymore since its just inline elsewhere

thheller12:03:52

kinda difficult to analyze dummy code like this since its inlined so aggressively

martinklepsch12:03:45

let me try with advanced in a more complex codebase

martinklepsch13:03:26

Seeing similarly off results with :advanced

thheller13:03:47

$ node -r source-map-support/register out/main.js 0
Error: boom
    at new $cljs$core$ExceptionInfo$$ (/mnt/c/Users/thheller/code/tmp/shadow-cljs-broken-node-source-maps/out/cljs/core.cljs:11304:31)
    at Function.<anonymous> (/mnt/c/Users/thheller/code/tmp/shadow-cljs-broken-node-source-maps/out/source_maps/core.cljs:4:9)
    at $cljs$core$apply_to_simple$cljs$0core$0IFn$0_invoke$0arity$03$$ (/mnt/c/Users/thheller/code/tmp/shadow-cljs-broken-node-source-maps/out/cljs/core.cljs:3890:15)
    at $cljs$core$apply$cljs$0core$0IFn$0_invoke$0arity$02$$ (/mnt/c/Users/thheller/code/tmp/shadow-cljs-broken-node-source-maps/out/cljs/core.cljs:3924:30)
    at /mnt/c/Users/thheller/code/tmp/shadow-cljs-broken-node-source-maps/out/cljs/core.cljs:10028:46
    at Object.<anonymous> (/mnt/c/Users/thheller/code/tmp/shadow-cljs-broken-node-source-maps/out/main.js:5698:3)
    at Module._compile (internal/modules/cjs/loader.js:688:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
    at Module.load (internal/modules/cjs/loader.js:598:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:537:12)

thheller13:03:59

(ns source-maps.core)

(defn main [x]
  (when (zero? (js/parseInt x 10))
    (throw (ex-info "boom" {:x x}))))

thheller13:03:09

{:deps true
 :builds
 {:main
  {:target :node-script
   :main source-maps.core/main
   :output-to "out/main.js"
   :compiler-options {:source-map true}}}}

martinklepsch13:03:58

Like sourcemap.clj returns lines in cljs-node-io.core as part of the stacktrace but the error is thrown elsewhere

thheller13:03:00

that looks accurate when using --debug

thheller13:03:18

without it doesn't .. so dunno whats happening there

martinklepsch13:03:34

you mean release --debug?

martinklepsch13:03:00

what is source-map-support/register?

thheller13:03:15

loading the node source map support

thheller13:03:40

otherwise it won't load any source maps at all

martinklepsch13:03:47

Ah interesting, so that allows us to see source maps right in the stacktrace vs using sourcemap.clj? that’s convenient 😅

thheller13:03:26

yeah for development builds thats just loaded automatically. for release you have to load it

martinklepsch13:03:24

Ok, I can reproduce --debug fixing the issue

martinklepsch13:03:45

interesting, it seems like after installing source-map-support I get more reasonable mappings already

martinklepsch13:03:05

also when looking them up with sourcemap.clj

thheller13:03:13

--debug is basically :pseudo-names true + source maps

thheller13:03:34

so I suspect source maps work better because of pseudo-names giving everything names that would otherwise be stripped

martinklepsch15:03:34

after a few more hours of fiddling with this I find that the only way I can remotely make it work is optimizations simple + pseudo-names and pretty-print but also there’s so many variables that I’m losing trust that I can actually hold the different combinations in my head 😄

thheller17:03:10

hmm yeah I dunno why its so weird, I don't do much node stuff so I can't really tell where the problem is

thheller17:03:26

--debug seems to do the trick and that is all I use

martinklepsch14:03:34

I’ve tried setting pseudo-names and pretty-print individually but I’ll give --debug another try as well

thheller14:03:56

--debug is basically :source-map true :pseudo-names true :pretty-print true

thheller14:03:30

--pseudo-names is pseudo and pretty because sometimes its easier to debug without source maps

coby18:03:30

I'm troubleshooting an issue in IE11 - my compiled app throws the error "WeakSet is undefined." I did npm install --save weakset and included ["weakset"] in my top-level require, but I'm still getting the error. Do I need to explicitly set js/window.WeakSet? Declare an extern? The user guide says that everything should be polyfilled down to IE10+, but I think I must be taking that out of context or something. Thanks!

(ns multicare-dfd.core
  (:require
   ["weakset"]
   [reagent.core :as reagent] ,,, ))

thheller19:03:42

@ctamayo who/what uses weakset? for polyfills like that it is probably better to use a third party polyfill since modern browsers won't need it

coby19:03:13

@thheller I'm not actually sure what is using it. I'm a bit confused because npm ls weakset just shows that my top-level module is the thing including it. What do you mean by polyfills like that?

thheller19:03:24

weakset is a standard JS feature in newer versions but it doesn't exist in IE11

thheller19:03:04

so if its not your code using weakset then it is likely some library which assumes you are using a modern browser or polyfills

coby19:03:46

yeah that is my thought as well

coby19:03:02

so then I am misunderstanding this somehow: > By default the generated JS output will be compatible with ES5 and all "newer" features will be transpiled to compatible code using polyfills. This is currently the safest default and supports most browsers in active use (including IE10+). What does that mean, if not that shadow-cljs injects polyfills needed for IE10+? Based on what you're saying I'd expect WeakSet to fall under that umbrella

thheller19:03:33

that only counts for CLJS output

thheller19:03:52

npm is different

coby19:03:08

ah, so you think something is using an NPM dependency that in turn uses WeakSet?

coby19:03:09

I see. That makes sense.

teawaterwire13:03:34

i finally understand what is going on: the js library has a function to check if an object is a BigNumber, it does so by getting object.constructor.name which returns "BigNumber" in dev but a u in prod, because i'm requiring the bignumber.js lib in one of my cljs file it gets optimized. can i fix that with this method? https://shadow-cljs.github.io/docs/UsersGuide.html#_simplified_externs