Skip to content
This repository has been archived by the owner on Sep 2, 2023. It is now read-only.

import: urls in Node #222

Closed
guybedford opened this issue Nov 10, 2018 · 14 comments
Closed

import: urls in Node #222

guybedford opened this issue Nov 10, 2018 · 14 comments

Comments

@guybedford
Copy link
Contributor

The current directions of import name maps are to bring these maps to other resources on the web as well, such as CSS and asset loads, using an import: URL. These URLs would be bare specifiers which would then be looked up in the package map themselves.

Node.js could in theory also support these. And where this might come in useful is all of our current use cases around fs.readFile(new URL('./x', import.meta.url)) where instead one might write fs.readFile(new URL('import:x')). Similarly this could be useful for new Worker, if this constructor were to be extended to support a URL input.

Is this something we want to consider? If so, perhaps we should explore some of these use cases further and ensure that Node is also represented in these discussions on the import name maps spec.

@MylesBorins
Copy link
Contributor

MylesBorins commented Nov 10, 2018 via email

@guybedford
Copy link
Contributor Author

Ideally Node.js could follow in implementing import: URLs, but that would require the Node.js URL parser to be contextually aware of the current module to get features like https://github.com/domenic/import-maps/blob/master/spec.md#modifications-to-the-url-parser-for-import-urls.

@weswigham
Copy link
Contributor

Is there a good argument for just allowing arbitrary URL protocol handlers to be registered for the fs library?

@devsnek
Copy link
Member

devsnek commented Nov 12, 2018

@weswigham it couldn't be done at an application level, because it would compromise the integrity of other modules using fs.

@jkrems
Copy link
Contributor

jkrems commented Nov 12, 2018

Not for fs but potentially for a (new) resource loading system. That way we would handle import: URLs there and it could also work for getting dependent files, not just module code. E.g. resource.loadContents('import:some-pkg/stop-words.txt', { referrer: import.meta.url }). Actual APIs and semantics still being a strawman. The specter of such a system was one of the outcomes of the sync Bradley and I had recently. E.g. pushing a lot of module loading concerns into a more generic system that allows consistent hooks into loading of "resources" in general.

@bmeck
Copy link
Member

bmeck commented Nov 13, 2018

This gets into context sensitive URLs, passing these URLs to different modules/locations could alter where they are located (similar to relative URL strings). Any APIs we use should be context aware, which means hanging them off import.meta, language extension, or having bound forms when imported. import() is fine using these URLs because it preserves callsite context info, but fs doesn't so it can lead to gotchas. If you compare import: URLs with first class Module References you might begin to see why passing around a first class value instead of a URL string would be useful.

I personally would rather hold off on this while the spec for import: URLs gets evaluated further. I think first class values solve a variety of problems with import: URL strings.

@guybedford
Copy link
Contributor Author

@bmeck the current implementation being suggested for import name maps is for the URL parser itself to do a check of the contextual script running the code. Now in Node.js we have the issue that URL is itself a module, but it should in theory still be possible in v8 to have this check walk the stack and thus filter to the right module code context. At least that's what would be needed in HTML, and it would be nice if Node could follow to get these benefits for eg new Worker('import:...') or other things.

@weswigham
Copy link
Contributor

Now in Node.js we have the issue that URL is itself a module, but it should in theory still be possible in v8 to have this check walk the stack and thus filter to the right module code context.

I recall people balking at the idea of a global require that does that to allow cjs requires everywhere in esm - I assume the URL module is in the same boat.

@bmeck
Copy link
Member

bmeck commented Nov 13, 2018

@guybedford we could make the URL parser context dependent but then we still get into some issues when passing these around:

// app
import MyWorker from 'custom_worker';
new MyWorker('import:foo');
// custom_worker
import {Worker} from 'worker_threads';
export default class MyWorker extends Worker {
  constructor(url) {
    super(url);
  }
}

Where would the context of the parser be applied? custom_worker? app? inside worker_threads? Would I have to rewrite app to use new URL('import:url')? What happens if the import doesn't resolve to a URL?

@jkrems
Copy link
Contributor

jkrems commented Nov 13, 2018

See also: WICG/import-maps#75

I think adding import: scheme support for APIs would be more confusing that helpful. It's different for <img /> tags but for JS APIs I would find it less confusing to have import.meta.resolve or an equivalent. If Worker resolves the URL it got passed, it should do so relative to the working directory (if at all). That would be mostly consistent with what the web would do, treating the working directory as the document / base URL.

@guybedford
Copy link
Contributor Author

Seems it is currently being considered to reduce this down to an HTML-based URL scheme only, in which case this issue would no longer apply apart from for use cases like JSDom I believe.

@bmeck
Copy link
Member

bmeck commented Dec 30, 2018

Can we close this and leave it to userland situations like JSDom which are creating their own realms through vm.Context to do work already?

@MylesBorins
Copy link
Contributor

Closing this as there has been no movement in a while, please feel free to re-open or ask me to do so if you are unable to.

@SMotaal
Copy link

SMotaal commented Apr 29, 2019

I think this relates to the js: prefix recently added to JavaScript Standard Library Proposal which seems to align with a URL scheme notation (worth noting that it originally used a less URL like form of js:: in its first appearance).

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

No branches or pull requests

7 participants