Skip to content
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

Are there plans for importmap-rails to support scopes? #148

Open
mpkuczer opened this issue Aug 24, 2022 · 5 comments
Open

Are there plans for importmap-rails to support scopes? #148

mpkuczer opened this issue Aug 24, 2022 · 5 comments

Comments

@mpkuczer
Copy link

mpkuczer commented Aug 24, 2022

In my project (using Rails 7 with importmap-rails) I am trying to import a module which has a complex dependency graph. In particular, two dependencies (let's call them A and B) depend on a third one (C) although they require different versions of it, and so I end up in dependency hell.

This isn't a problem according to the WICG importmap spec, because you could use scopes to include both versions depending on which scope C is being imported from, like so:

"scopes": {
  "https://ga.jspm.io/npm:path-to-A/": {
     "C": "https://ga.jspm.io/npm:[email protected]/index.js"
  },
  "https://ga.jspm.io/npm:path-to-B/": {
     "C": "https://ga.jspm.io/npm:[email protected]/index.js"
  }
}

In its current state, importmap-rails doesn't make use of the scopes object and only ever parses the imports part of a generated importmap, in fact it ignores any scoped imports. A one-to-one map of names to paths is generated, and as a result, a singular module name can only ever point to a particular version of it. This potentially renders a complex importmap unusable. Is this something we could potentially have support for?

@dhh
Copy link
Member

dhh commented Jun 18, 2023

Happy to see an attempt at supporting this explored. But don't want to dramatically complicate the implementation to get there. Do have a stab.

@dkniffin
Copy link
Contributor

dkniffin commented Aug 24, 2023

This is a pretty important feature. But I think dependency conflicts are kind of rare.

What's more important to me, is that we at least get some alert about subdependencies being incompatible. At the moment, I think if there are different versions of subdependencies, importmap will silently pin one of them, and we'd never know unless it causes issues, right? Maybe I'm wrong.

@aprescott
Copy link

I haven't fully thought this through, but perhaps a solution here could also simplify importmap.rb with respect to transitive dependencies? Currently, pinning will download other packages that the target package relies on, which causes extra work to maintain/track/understand what the actual top-level dependencies of an application are. It would be great if importmap.rb were more like a package.json set of direct dependencies and less like a lockfile. It seems as if "scopes" might permit specifying the transitive dependencies as keys of the mapping. Then, if the vendor/javascript/ directory mirrored the "imports" vs "scopes" structure, removing a dependency could remove the corresponding vendored files, and a dev wouldn't need to figure out top-level vs. transitive deps.

@oboxodo
Copy link

oboxodo commented Apr 26, 2024

@aprescott management of transitive dependencies is one of the reasons we (actually @dkniffin) ended up implementing https://github.com/Quimbee/importmap-package-manager as a wrapper for importmap-rails. It pretty much allows us to use importmap.rb as if it were package.json (*), and we declare only the top-level dependencies in config/importmap_packages.yml.

We've been using it in production since Sep 2023 or so and it's been very helpful.

(*) UPDATE: I was wrong. Actually we leave importmap.rb to be used only for our internal JS dependencies and then declare our 3rd-party dependencies in config/importmap_packages.yml. Then we run rails importmap_package_manager:update which autogenerates config/importmap-packages-lock.rb. And this file acts as package-lock.json or yarn.lock. It then is treated as a complement of importmap.rb.

@dkniffin
Copy link
Contributor

@aprescott Yep, what @oboxodo said. I was hoping importmap-rails would natively have some way to distinguish between dependencies and subdepenencies, so I opened #174, but apparently it's outside the scope of this project. So I made my own!

The other important thing our library does is support version ranges, as described in #173. With those two features, it now behaves much more like you'd expect from a package manager type system.

I don't think scopes will solve those issues, but I might be wrong. As I understand it, scopes are for avoiding dependency conflicts. I do think it's important to have support for that inside importmap-rails, because I don't think there's a way for us to include that in a wrapper library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants