Fork me on GitHub
#shadow-cljs
<
2019-08-06
>
kasuko18:08:24

Hello, while migrating our application to shadow-cljs I am running into issues trying to get the code to run with a release. The code runs fine in dev mode. However, when I run it as a release I get an Invarient Violation from React. It seems like React is eating up the error so I can't figure out what is going wrong. Is there a way I could do the advanced compilation but some how set the NODE_ENV to development so React will give me the error?

Stefan19:08:48

I’m a shadow-cljs beginner really, so I don’t have the answer, but do you know about shadow-cljs check? Maybe it helps, I would have liked to know about it earlier a few months ago 🙂

kasuko19:08:49

I have run shadow-cljs check and it gives me some warnings. Most warnings are in external library code, but none that seem like they would break only in a release

thheller19:08:04

hmm no that is not currently overrideable

thheller19:08:52

do you have :infer-externs :auto turned on? it is most likely related to missing externs and using property access for something https://shadow-cljs.github.io/docs/UsersGuide.html#infer-externs

kasuko14:08:43

Whew! That was a crazy issue. Ultimately it had little to do with shadow-cljs. We had an in-house JavaScript library called paradigm and when we did the original interop with lein we just had it provide the same namespace that the global object provided paradigm. However when I followed the technique described to convert CLJSJS packages things went wrong in a weird way when released. Somehow the code was optimizing in a way that js/paradigm was resolving to the cljs paradigm namespace rather than the paradigm that we exported globally. I have no clue why this was happening only on a release build but worked fine in dev. Changing the namespace to avoid clashing with the global object fixed it.

neupsh19:08:02

I cannot seem to make "release" build of my firebase app work. My development build runs fine. If I serve the js files compiled using shadow cljs normal build using firebase serve, the app works, but if i do shadow-cljs release main (main is the app build), and do firebase serve I get errors for firebase. It does not initialize firebase and app does not show up. Is there a way to test advanced build using shadow-cljs?

neupsh19:08:23

I tried

:dev {:compiler-options
                      {
                       :optimizations :advanced
                       :closure-defines {re_frame.trace.trace_enabled? true
                                         day8.re-frame.tracing.trace-enabled? true

                                         ;goog.DEBUG false
                                         }}}

neupsh19:08:50

but for the main build but i cannot seem to force shadow-cljs to do :advanced optimizations on the build

thheller19:08:21

@neupsh there is shadow-cljs release main --debug

thheller19:08:38

but re-frame trace stuff won't work in release builds

neupsh19:08:25

@thheller I have only used tracing on :dev,

neupsh19:08:59

@thheller is there a way to force :optimizations :advanced on the normal (non-release) builds? using that key value on compiler-options did not seem to create advance optimized builds

neupsh19:08:18

What I am facing is : Uncaught TypeError: firebase.initializeApp is not a function on the "release" version

thheller19:08:52

pretty much the only difference between dev and release is advanced

thheller19:08:17

what is firebase in your app?

neupsh19:08:11

but since I am using https://github.com/deg/re-frame-firebase, i think it is getting initialized twice (wrongly in release build)

neupsh19:08:54

when i debug, I can see it is just an object instead of the actual firebase object in the js code, but since this only happens in advanced optimization, i am not sure why it is happening

thheller19:08:14

it is more important to know how YOU use it. in your code I mean

thheller19:08:18

not the node_modules code

thheller19:08:19

that re-frame lib for example is depending on a global variable

neupsh19:08:34

i use the re-frame-firebase library. I don't call firebase directly.

neupsh19:08:55

may be it is in conflict with the firebase I have in the package.json file. Let me try to remove the one in package.json and try again

thheller20:08:06

no you need it in package.json

thheller20:08:40

as far as I can tell this should be working or not at all (so also not in dev)

thheller20:08:09

you are basically relying on this "shim" to create the global js/firebase that library uses

thheller20:08:28

I'm gonna take a wild guess and say that it is expecting an older version

👍 4
thheller20:08:34

and you probably just have a newer version isntalled

thheller20:08:48

[cljsjs/firebase "5.7.3-1"]

thheller20:08:10

check which version you have under cat node_modules/@firebase/app/package.json

neupsh20:08:26

i do have newer version 🙂

thheller20:08:02

you might be able to copy this file to your src directory

neupsh20:08:13

thank you for the pointers. I will check more. I am surprised that it works with shadow normal build

thheller20:08:27

and change it to

(ns 
  (:require ["@firebase/app" :default firebase])

thheller20:08:55

yes that surprises me too

thheller20:08:44

which version do you have? I want to test something

neupsh20:08:03

"name": "@firebase/app",
  "version": "0.4.11",
...

neupsh20:08:09

that is from your command

neupsh20:08:27

this is from my pagckage.json: "firebase": "^6.3.1",

neupsh20:08:49

i think 6.3.1 is the general version and 0.4.11 is the "app" module version

thheller20:08:07

hmm yeah makes sense

neupsh20:08:20

I am very new to front end development so still confused with alot of things 🙂

thheller20:08:36

welcome to the madness that is JS 😉

thheller20:08:35

oh before I forgot which build target do you use?

thheller20:08:28

it is working fine for me in a :browser build

neupsh20:08:41

it is browser

neupsh20:08:28

I am 99% sure it is because of that reframe library

thheller20:08:34

with multiple :modules maybe?

neupsh20:08:05

i only have one :modules {:main {:entries []}}

thheller20:08:59

yeah I'm unsure why it would be working in dev but not release

thheller20:08:30

you can try making a release build and then when loading it in the browser you can check via the console if there is a firebase variable

thheller20:08:39

there should be

neupsh20:08:47

i can actually see it in the global variable

thheller20:08:26

maybe try compiling with shadow-cljs release main --pseudo-names and debug it in the browser

👍 8
thheller20:08:37

should be some clue in there

neupsh21:08:49

I will try that.

benwen00:08:58

@neupsh I've been trying to elucidate that exact behavior myself for the last three weeks. I also use re-frame-firebase

benwen00:08:35

Similarly, I’ve traced it down to a double declaration of “var firebase” that in the re-frame-firebase initialization scope overloads the goog.exportSymbol’s firebase. I’ll try the above recommendations too and report back if that helps debug. Thank you.

👍 4
neupsh01:08:18

In the "advanced optimized" js if i search for "firebase" I see two places where that var is assigned a value. One for global and one for local (in scope of that reframe lib node module init function).

neupsh01:08:01

The global one has correct value right after it is assigned, but the local scoped one is initialized as an empty object and then for each modules (sub modules?) they are added as properties of the "firebase" local object. Now, this object may have those submodules, but it does not have the "initializeApp()" method as it is never added to that object.

benwen01:08:51

yes, in the debugger, at the point firebase.initializeApp is called, firebase is a nearly empty object, with properties (this is from my recent memory, so may be missing things)

benwen01:08:13

{auth: {}, database: {}, firestore: {}} which is also initialized in that containing scope by a similar assignment to the var firebase = {app: {}} (I’m using :simple optimizations, so the app: {} nor other empties are being optimized out, forgot to mention that)

benwen01:08:42

immediately prior to use of say firestore, there’s a dummy dec’l firebase.firestore = {}

benwen01:08:48

BTW, did you get --pseudo-names to do anything useful, I’m on the horns of that now, with a … TypeError : $s$$.substring is not a function

benwen01:08:09

seems to be on the second call leading up to that form

benwen01:08:48

Separately, I have a minimal app that exhibits this “firebase.initializeApp not a function” behavior that I can share

👍 4
neupsh02:08:10

@U20AW42V7 I have not got around to try that yet 🙂 I only get to play with clojure(script) off work.

neupsh03:08:20

Tried to spend some time without any progress.. I will continue tomorrow. Lets get to the bottom of this 🙂

thheller06:08:17

@U20AW42V7 please share the repo if you can. happy to dig into that

👍 4
benwen07:08:00

@thheller I’m in the middle of cleaning it up right now, thank you. Last minute npm wrestling.

thheller07:08:26

thanks. I'll take a look

benwen07:08:29

Apologies for letting /semantic sneak in there! Thank you for shadow-cljs. Am going to turn in for the evening.

benwen07:08:10

one last thing, I have a fork of shadow-cljsjs and/or re-frame-firebase that seems to supress the :dev build warning:

benwen07:08:20

‘‘’ Warning: Firebase is already defined in the global scope. Please make sure Firebase library is only loaded once. shadow$provide.module$node_modules$$firebase$app$dist$index_cjs @ index.cjs.js:484 shadow.js.jsRequire @ js.js:63 shadow.js.require @ js.js:97 (anonymous) @ firebase.app.js:3 ‘’'

thheller07:08:36

I found the problem I think

benwen07:08:53

oh, that’s encouraging

thheller09:08:03

yeah problem is fixed in master. will make a release a bit later

parrot 8
neupsh13:08:42

OMG @thheller I could not thank you enough 🙂

benwen14:08:35

@thheller Thank you, that is awesome! 🙏

thheller17:08:21

fixed in 2.8.45

👍 8
neupsh18:08:47

I can confirm it works now. Thank you very much @thheller

neupsh18:08:36

I have another issue with "styling" and layout on the advanced build (material-ui) but that may not be related to this issue. I will create another thread if needed one.

benwen19:08:03

Thank you @neupsh for bringing up the issue. I thought I was going crazy. Was starting to dig through shadow-cljs codebase.

👍 4