nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
107.56k stars 29.58k forks source link

Special URL schemes for resources within single executable applications #53715

Open joyeecheung opened 4 months ago

joyeecheung commented 4 months ago

When discussing about the implication of using URLs to register module hooks (so if SEA uses it to override module loading to point loads to within the binary, the SEA need a way to override default module resolution before its own resolution customization is registered) @GeoffreyBooth came up with the idea of adding special URL schemes like node-sea: which allows various APIs to point to assets within the binary. Since SEA was designed with a lower-level user-land abstraction layer in mind (for example, turning fs API calls from within the application into an access to sea.getAssetRaw() + some additional access), this looks like a good utility for that abstraction layer in general, beyond just module hooks. So opening this issue to see what others think of it.

cc @nodejs/single-executable

arcanis commented 4 months ago

Since custom url schemes wouldn't be compatible with the path module and how most 3rd-party library and tools work with regards to paths (countless of ${path}/package.json), I'd only see it as very moderately useful.

Yarn (and Electron, I think) treats archives as virtual mount points (ie /home/foo/file.zip/package.json is a valid path). It works well for our use cases.

joyeecheung commented 4 months ago

The idea here is mostly addressing the request to maintain the module.register() API in the new hooks proposal, which requires registering a hooks via an URL - and in a SEA use case, you can't really register hooks via a file:// URL to patch the internal modules.

For the path use case to work, I think this would be a lower-level primitive for path hooks (e.g. path.registerHooks('node-sea://path/to/path/hooks')). There will need to be some abstraction layer (likely in user land) that handle the redirection from a path API access to something inside the SEA, and node-sea:// is not intended as the full solution, but a utility for such abstraction.

ExE-Boss commented 3 months ago

Note that the URI scheme would have to be node-sea: without the //, as // in an URI means that the following field is the authority section (i.e.: host and port)[^1]:

URI           = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

hier-part     = "//" authority path-abempty
              / path-absolute
              / path-rootless
              / path-empty

authority     = [ userinfo "@" ] host [ ":" port ]

path-abempty  = *( "/" segment )
path-absolute = "/" [ segment-nz *( "/" segment ) ]
path-rootless = segment-nz *( "/" segment )
path-empty    = 0<pchar>

segment       = *pchar
segment-nz    = 1*pchar

[^1]: RFC 3986 – Uniform Resource Identifier (URI): Generic Syntax

joyeecheung commented 3 months ago

Good catch, it should be node-sea: