-
Notifications
You must be signed in to change notification settings - Fork 72
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
Sugary defaults: can we create a simple case for advanced ahead-of-time tools? #7
Comments
package-community/discussions#2 is relevant I would like to note my dislike if this would cause diverging package ecosystems. |
I'll note that this also is important if we want to enable people who are not using package managers to use bare import specifiers without a lot of manual synchronization between their filesystem and their package map. For example, imagine someone who downloads libraries as zip files and unzips them into a Or imagine a tutorial that says something like "insert these lines into your page and now you can use any package on npm:" {
"pattern": "https://normalized.unpkg.com/*/index.js"
} (Here "normalized.unpkg.com" is a hypothetical variant of unpkg that ensures a top-level index.js is always the main module, somehow.) |
I'm not against adding this, but I strongly prefer to not have this in the first cut. I think we can carefully add this later. |
Adding |
After trying out prefix-matching with many existing packages in node.js (and based on feedback from bundlers), it looks like the bare specifier mapping there may move away from prefix and instead always suggest using a syntax that's very similar to this. Since import maps haven't shipped widely yet, this may be an opportunity to prevent confusion on the browser side and "just" never add prefix-matching. For the cases where prefix-matching behavior is the actual desired behavior, it can be expressed with fairly limited overhead using basic pattern support: {
"imports": {
// before:
"components/": "/static/app/components/",
// after:
"components/*": "/static/app/components/*",
// or with the syntax in OP:
"components/*": "/static/app/components/$1",
}
} |
To add to @jkrems's point here, Node.js is currently considering landing effectively an analog to this feature here - nodejs/node#34718. The PR would effectively then seek to deprecate the trailing slash path exports if it lands as we're finding these pattern definitions more flexible. |
I've been using a method similar to convention based flat mapping: I prefix, usually with a tool, all bare imports with /lib. Then I have both dynamic (nginx) and static (my keaton static cache builder) ways of mapping /lib to particular libraries not only from node_modules but also various other application directories. Publishing the tools and technique soon. |
A workaround in the absence of this is a simple Service Worker that remaps the path based on any Javascript logic. This is less than ideal because it would require the complexity, overhead, and browser-support of a Service Worker, but it's available today, and may be useful as a thought exercise. |
In the way I see ServiceWorker, they cannot be used to control import behaviour as they are installed concurrently with the main page. To me they can start to control import behaviour (if worker installed successfully) only the next time page is loaded. |
@dmail This is part of the overhead and complexity, and your concern is noteworthy — it's not immediately obvious how to solve the many complex needs of
For example: importing navigator.serviceWorker.ready.then(() => import('/entry')) However, your comment is illustrative of the fact that Service Workers are a complex mechanic, versus an import maps glob. |
Waiting to execute javascript until the service worker is installed is not just complexity, but a performance limitation. This documentation talks about service workers as an alternative that was considered: https://github.com/WICG/import-maps#service-workers |
How about in a first iteration we "allow" This would mean the functionality would be exactly like the existing {
"imports": {
"lodash/": "/node_modules/lodash-es/",
"lodash/*": "/node_modules/lodash-es/*",
}
} 👆 both of these imports are exactly the same We would however gain
What do you think? |
I would suggest mimicking the behavior well-defined for the {
"exports": {
"./features/*.js": "./src/features/*.js"
}
} |
This globbing feature would be generic and would cover extensionless specifiers, while the idea in is simpler, with no globbing, specifically for extensions in a way similar to scopes. |
This would be very useful for certain libraries, for example here's an importmap for Shoelace: "@shoelace-style/shoelace/": "/node_modules/@shoelace-style/shoelace/", and usage: import '@shoelace-style/shoelace/dist/components/card/card.js' Importing from "shoelace/*": "/node_modules/@shoelace-style/shoelace/dist/components/*/*.js", and the usage would then be: import 'shoelace/card' Wildcards would also play well with TypeScript |
I hope import-map can provide a Subpath patterns function similar to node exports, so that I can run the module in the browser without adding the |
I think the core reasons from the npm world to support subpath patterns are:
It's a little unfortunate that Node shipped a pattern capability that import maps don't support, but here we are and I think it'd be a pragmatic thing to do. |
As mentioned in "A convention-based flat mapping", it'd be ideal to also support a way of doing a very simple package map for applications which are laid out ahead of time in a conventional way on-server. For example, you could imagine something like
In offline discussions, @nyaxt cautioned that this would add a lot of complexity to what was so far a simple format. For example, as-written this would presumably work at any level of the tree. Still, it'd sure be nice...
An alternative is to not reuse the same format, but instead come up with something specifically tailored for this use case, that only works at top level. As a straw-person, you could do:
The text was updated successfully, but these errors were encountered: