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

ESM Modules: Allow an option to serve bare module names for importmap use #18538

Open
2 tasks done
weaverryan opened this issue Oct 27, 2023 · 5 comments
Open
2 tasks done

Comments

@weaverryan
Copy link

weaverryan commented Oct 27, 2023

Is your feature request related to a problem? Please describe.

In the Symfony PHP framework, we're heavily-relying on the wonderful ESM support from JsDelivr. In this integration, we allow for users to download the ESM module files from JsDelivr locally. To do that, we:

A) Download the contents of a file - e.g. https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/+esm
B) Parse out import statements to other modules - e.g. import*as t from"/npm/@popperjs/core@2.11.8/+esm";
C) Change those to a "bare" import in the content - e.g. import*as t from"@popperjs/core";
D) Download @popperjs/core locally and add it to the importmap.

Describe the solution you would like.

This is working well, only thanks to some pretty heavy regex to find these imports :). What I would love is:

A) An option to get the contents of a module with bare imports - e.g. perhaps a URL like https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/+esm+importmap

B) A new key on the https://data.jsdelivr.com/v1/packages/npm/bootstrap@5.3.0 endpoint (or a new endpoint) called ems that lists the imports - e.g.

{
    "type": "npm",
    "name": "bootstrap",
    "version": "5.3.0",
    "default": "/dist/js/bootstrap.min.js",
    "files": [],
    "modules": { "@popperjs/core": "2.11.8" }
    "_links": {}

Under modules, the key is the module name (optionally with a path - in some rare cases, the import looks like import e from"/npm/locutus@2.0.16/php/strings/sprintf/+esm";) - and the value is the version, which in some rare cases will be null.

Describe alternatives you have considered.

We currently DO have a workaround. But we would love to make this more accessible for others and more resilient on our end.

Requisites

  • I performed a cursory search of the issue tracker to avoid opening a duplicate issue.
  • I understand that not filling out this template correctly will lead to the issue being closed.

Additional content

I understand that, due to my lack of understanding about jsdelivr, that this could involve significant work or infrastructure changes. I've tried to propose a solution that I imagine would be the easiest, but that's just a guess.

This would definitely help us in Symfony. And my hope is that, as importmaps become more prevalent, this will be useful for other projects. The current ESM works fantastic if you point to them directly. For users who are unable or unwilling to use a CDN on production, it'd be great to offer this.

Thank you :)

@MartinKolarik
Copy link
Member

Hey, thanks for the detailed description. I'll keep this open to consider later, as we were thinking about a similar feature before as well. Unfortunately, I don't think we'll be able to add this soon, but as an improvement that you can do on your side, I'd suggest using a tool such acorn or rollup to get the imports directly from AST instead of the regexes.

@weaverryan
Copy link
Author

Hey, thanks for the detailed description. I'll keep this open to consider later, as we were thinking about a similar feature before as well.

Thank you! Fantastic!

Unfortunately, I don't think we'll be able to add this soon

I get that :)

I'd suggest using a tool such acorn or rollup to get the imports directly from AST instead of the regexes.

We're in PHP - so that's the root of the problem. Fortunately, our regex seems to be holding up... assuming we stop finding new edge-case syntaxes (which I think we will) 🙂

@MartinKolarik
Copy link
Member

I understand, regex seems like the best option, then

What you're building seems quite interesting, so feel free to ping me any time, even directly in your repo, if you run into any issues/questions about the CDN or the API! I'm also curious and couldn't quickly find it - is this feature already part of the stable release or still in development?

@tacman
Copy link

tacman commented Nov 9, 2023

AssetMapper is a new component in Symfony, marked as experimental in 6.3 but will be officially released in Symfony 6.4 / 7 in a few weeks.

After installing Symfony and requiring the asset-mapper component, the developer is able to add front-end assets with the importmap:require command.

bin/console importmap:require bootstrap -vvv
14:16:12 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/bootstrap/resolved"
14:16:13 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/bootstrap/resolved"
14:16:13 INFO      [http_client] Request: "GET https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/+esm"
14:16:13 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/bootstrap@5.3.2/entrypoints"
14:16:13 INFO      [http_client] Response: "200 https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/+esm"
14:16:13 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/bootstrap@5.3.2/entrypoints"
14:16:13 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/@popperjs/core/resolved?specifier=2.11.8"
14:16:13 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/bootstrap/resolved?specifier=5.3.2"
14:16:13 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/@popperjs/core/resolved?specifier=2.11.8"
14:16:14 INFO      [http_client] Request: "GET https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/+esm"
14:16:14 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/@popperjs/core@2.11.8/entrypoints"
14:16:14 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/bootstrap/resolved?specifier=5.3.2"
14:16:14 INFO      [http_client] Request: "GET https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
14:16:14 INFO      [http_client] Response: "200 https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/+esm"
14:16:14 INFO      [http_client] Response: "200 https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
14:16:14 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/@popperjs/core@2.11.8/entrypoints"

                                                                                                                        
 [OK] 3 new items (bootstrap, @popperjs/core, bootstrap/dist/css/bootstrap.min.css) added to the importmap.php!         
                                                                                                                        

Ryan has an excellent tutorial here: https://symfonycasts.com/screencast/asset-mapper and there's documentation at https://symfony.com/doc/current/frontend/asset_mapper.html

@bbb651
Copy link

bbb651 commented May 4, 2024

Also run into this, I'm trying to import codemirror 6 which is split up into a lot of different packages and having multiple different versions of @codemirror/state (even patch ones) breaks the library, bare module names would allow me to control the version of transitive dependencies.

Side note: I noticed sourcemaps are a bit broken es modules, at least on firefox, with esm.run the sourcemaps are point to a path on jsdelivr.com so they don't work at all, and using jsdelivr.com/.../+esm results the sourcemap of the node version of the package(?)

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

4 participants