shadow-cljs

David Greenspan 2026-03-27T19:42:25.855589Z

I'm relatively new to CLJS, and brand-new to shadow-cljs. I'm running into a few things. I guess my first question is, is there any way to prefix or otherwise stop the compiler from making all the namespaces globals in dev mode? we have namespaces that start with foo, and I want to name a global foo in the browser, and this particular global can't do double-duty. output wrapping and namespace prefixing exist, but only with advanced optimization turned on, apparently

thheller 2026-03-27T19:57:25.790729Z

no, this is not supported. hot-reload and REPL rely on things being global.

David Greenspan 2026-03-27T19:54:36.379899Z

Another question is how to control the classpath scanning for JS. I want to use a dynamic import, in a JS file, that happens to be on the classpath, and it seems shadow-cljs scans all JS files on the classpath and complains if any of them have a dynamic import. I found that certain directory names are excluded from the scan, but it is hardcoded. Maybe there could be a configuration option for that.

thheller 2026-03-27T20:00:11.045759Z

I don't understand the description. what is the intention of this dynamic import? why is it on the classpath? how is it referenced? just the mere presence shouldn't cause any trouble?

thheller 2026-03-27T20:01:55.152319Z

also don't except the interop with classpath JS to be smooth. it is sketchy at best because I tried to make it part of the :advanced compilation parts, which generic JS often doesn't survive. use only if you really must have two way interop with CLJS. if you are only calling it from CLJS then its better to stay in "npm" land

thheller 2026-03-27T20:02:38.932959Z

also since you are new you might be using the wrong terms. classpath scanning doesn't seem to apply here.

David Greenspan 2026-03-27T22:42:43.221799Z

@thheller thanks for your replies. the file causing the error is a static JS file that we are not necessarily trying to make ClojureScript aware of, in a resources directory (called res). it is on the classpath because the application server reads it and serves it over HTTP. As far as whether it could just not exist on the classpath in the JVM in which shadow is running, I'm not sure; I'd have to do a deeper dive into our deps.edn file and how the various tasks and things are structured. Currently, res is always in the classpath, for all the JVMs we run in development. The error looks like:

RuntimeException INTERNAL COMPILER ERROR.
Please report this problem.

file uses import() with unsupported arguments and cannot be processed

	com.google.javascript.jscomp.Compiler.throwInternalError (Compiler.java:3507)
	com.google.javascript.jscomp.NodeTraversal.throwUnexpectedException (NodeTraversal.java:513)
	com.google.javascript.jscomp.NodeTraversal.traverse (NodeTraversal.java:533)
	com.google.javascript.jscomp.NodeTraversal$Builder.traverse (NodeTraversal.java:469)
	com.google.javascript.jscomp.NodeTraversal.traverse (NodeTraversal.java:539)
	shadow.build.closure.JsInspector.getFileInfo (JsInspector.java:189)
	shadow.build.closure.JsInspector.getFileInfoMap (JsInspector.java:196)
	shadow.build.classpath/inspect-js (classpath.clj:102)
	shadow.build.classpath/inspect-js (classpath.clj:78)
	shadow.build.classpath/inspect-resource (classpath.clj:256)
	shadow.build.classpath/inspect-resource (classpath.clj:252)
	shadow.build.classpath/index-file-add (classpath.clj:955)
I was sort of assuming, but also wanting to confirm, that all JS files on the classpath are fed through Closure (or everything except some hard-coded exceptions), and suggesting there could be a way to customize this. • In the shadow-cljs User Guide, section 13.2.2, it says: IMPORTANT: It is expected that the classpath only contains JavaScript that can be consumed without any pre-processing by the Compiler. • In a file called classpath.clj, there is what looks like a bunch of logic to try to deal with the fact that realistically, classpaths have all sorts of stuff in them, first-party and third-party. It appears that directories named resources are excluded, for example.

David Greenspan 2026-03-27T23:46:48.517639Z

It looks like I'm not going to need a dynamic import in this case, but I think the feature is still worth considering. The JS file in question does happen to have /public/ in its resource path, it's just not at the beginning of the path, and it looks like if it is at the beginning of the path it is ignored.

thheller 2026-03-28T05:51:30.983089Z

should have asked this first. which shadow-cljs version are you using? very old versions used to choke on this, newer ones should not?

thheller 2026-03-28T05:53:35.965929Z

hmm or rather what is that import() call actually using as arguments?

thheller 2026-03-28T05:54:24.730349Z

oh wow .. I can actually reproduce this

thheller 2026-03-28T05:56:22.068879Z

yeah ok, will fix. the closure compiler normally doesn't throw for errors.

ExceptionInfo parsed file had errors {:url #object[java.net.URL 0x620e57ae "file:/Users/thheller/code/shadow-cljs/src/dev/demo/mine.js"], :resource-name "demo/mine.js", :errors [{:message "Semi-colon expected", :line 7, :column 5}]}
so that case is covered. but for some reason it throws for a "bad" import

thheller 2026-03-28T05:57:23.321699Z

actually not even the closure compiler fault ... all my code. will fix.

thheller 2026-03-28T06:15:42.385209Z

should be fixed in 3.3.7

thheller 2026-03-28T06:16:04.016449Z

solid analysis for someone "new" 😉

David Greenspan 2026-03-28T18:56:41.426409Z

oh awesome, thanks, and thanks! shadow-cljs is super impressive