-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Changes to support hosting within larger compilers (esbuild/swc/webpack/rollup) #169
Comments
Apologies for the wall of text. You library seems cool and I wanted to organize my thoughts after digging around the code in the middle of the night😅 |
Making it possible to call rsass from other compilation environments was the point of the current Putting the entire resolver on the other side of the boundary would imply the user have to implement the name resolution rules, which I considered someting that should be kept in one place (note that the rules in Context::find_file` still is more simplistic than it should be, so to be correct, the duplicated code would have to be more than that). Is crossing the FFI boundary really that expensive? I'd imagine that even if its a lot more expensive than a regular function call, it's still cheaper than actually accessing the file system (probably by a magnitude or so) and therefore hardly relevant? Could you try implementing your resolver api, but also implement using a |
This is, an unfortunate byproduct, yeah. I originally toyed around with the idea of just turning the
As written, at no point does the Loader get
I think this makes resolving with the bundler impossible, since
Libsass's behaviour here is to allow hijacking resolution, but also falls back to default resolution logic (what is currently in
This is true if you assume you are going to disk each time. But in the context of a larger build, those resolutions and files are likely already cached in memory as they will be read multiple times over the course of a build. This becomes more likely during an incremental rebuild (e.g. in development). where file content will be cached in-memory between runs. I also have a bias towards engineering around FFI overhead because I'm working in go, where the FFI story is absolutely awful. Since go's special stack format requires a full register switch when you do FFI with C-calling-convention languages, FFI gets expensive quickly. For completeness, it's worth noting that
Seems reasonable -- I'll give it a shot! |
Hey there,
I'm working on a project and am interested in using
rsass
, hosted inside of a customesbuild
plugin. This would be replacing an existing plugin that is based onlibsass
I think I have a rough sketch of what that would entail, and I'd like to pursue it. However, I'm curious if this work is something you'd be interested in upstreaming into
rsass
, or if it's something I'd be maintaining in a fork indefinitely.Updates to Rsass
Here's my thought process:
@import
/@use
strings are resolved to files:node-sass
, the import specifier~my-node-package/src/colors.sass
resolves using node's builtin resolver, reads the file, and passes the result back to libsassLoader
, which essentially acts as a virtual file system (a singlefind_file()
method).rsass
does import resolution and file loading to accommodate this approachActual Changes
What I was thinking of was:
Loader
in Context with aResolver
trait that looks something like this sketch:Context::find_file() and do_find_file()
into someimpl Resolver<T> for Loader <T>
, backed by the existingLoader::find_file()
implementations.These could also be named
ResolverLoader
(the new API I am describing), andLoader
(the existing virtual filesystem)FFIResolver
Minimizing Rsass -> Host calls during compilation
When consuming rsass in FFI scenarios, my plan was to provide an implementer of the new
Resolver
trait that performed the actual FFI. To do as little FFI as possible, it makes sense to cache resolutions on the rust-side. I was thinking of using a shared probabalistic cache based on the import + export pairs. This is, again, to minimize the time spent crossing the FFI barrier during compilationThe API presented to C-like languages would be a bit different to support this caching
That could then be used to avoid additional FFI round-trips at the cost of some memory overhead.
Minimizing Host -> Rsass calls during incremental compilation
Even if all the files within the compilation of a file are fully cached in the FFIResolver, Crossing the barrier from the host into rust to re-evaluate the compilation is still expensive.
libsass solves this problem by returning the list of resolved files from a compilation I make heavy use of this in my existing libsass-based plugin to check relevant files for changes and use that to short-circuit full compilation results during rebuild requests, to minimize the number of calls into libsass.
I think the FFIResolver is in a reasonable position to do something similar, since it will be intercepting all file resolutions.
To me both of these this seems like it would be an internal concern of the FFIResolver.
However, if there is any interest in supporting hosted compilers / FFI, I think it would make sense to PR in the FFIResolver I'm describing here as well.
If not, I'm happy to maintain it as an implementation detail on a wrapping library / fork
The text was updated successfully, but these errors were encountered: