Fork me on GitHub
#shadow-cljs
<
2022-11-11
>
Ferdinand Beyer14:11:27

I see a really strange behaviour in my shadow-clhs build. I’m using the :npm-module target and the default :advanced optimizations in a Release build. The module output for clojure.string.js changes depending on whether I use remove-watch in my code or not. Without, everything works fine, and the file’s second line starts like this:

'use strict';var Sl,Ul;$CLJS.Fh=function(a,b){return $};Sl=function(a,b){var c=Array(a.length-2);$CLJS.fc...
When I refer to remove-watch, then this line looks like this, skipping the creation of the Fh function:
'use strict';var Sl,Ul;Sl=function(a,b){var c=Array(a.length-2);$CLJS.fc(a,0,c,0,2*b);$CLJS.fc....
But $CLJS.Fh is later used in the same file, e.g.:
$CLJS.ae.prototype.nd=$CLJS.Fh(27,function(a,b,c)...
And I get a JavaScript error that $CLJS.Fh is not defined. Took my a lot of time and frustration to narrow it down to remove-watch… What’s special about that var? Any ideas?

Ferdinand Beyer14:11:12

I noticed that the Fh definition is moved to taoensso.encore.js when I use remove-watch, but this file is not required by clojure.string of course

Lone Ranger15:11:40

Why not pretty print it ?

Lone Ranger15:11:27

Can’t remember the exact settings but configure it to not shorten the names, use the originals to get better insight

thheller17:11:38

@U922FGW59 compile with npx shadow-cljs release <your-build> --pseudo-names

thheller17:11:00

to see what this actually is

thheller17:11:19

stuff moving around files is expected, thats what the closure compiler does

Ferdinand Beyer17:11:08

OK, will try that, thanks. Was confused that things are moved to modules with the wrong dependency relationship, as encore depends on clojure.string and not vice versa

thheller18:11:05

always verify. there is no guarantee that Fh of one build is Fh in another build

thheller18:11:32

if a function is only used once somewhere the closure compiler will either inline it entirely or move it to the module it was used in

thheller18:11:05

you might be chasing down the wrong problems. advanced can be very misleading that way 😛

Ferdinand Beyer19:11:07

It might, but the Fh definition is exactly the same. And anyway, I do get the problem that clojure.string uses this but does not have it

Ferdinand Beyer19:11:12

The function Fh is this:

$CLJS.$JSCompiler_unstubMethod$$ = function($JSCompiler_unstubMethod_id$$, $JSCompiler_unstubMethod_body$$) {
  return $CLJS.$JSCompiler_stubMap$$[$JSCompiler_unstubMethod_id$$] = $JSCompiler_unstubMethod_body$$;
};

thheller19:11:33

ah. yeah thats a nasty one

Ferdinand Beyer19:11:44

What is it? 🙂

thheller19:11:24

set :compiler-options {:cross-chunk-method-motion false} in your build config

thheller19:11:08

haven't seen that problem in a long time though. not sure how clojure.string would be involved either

thheller19:11:33

could totally be something else but the stub thing looks familiar

Ferdinand Beyer19:11:54

Ah, I had that in a different project once, I remember…

Ferdinand Beyer19:11:04

Do you know what unstubMethod does?

thheller19:11:22

moves methods cross chunks 😛

Ferdinand Beyer19:11:25

In my case probably totally useless, as I later use webpack to glue it all together

thheller19:11:47

well, it means that if you have a type/class, with methods on it

thheller19:11:59

class Thing { foo() { ... } } or so

Ferdinand Beyer19:11:15

Yeah, I do use shadow.modern/defclass

thheller19:11:20

and foo is only used on one module but Thing in multiple. it may move the definition of foo elsewhere

thheller19:11:27

not specific to defclass

thheller19:11:39

any deftype defrecord and or JS type really, even reify.

thheller19:11:40

if you run webpack anyways you should probably consider using :target :esm with :js-provider :import

thheller19:11:50

it addresses some of the weirdness in :npm-module

Ferdinand Beyer19:11:38

Not sure if I can. You might not remember, but you were helping me back in the day with my setup to build VS-Code Web Extensions

thheller19:11:00

ah right. it didn't like modules right?

Ferdinand Beyer19:11:04

Where I need a special web-worker build that uses require and module exports

Ferdinand Beyer19:11:17

Yep, needs all in one file

Ferdinand Beyer19:11:47

Unfortunately I cannot keep the differences between ESM/whatever other JS module version in my head 🙂

Lone Ranger19:11:50

Ok dam if there was an award for rapid esoteric knowledge and response this would be it

Lone Ranger19:11:08

I’d probably have to tell my boss this is a research project and I’ll see you in a few months

😅 1
Ferdinand Beyer19:11:31

Yes, thanks Thomas, your help is highly appreciated!

Ferdinand Beyer19:11:20

Fun fact: I actually worked around not needing remove-watch in the end and came up with a better design anyway

Ferdinand Beyer19:11:17

:cross-chunk-method-motion false seems to indeed solve this! 🎉

👍 1
zane23:11:19

It seems like passing the NPM package mermaid through shadow-cljs might corrupt it somehow. The DOM elements added by mermaid after it has been passed through shadow-cljs come out malformed compared to the elements that come out when you add mermaid to the page directly via a script tag. Here’s https://github.com/zane/shadow-cljs-mermaid-repro.