denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
95.5k stars 5.3k forks source link

Revisiting "Custom URL Schemes or Configurable Resolvers for Imports" #16555

Open harrysolovay opened 1 year ago

harrysolovay commented 1 year ago

In May of 2019, @rsp opened denoland/deno#2348, in which he describes the feature request of custom URL schemes / resolution.

@ry's response at the time:

I wouldn't rule out having a general purpose hook for custom URL schemes in the future. (It would be nice to have ipfs:// for example. Then again, that might be better if it was built-in and default.)

However, at the moment I would like to keep this simple and not add a bunch of hooks that we may later regret. (Hooks allow things to get complex.)

Given the recent addition of npm:-prefixed imports and the stability of the project as a whole, perhaps it's time to revisit this feature request?

If not, please let me know and I'll close out this issue.

lrowe commented 1 year ago

I think it's worth reconsidering Service Workers for this use case since they're a part of the standard Web Platform API.

Service Worker API support was previously discussed in #5957, but I believe the rationale for discounting them may be misconceived:

Due to how the API works (service workers are installed after first startup, plus imperative API) it's not a valid solution to custom module loaders or rewriting fetch requests (ie. the rewrites wouldn't work the first time you try to run it, they would only work on subsequent process runs). https://github.com/denoland/deno/issues/5957#issuecomment-985494969

Here's an example of using @swc/wasm-web to transform TypeScript to JavaScript at load time in the browser: https://codesandbox.io/s/service-worker-transpilation-ckifig.

This works on first startup by awaiting the controllerchange event. Subsequently the dynamic import("./app.tsx") along with its transitive static imports not previously loaded are intercepted by the service worker and transpiled to JavaScript.

For deno I imagine it might make sense to offer an option to preload a service worker before the main script is loaded as a convenience, but it would be equivalent to a wrapper script managing the service worker and dynamically importing the main script. Conceptually this would be like visiting a page in the browser where the service worker already running.

My motivation here is that I would like to write loader transforms without a separate bundler. This seems doable in the browser but it would be very convenient to be able to use them from deno too.

roelentless commented 10 months ago

Another reason for this would be for accessing modules (dynamically) from an authenticated host without sharing credentials with the modules (keep them out off the path and out of imports.meta.url).

Installing a service worker at start time for the main thread deno run --sw ./sw.ts ... or passing it when creating a worker would be ideal. Eg: new Worker(..., { type, serviceWorker: './sw.ts' }); For the worker that could act as an override.

I'm now falling back from clean remote imports to an ugly setup to work around this.

Service worker support would allow this, as previously discussed in closed issue #5957.