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 caseHey, 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
Looks like all the other part is working as expected, i mean, that the rest of build process properly refers to shadow$bridge.
On the browser target, i see this code, i'mttrying make the same operation on esm target code.
any hint where it should go would be nice
Ok, it looks like it should be go in shadow.build.targets.esm/process function (on the end, where flush is performed)
correct yeah
currently in the process of upgrading cljs. I will add that as well
i have a commit for it, for test it , any hint on how to build shadow-cljs?
no need to build it really. just go into the repl and redefine the function ๐
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
I just do lein install or lein deploy clojars to build
but I just made the 3.2.2 release with your PR merged
cljs upgrade needs some more digging because of lite-mode stuff, will do that later
oh nice, thanks
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.
i will try the 3.3.0
With 3.3.0 (with cljs upgrade) i start getting this error
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
causing exception when it can not find the prototype
(i'm not clearly understand how compiler decides that several part of reify impl (which is always under conditional) to move to other module...)
I fixed that be redefining how reify works normally? or are you testing with regular cljs?
in this case, is a bit different, it looks it tries to use the prototype before the class is created
reify isn't supposed to be conditional in shadow-cljs
let me check if that fix is still in place
i mean the condition is on js output our reify is in a function without any conditional
the reify issue is happening with functions like this
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
yep, thats it
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?
that issue happened to us with shadow-cljs 3.2.0
method moved to other module...
this has been fixed for a long time though? (and not changed in 3.3.0)
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)
with 3.3.0 i have this error
(the same as first image on the thread today)
and there is also :compiler-options {:cross-chunk-method-motion false}. maybe try if that fixes it? otherwise might be something else?
ok, i'll try
I'm uncertain why there is a .$Vector property. that should be flattened entirely
https://github.com/clojure/core.rrb-vector its this one I assume? which version of it do you use?
let me look, it is not a direct dependency
0.1.2
and can you check where (if ever) the $APP.$clojure$core$rrb_vector$rrbt$$.$Vector$ is defined?
is that i'm looking right now
I only found these lines above in the same file
and do not found anywhere the definition of that
i will look on other modules, but on the shared.js it is not defined
the :cross-chunk-method-motion false do not fixes it
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?
I have looked on .$Vector but didn't find anything, let me check it again after a buld with method motion disabled
and as far as I known, i remove cache on every "prod" build, but also, let me check that also
with cleaned cache, it still throws in the same way, but now i see the following warnigs:
And this one related to rrb vector
maybe is a regression on cljs compiler?
why is it compiling cljs.analyzer.api? do you use that somewhere?
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
(best try a build report and check whats requiring it)
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
otherwise that require alone probably adds a megabyte of JS to your build ๐ including cljs.analyzer basically includes the entire compiler
LOL, i will check it
Ok, removing it from :cljs part, no longer shows that warnings, but the rrb vector warnings are stil there
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
there is definitely a bug somewhere. checking.
found the problem and it is fixed in CLJS master, but has no release yet
nice, thanks!
3.3.1 has a fix for the vector problem
awesome, i will try it ASAP
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...
and makes including js dependency 0 problem, because we no longer need to deal with this kind of issues
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
assuming the JS tools can actually output esm (i.e. preserve the export) these days. havent worked with any for a long long time ๐
hehe
i usually do not assume anything when is related to js ecosystem...
which JS tools do you use?
right now we use esbuild for bundle the external js dependencies
would you mean something like this? https://rspack.rs/blog/announcing-1-6#improved-esm-output
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
doesn't really matter what happens with the rest
If we could process the modules separately then it could just bundle those modules which have been processed by a bundler
thats what that does yes
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 disappearsbut for that the JS tool would need to preserve the export { shadow$bridge } which most tools will likely eliminate
i think esbuild will preserve it, but i'll test it
I think it has an esm output format option, but never actually tested it
yes, we use it (on my branch on migrating to :esm shadow target)
to be fair, all this would achieve is eliminating the shadow$bridge global. not sure that actually a problem worth addressing ๐
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...
its :browser only, at least thats the only thing I tested
i confirm that esm build is working as expected with the :js-provider :external
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
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
and I can confirm it works as expected
any particular reason you are trying to avoid the closure compiler for js stuff?