discourse/frontend/discourse/lib/dynamic-chunk-url-plugin.mjs
David Taylor a32f09021f
DEV: Refactor worker and WASM loading for media-optimization-worker (#40793)
- Add new `discourse/app/workers/...` directory

- Adds a custom rolldown plugin which can create a dynamic entrypoint
and return a digested URL for it

- Update media-optimization service to use this new rolldown interface,
and launch the worker via a `blob:`

- Updates media-optimization to use type:module worker, and improve
boot-error-handling strategy

This is an improvement for a few reasons:

1. We can drop all the manual entrypoint/manifest/ruby config which was
used to obtain the media-optimization bundle URL

2. We don't need to serve the worker from the (undigested/uncached)
`public/` directory on the forum domain. Instead we just generate a
one-liner worker entrypoint and create a blob from it

3. Since we're launching from a blob, the worker inherits the CSP of the
host document, which is a nice defense-in-depth improvement
2026-06-12 09:18:32 +01:00

49 lines
1.6 KiB
JavaScript
Vendored

import { relative } from "path";
const PREFIX = "virtual:dynamic-chunk-url:";
const RESOLVED_PREFIX = "\0" + PREFIX;
/*
* Importing `virtual:dynamic-chunk-url:<specifier>` emits <specifier> as its own
* bundled, hashed chunk and resolves to that chunk's final URL (a string). The
* specifier is resolved like a normal import (relative to the importer).
*
* For example, a worker can be started from a blob bootstrap that imports the real
* chunk by absolute URL, so the worker inherits the host document CSP.
*/
export default function dynamicChunkUrlPlugin() {
return {
name: "dynamic-chunk-url",
resolveId: {
filter: { id: /^virtual:dynamic-chunk-url:/ },
async handler(source, importer) {
const target = source.slice(PREFIX.length);
const resolved = await this.resolve(target, importer, {
skipSelf: true,
});
if (!resolved) {
this.error(`dynamic-chunk-url: could not resolve "${target}"`);
}
return { id: RESOLVED_PREFIX + resolved.id };
},
},
load: {
filter: { id: /^\0virtual:dynamic-chunk-url:/ },
handler(id) {
const target = id.slice(RESOLVED_PREFIX.length);
const refId = this.emitFile({
type: "chunk",
id: target,
name: relative(process.cwd(), target)
.replace(/\.[^.]+$/, "")
.replace(/[/\\]/g, "-"),
preserveSignature: "strict",
});
return {
code: `export default import.meta.ROLLUP_FILE_URL_${refId};`,
moduleType: "js",
};
},
},
};
}