Open martinklepsch opened 3 months ago
Although we've discussed this, I think this also falls into the category of proposing a solution rather than stating a problem.
I think the issue is: when squint compiles a file, should compileString
already resolve symbolic namespaces to files (e.g. foo.bar
becomes ../foo/bar.cljs
or ../foo/bar.cljc
etc such that the plugin won't have to implement extra logic to resolve files or should this logic be in the plugin (to which the above proposed solution is but one detail).
I think I prefer to have this logic as much as possible in one place such that efforts shouldn't have to be duplicated. This logic already exists for the squint CLI + squint.edn
approach and maybe it would be interesting to see if we could lift this logic into compileString
somehow such that the plugin can also benefit from this.
Fair point, let me try to get more at the underlying problem:
These days many tools operate on ESM module graphs, they use them to create bundles, transpile files as they are imported etc. Tools like Vite and Rollup allow you to tell them how to resolve the right side of an import statement. For example vite-plugin-svgr
can turn SVGs into React components:
import Logo from "./logo.svg?react";
In this case the plugin can tell Vite that it knows how to resolve modules ending with .svg?react
and automatically compiles them to JS modules containing a React component on the fly.
Currently to resolve namespaces we have squint.edn
which tells the compiler where to look for files. But in the case of tools like Vite it's not actually squint that does the lookup and instead it is Vite. It would be great to be able to teach Vite how to look up Squint namespaces.
Right now a Vite plugin could intercept module resolution but with namespaces just being compiled to plain strings we'd need to employ heuristics to determine if a given string is in fact a namespace.
(require [foo.bar :as foo])
import foo from "foo.bar";
The JS doesn't give a clear indication that foo.bar
is a namespace making it difficult for Vite to actually find the respective .cljs
file and compile it.
:paths
from squint.edn
to know about directories it should scan for namespaces. it would be interesting to see if we could lift this logic into
compileString
somehow such that the plugin can also benefit from this.
I guess compileString
could also transform symbolic namespaces to filepaths so the above example would become something like
import foo from "./src/foo/bar.cljs";
but then that isn't really runnable JS since the cljs file still needs to be compiled / the import needs to point at JS. But for the purpose of the Vite plugin this could work.
Another thought: Maybe the API could also be to pass the contents of squint.edn
to compileString
. That way the APIs would be reachable from both the CLI (with squint.edn
implicitly read) and JS, where the data could either be read from squint.edn
or provided raw.
But in the case of tools like Vite it's not actually squint that does the lookup and instead it is Vite. It would be great to be able to teach Vite how to look up Squint namespaces.
squint could still resolve those symbols to e.g. "./foo.cljs"
using the same mechanism that is now used in the squint CLI and then vite would work exactly the same as when you would manually write that.
This is more in line with your second post I think, but the API could also just read squint.edn
itself. Basically we need programmatic access to compileString
not from the lower level API but what is used by the CLI and hook that up to the plugin, then we're all set I think.
That would also then enable using macros
Similar discussion as #500
I think if we would expose this function: https://github.com/squint-cljs/squint/blob/9d2415394be87832658f4a278761b19be1f520e0/src/squint/internal/cli.cljs#L66-L104
or this one:
or perhaps a slight variation on both
then we would have both macro and symbolic namespace support
To upvote this issue, give it a thumbs up. See this list for the most upvoted issues.
Is your feature request related to a problem? Please describe.
I'm using squint with vite as a build tool and I'd like to explore how I could integrate library dependencies like promesa into squint. Currently when requiring a namespace it just shows up as a verbatim string which makes it difficult to implement custom resolver logic.
Describe the solution you'd like
Something like this would be great, the prefix could be configurable but also a static prefix would be enough.
Additional context
Here's a basic Rollup plugin using
resolveId
Rollup is the bundler behind
vite
and supports emitting code for the browser, node etc.The below can be used as an entry in the
plugin
array in vite's config.