shadow-cljs

niwinz 2025-11-20T17:06:37.901089Z

Hey, is :js-provider :external compatible with :esm target? If yes, how it works? i mean how i need to load that file in the browser, i know that loading ESM module is looks like this:

But when i use it, it raises shadow$bridge on is not available on page load because it is defined in the libs.js which i don't know how to load properly Thanks in any case

niwinz 2025-11-26T08:54:36.932099Z

Hey, i reopen this ๐Ÿงต Seems like the :esm target does not flushes the external index. It worked for me on first instance because of stale index.js file found from the previous builds with :browser target

niwinz 2025-11-26T08:55:23.649399Z

Looks like all the other part is working as expected, i mean, that the rest of build process properly refers to shadow$bridge.

niwinz 2025-11-26T08:56:11.533709Z

On the browser target, i see this code, i'mttrying make the same operation on esm target code.

niwinz 2025-11-26T08:56:32.873589Z

any hint where it should go would be nice

niwinz 2025-11-26T08:59:57.630619Z

Ok, it looks like it should be go in shadow.build.targets.esm/process function (on the end, where flush is performed)

thheller 2025-11-26T09:11:58.106339Z

correct yeah

thheller 2025-11-26T09:12:26.781099Z

currently in the process of upgrading cljs. I will add that as well

niwinz 2025-11-26T09:12:29.188669Z

i have a commit for it, for test it , any hint on how to build shadow-cljs?

thheller 2025-11-26T09:13:01.549849Z

no need to build it really. just go into the repl and redefine the function ๐Ÿ˜‰

niwinz 2025-11-26T09:19:58.637919Z

https://github.com/thheller/shadow-cljs/pull/1242

niwinz 2025-11-26T09:23:45.327859Z

I asked for the build, because i temporally want to use a patched version of shadow-cljs on our project, because our migration to :esm is right now blocked by this hehe

thheller 2025-11-26T09:39:43.510259Z

I just do lein install or lein deploy clojars to build

thheller 2025-11-26T09:40:00.673429Z

but I just made the 3.2.2 release with your PR merged

thheller 2025-11-26T09:40:35.745419Z

cljs upgrade needs some more digging because of lite-mode stuff, will do that later

๐Ÿ‘๐Ÿฝ 1
niwinz 2025-11-26T09:40:48.373909Z

oh nice, thanks

thheller 2025-11-26T09:58:25.294839Z

found the issue with the cljs upgrade, so 3.3.0 also has that upgrade if you are upgrading anyway. likely nothing that'll affect your build but still.

niwinz 2025-11-26T09:59:49.373269Z

i will try the 3.3.0

niwinz 2025-11-26T10:25:08.440819Z

With 3.3.0 (with cljs upgrade) i start getting this error

niwinz 2025-11-26T10:26:07.888389Z

is not the same but i found similar issues like this previously with other cljs compiler versions, when several parts of a refiy is moved to different module

niwinz 2025-11-26T10:26:51.082599Z

causing exception when it can not find the prototype

niwinz 2025-11-26T10:27:30.360289Z

(i'm not clearly understand how compiler decides that several part of reify impl (which is always under conditional) to move to other module...)

thheller 2025-11-26T10:27:44.230919Z

I fixed that be redefining how reify works normally? or are you testing with regular cljs?

niwinz 2025-11-26T10:27:50.929599Z

in this case, is a bit different, it looks it tries to use the prototype before the class is created

thheller 2025-11-26T10:28:26.388179Z

reify isn't supposed to be conditional in shadow-cljs

thheller 2025-11-26T10:28:50.563529Z

let me check if that fix is still in place

niwinz 2025-11-26T10:29:02.977889Z

i mean the condition is on js output our reify is in a function without any conditional

niwinz 2025-11-26T10:30:12.061119Z

the reify issue is happening with functions like this

thheller 2025-11-26T10:30:49.271949Z

yes, that is fine. I meant that reify created the type conditionally, thus breaking if the cross method motion stuff tried to add things before it was actually defined

niwinz 2025-11-26T10:31:14.515039Z

yep, thats it

thheller 2025-11-26T10:31:27.336239Z

but in shadow-cljs reify always defines the type at the top level, so it is always available and thus fixing the cross motion stuff. at least I haven't seen it since?

niwinz 2025-11-26T10:31:50.929719Z

that issue happened to us with shadow-cljs 3.2.0

niwinz 2025-11-26T10:32:09.299209Z

method moved to other module...

thheller 2025-11-26T10:32:09.725409Z

this has been fixed for a long time though? (and not changed in 3.3.0)

niwinz 2025-11-26T10:32:59.845019Z

i mean, I think i have generated a bit of confusion, here we have two different but maybe similar issues (maybe i'm wrong about similarity)

niwinz 2025-11-26T10:33:25.057219Z

with 3.3.0 i have this error

niwinz 2025-11-26T10:33:43.059959Z

(the same as first image on the thread today)

thheller 2025-11-26T10:33:56.665319Z

and there is also :compiler-options {:cross-chunk-method-motion false}. maybe try if that fixes it? otherwise might be something else?

niwinz 2025-11-26T10:34:32.881109Z

ok, i'll try

thheller 2025-11-26T10:35:02.973549Z

I'm uncertain why there is a .$Vector property. that should be flattened entirely

thheller 2025-11-26T10:36:19.802599Z

https://github.com/clojure/core.rrb-vector its this one I assume? which version of it do you use?

niwinz 2025-11-26T10:36:43.551739Z

let me look, it is not a direct dependency

niwinz 2025-11-26T10:38:20.462459Z

0.1.2

thheller 2025-11-26T10:39:15.198599Z

and can you check where (if ever) the $APP.$clojure$core$rrb_vector$rrbt$$.$Vector$ is defined?

niwinz 2025-11-26T10:39:34.652899Z

is that i'm looking right now

niwinz 2025-11-26T10:42:32.689659Z

I only found these lines above in the same file

niwinz 2025-11-26T10:42:46.986789Z

and do not found anywhere the definition of that

niwinz 2025-11-26T10:43:08.501809Z

i will look on other modules, but on the shared.js it is not defined

niwinz 2025-11-26T10:43:43.350519Z

the :cross-chunk-method-motion false do not fixes it

thheller 2025-11-26T10:45:36.616139Z

and if you just look for .$Vector$? somewhere it should be assigned. cross-chunk-method-motion should remove any calls to $JSCompiler_stubMethod.... maybe try wiping cache?

niwinz 2025-11-26T10:46:34.940149Z

I have looked on .$Vector but didn't find anything, let me check it again after a buld with method motion disabled

niwinz 2025-11-26T10:46:59.230059Z

and as far as I known, i remove cache on every "prod" build, but also, let me check that also

niwinz 2025-11-26T10:50:12.465129Z

with cleaned cache, it still throws in the same way, but now i see the following warnigs:

niwinz 2025-11-26T10:50:32.208959Z

And this one related to rrb vector

niwinz 2025-11-26T10:51:10.927929Z

maybe is a regression on cljs compiler?

thheller 2025-11-26T10:52:59.216949Z

why is it compiling cljs.analyzer.api? do you use that somewhere?

thheller 2025-11-26T10:53:51.381509Z

that is self-hosted territory? I mean likely unrelated to the other vector issue, but still probably worth checking out? it'll make your build huge

thheller 2025-11-26T10:54:08.070889Z

(best try a build report and check whats requiring it)

niwinz 2025-11-26T10:55:51.271039Z

ok, i'll look in it, i use it on a single namespace for macros, is used on a legacy macro that we already removing from our code base, i'll try to restrict this only to :clj

thheller 2025-11-26T10:56:47.915959Z

otherwise that require alone probably adds a megabyte of JS to your build ๐Ÿ˜› including cljs.analyzer basically includes the entire compiler

niwinz 2025-11-26T10:57:37.119369Z

LOL, i will check it

niwinz 2025-11-26T10:58:17.684779Z

Ok, removing it from :cljs part, no longer shows that warnings, but the rrb vector warnings are stil there

thheller 2025-11-26T11:00:11.752189Z

well, yeah the warnings are just missing :refer-clojure in its ns form. that alone shouldn't cause any issues as they are just warnings, but I'm checking the code

thheller 2025-11-26T11:01:23.556539Z

there is definitely a bug somewhere. checking.

thheller 2025-11-26T11:34:39.610809Z

found the problem and it is fixed in CLJS master, but has no release yet

niwinz 2025-11-26T11:34:55.598929Z

nice, thanks!

thheller 2025-11-26T13:22:55.042589Z

3.3.1 has a fix for the vector problem

niwinz 2025-11-26T13:23:36.742509Z

awesome, i will try it ASAP

niwinz 2025-11-21T08:19:26.266189Z

we use a very different set of libraries, each one with its own peculiarities, and adding dependency is always a interesting journey, small and very common dependencies are OK, but several other presents problems (such that using dynamic imports which need to be patched, per example). Our team are hybrid and not all the team members has knowledge to deal with this kind of things. So lealving JS stuff to JS tooling is just simplier...

niwinz 2025-11-21T08:20:16.967269Z

and makes including js dependency 0 problem, because we no longer need to deal with this kind of issues

thheller 2025-11-21T11:00:57.153139Z

just checking. I mean in theory it should be possible to generate "better" fitting :external files. it can already generate files using import, so it could just add an export as well. then the other files generated could just import this external file automatically without having the need for an extra script tag

thheller 2025-11-21T11:01:30.134679Z

assuming the JS tools can actually output esm (i.e. preserve the export) these days. havent worked with any for a long long time ๐Ÿ˜›

niwinz 2025-11-21T11:07:09.927109Z

hehe

niwinz 2025-11-21T11:07:36.509829Z

i usually do not assume anything when is related to js ecosystem...

thheller 2025-11-21T11:32:31.211429Z

which JS tools do you use?

niwinz 2025-11-21T11:33:00.525849Z

right now we use esbuild for bundle the external js dependencies

mitchelkuijpers 2025-11-21T11:43:36.540039Z

would you mean something like this? https://rspack.rs/blog/announcing-1-6#improved-esm-output

thheller 2025-11-21T12:33:16.463769Z

no, far simpler. basically now the :external file just creates a shadow$bridge global object. all it would add is a export { shadow$bridge } and assume that would stay alive

thheller 2025-11-21T12:33:42.907799Z

doesn't really matter what happens with the rest

mitchelkuijpers 2025-11-21T12:33:55.511389Z

If we could process the modules separately then it could just bundle those modules which have been processed by a bundler

thheller 2025-11-21T12:35:34.230479Z

thats what that does yes

thheller 2025-11-21T12:37:47.415309Z

import * as i0 from "react";
import * as i1 from "dyn-import";

const ALL = {};

globalThis.shadow$bridge = function(name) {
  const ret = ALL[name];
  if (ret == undefined) {
    throw new Error("Dependency: " + name + " not provided by external JS!");
  } else {
    return ret;
  }
};

ALL["react"] = i0;

ALL["dyn-import"] = i1;
for example this is dummy current version of the output. note the use of globalThis. it could just be export { shadow$bridge }. then the other output files could just import { shadow$bridge } from "the/other/output.js"; and the extra script tag disappears

thheller 2025-11-21T12:38:15.093949Z

but for that the JS tool would need to preserve the export { shadow$bridge } which most tools will likely eliminate

niwinz 2025-11-21T12:44:48.542529Z

i think esbuild will preserve it, but i'll test it

thheller 2025-11-21T12:47:33.781769Z

I think it has an esm output format option, but never actually tested it

niwinz 2025-11-21T12:48:41.084249Z

yes, we use it (on my branch on migrating to :esm shadow target)

thheller 2025-11-21T12:49:38.766679Z

to be fair, all this would achieve is eliminating the shadow$bridge global. not sure that actually a problem worth addressing ๐Ÿ˜›

niwinz 2025-11-20T17:51:01.237799Z

Ok i have the code working, the libs.js compiled as esm module and application also compiled as module, and all works except the webworker module, which is unable to access to the shadow$bridge which is defined in libs.js... and I don't know how to load that libs.js wiithin worker...

thheller 2025-11-20T18:25:51.052559Z

its :browser only, at least thats the only thing I tested

niwinz 2025-11-20T18:26:51.792819Z

i confirm that esm build is working as expected with the :js-provider :external

niwinz 2025-11-20T18:28:14.198319Z

I have splited the webworker in a separate build and do not use the :js-provider :external on that build. As build internal dependencies are small, and we have no problem that deps pass through shadow-cljs/closure compiler, seems like everything is working

niwinz 2025-11-21T07:05:36.880439Z

on the end, i have every thing working, and also just to leave a feedback here: Having the js-provider external and external-index supported on ESM target is a key because independently of targeting esm or browser, we still want to use external tool for handle js stuff and do not feed it to the google closure compiler

niwinz 2025-11-21T07:06:41.928539Z

and I can confirm it works as expected

thheller 2025-11-21T07:56:33.373739Z

any particular reason you are trying to avoid the closure compiler for js stuff?