Is it possible to override :js-options {:entry-keys ... for individual packages? I have a weird dep where the :browser key build is a UMD that includes ALL its dependencies, but the :main and :module builds are contained cjs and esm. I need to avoid this particular :browser build, but I'm not sure about that in general.
Would it be :js-options {:resolve {"some-package" {:target :file :file "node_modules/some-package/dist/my.build.cjs ?
----
Also, the guide says "Interop between CommonJS and ESM can be tricky so shadow-cljs defaults to using CommonJS but it can be beneficial to use ESM."
How bad is mixing them in 2025? Is cjs still preferred?
Thx for the suggestion! I'll try that next time.
that entirely depends on what packages you are using. even some modern packages (react) still only ship commonjs, but are generally well behaved and mix well with ESM. some on the other hand are entirely incompatible due to their ESM and commonjs variants exporting different APIs (mostly related to default exports)
and no. there is no per-package :entry-keys
generally avoid :target :file and prefer :resolve {"some-package" {:target :npm :require "some-package/dist/my.build.cjs
Interestingly, it looks like the cjs build also had an issue caused by shadow Js require rewrites.
The underlying problem is that this videojs plugin has its own dir of node_modules, and when it imports video.js, shadow altered it to pull from its copy under its node_modules (`require("module$node_modules$$devmobiliza$videojs_vimeo$node_modules$video_js$dist$video_cjs")`), instead of my copy from the top-level node_modules (`require("module$node_modules$video_DOT_js$dist$video_cjs")`). This means its registering itself as a plugin in the wrong place.
I don't know how node typically works, but it's definitely related to how shadow/closure rewrites js requires, because it worked once I deleted the plugin's local node_modules. Shadow/closure rewrote the file to correctly use the top-level videojs.
Is this a shadow bug?
not a bug from what this reads like. the default node resolve rules are to use nested packages when present. you can either remove the reason that nested package exists in the first place, which is usually a dependency conflict. or you can set :js-options {:allow-nested-packages false} to ignore them and just use "top-level" packages instead