mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-06-19 04:03:45 +08:00
- 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
49 lines
1.6 KiB
JavaScript
Vendored
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",
|
|
};
|
|
},
|
|
},
|
|
};
|
|
}
|