Fork me on GitHub
#shadow-cljs
<
2022-09-05
>
surferHalo02:09:34

> Typically all JS Dependencies are foreign and won’t be passed through :advanced and thus require Externs. > from https://shadow-cljs.github.io/docs/UsersGuide.html#externs Does that mean Closure Compiler not doing dead code elimination on the dependency library?

thheller06:09:56

yes, if by dependency library you mean npm JS dependency.

🙃 1
bbss08:09:50

I've been updating dependencies in a project and running into Module not provided: @babel/runtime/helpers/interopRequireDefault often. Tricky that it doesn't list which npm package / file is to blame. I think it has to do with using either @babel/runtime @babel/preset-react @babel/preset-env to pre-compile. Is it perhaps because I didn't configure .babelrc properly? I do have a babel.config.json that I think shadow-cljs uses.

thheller08:09:47

@bbss kinda hard to say. why do you configure babel at all?

bbss08:09:38

I've needed it several times when shadow couldn't compile when requiring an npm dep.

bbss08:09:43

EOF when reading it IIRC

bbss08:09:19

[2022-09-05 17:14:53.607 - WARNING] :shadow.build.babel/babel-transform-ex - {:code "/* eslint-env browser */\nexport const performance = typeof window === 'undefined' ? null : (typeof window.performance !== 'undefined' && window.performance) || null\n\nconst isoCrypto = typeof crypto === 'undefined' ? null : crypto\n\n/**\n * @type {function(number):ArrayBuffer}\n */\nexport const cryptoRandomBuffer = isoCrypto !== null\n  ? len => {\n    // browser\n    const buf = new ArrayBuffer(len)\n    const arr = new Uint8Array(buf)\n    isoCrypto.getRandomValues(arr)\n    return buf\n  }\n  : len => {\n    // polyfill\n    const buf = new ArrayBuffer(len)\n    const arr = new Uint8Array(buf)\n    for (let i = 0; i < len; i++) {\n      arr[i] = Math.ceil((Math.random() * 0xFFFFFFFF) >>> 0)\n    }\n    return buf\n  }\n", :file "/Users/baruchberger/nexus-core/node_modules/isomorphic.js/browser.mjs", :preset-config {:targets {"chrome" "90"}}, :shadow.build.babel/reply-to #object[clojure.core.async.impl.channels.ManyToManyChannel 0x2d46eb58 "clojure.core.async.impl.channels.ManyToManyChannel@2d46eb58"]}
RuntimeException EOF while reading

bbss08:09:02

I've also hit it on @material-ui v4

bbss08:09:55

this isomorphic.js thing is a dependency of y-webrtc which is you'd use with yjs a pretty cool lookin' crdt lib.

thheller08:09:19

instead of messing with babel you should probably just be using webpack instead

bbss08:09:49

okay, cool didn't consider that. I'll check it out! Thanks 🙂

thheller08:09:55

dunno what this error is. just seems to be missing a } at the end?

thheller08:09:31

hmm no wait it doesn't

thheller08:09:22

you definitely shouldn't have a babel config or manually call babel on the output or input. that is not expected to work

thheller08:09:11

it also compiles fine on my machine

thheller08:09:18

so maybe the babel config is causing it in the first place?

bbss08:09:45

okay, that's a bit confusing to me in how far shadow-cljs will go there, there is some mention of manually passing things through babel, and that has worked out for me in the past. So just a .babelrc is supported, and I should get rid of the babel.config.json in my root?

bbss08:09:00

Perhaps, let me check.

thheller08:09:34

I don't know. what do you use them for? shadow-cljs ONLY uses babel to transform npm ESM code to commonjs. nothing else, not for polyfilling or whatever else

thheller08:09:44

so if you make it do more you will essentially brick it

thheller08:09:28

I wouldn't use babel for this at all but unfortunately the closure compiler is rather picky about its input, so I kinda have to

bbss08:09:30

I use them because I thought it was needed to get some npm deps to work, here and there I've run into these babel-transform-ex.

thheller08:09:49

no, you should not have any babel config whatsoever. unless you actually use babel manually anywhere I guess

thheller08:09:18

but not for the babel used by shadow-cljs

bbss08:09:54

Great, the babel.config.json seemed to be the problem, code now runs. Thank you very much!

Filipe Silva15:09:08

On the topic of the babel config and closure compiler, I’m running into an ES6 transpilation of 'Public class fields' is not yet implemented. from the closure compiler and was trying to get shadow’s babel config to use include @babel/plugin-proposal-class-properties, but it doesn’t seem to. Is this a bad idea?

thheller16:09:02

yes, that is bad. it is not a supported use case. basically if you need to use code that the closure compiler doesn't support you are better off using webpack

👍 1
Ivan Fedorov17:09:05

Hey! Anyone seen any videos or “for-dummies” material on externs?

thheller17:09:28

do you not get any inference warnings?

Ivan Fedorov18:09:54

I get them, yeah. 188 about core.cljs, one about garden color, two about reader_types

Ivan Fedorov18:09:26

Have you seen any shadow-cljs projects using d3 v7? Maybe I could dig that

Ivan Fedorov18:09:00

Or may I buy 30-60 minutes of your time for a zoom session, if you’re open to that. I promise to release a guide for shadow-cljs <-> d3 if that’ll be fruitful.

Ivan Fedorov18:09:49

Sourcemapping with simple optimizations is wrong too

Ivan Fedorov18:09:02

I also have warnings about param names (based on function doc comment) Like

Resource: flow_ui/views/graph-tree-v2.js:809:19
 Parse error. invalid param name "optContextPatch.changedNodeId"

thheller19:09:25

> I get them, yeah. 188 about core.cljs, one about garden color, two about reader_types

thheller19:09:32

what do you mean? those are probably not inference warnings?

thheller19:09:54

I'm talking about warnings you get when you compile your build

thheller19:09:08

so shadow-cljs release app or shadow-cljs watch app or shadow-cljs compile app

thheller19:09:33

if you meant setting :infer-externs :all then you should not be doing that

Ivan Fedorov19:09:37

yes, I got that long list on :infer-externs :all retrying on :auto

thheller19:09:05

the most direct way to debug externs issues is via shadow-cljs release app --pseudo-names

❤️ 1
thheller19:09:18

takes a bit of practice though

thheller19:09:33

pseudo-names names variables in a way that lets you recognize what they were originally

thheller19:09:50

but requires stepping through a bit of generated JS maybe

Ivan Fedorov19:09:08

retried. Got 29 regular warnings about param names

thheller19:09:53

and what would be the source for that JS parse error?

Ivan Fedorov19:09:31

yeah, pseudo-names may help indeed, thanks!

thheller19:09:54

I assume you are using the JS code directly?

thheller19:09:14

no externs inference is done for JS code, so only pseudo names will help there

Ivan Fedorov19:09:26

about these 29 warnings – yeah, my guess is that my doc param naming doesn’t match the Closure scheme

thheller19:09:50

yes, including JS that way only really works if you follow the closure compiler style

thheller19:09:03

otherwise it'll get confused and produce various issues

Ivan Fedorov19:09:08

on js usage – using it from a CLJS wrapper. Had some issues with d3 modules system, ended up with a crutch (pic). At the time I felt like d3 is written to be compiled by babel or something.

thheller20:09:37

not sure why you are doing this

thheller20:09:01

but if the graph-tree-v2.js file does any interop with d3 then that is likely the source of your externs issues

thheller20:09:24

again no inference is done for those, so externs need to be added manually there

Ivan Fedorov20:09:36

> follow the closure compiler style will try, thanks!

Ivan Fedorov20:09:45

shadow-cljs release app --pseudo-names produces good source mapping

Ivan Fedorov20:09:36

I guess I’ll prioritise fixing annotations to exclude their influence. Thanks for the tips!

thheller20:09:47

they don't really fix and externs issues but yes, getting rid of warnings should always be the goal

Ivan Fedorov15:09:51

Externs solved it! Is there a way to generate externs automatically? I need to scan a couple of JS files and dump field names from every constructor in those.

Ivan Fedorov15:09:51

Externs solved it! Is there a way to generate externs automatically? I need to scan a couple of JS files and dump field names from every constructor in those.