70bf21e064
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled
111 lines
3.2 KiB
TypeScript
111 lines
3.2 KiB
TypeScript
import { join, resolve } from "node:path";
|
|
import {
|
|
BuildContext,
|
|
BuildOptions,
|
|
context,
|
|
Plugin,
|
|
build as runBuild,
|
|
} from "esbuild";
|
|
|
|
type EmbedWorkersOptions = {
|
|
/**
|
|
* workersRootDir is a path to a directory containing external Workers that
|
|
* will be bundled
|
|
*/
|
|
workersRootDir: string;
|
|
workerOutputDir: string;
|
|
};
|
|
|
|
/**
|
|
* embedWorkerPlugin is an ESBuild plugin that will look for imports to Workers specified by `worker:`
|
|
* and bundle them into the final output.
|
|
*/
|
|
export const embedWorkersPlugin: (options: EmbedWorkersOptions) => Plugin = ({
|
|
workerOutputDir,
|
|
workersRootDir,
|
|
}) => {
|
|
return {
|
|
name: "embed-workers",
|
|
setup(build) {
|
|
const namespace = "embed-worker";
|
|
// For imports prefixed with `worker:`, attempt to resolve them from a directory containing
|
|
// your Workers
|
|
build.onResolve({ filter: /^worker:/ }, async (args) => {
|
|
let name = args.path.substring("worker:".length);
|
|
// Allow `.worker` to be omitted
|
|
if (!name.endsWith(".worker")) name += ".worker";
|
|
// Use `build.resolve()` API so Workers can be written as `m?[jt]s` files
|
|
const result = await build.resolve("./" + name, {
|
|
kind: "import-statement",
|
|
// Resolve relative to the directory containing the Workers
|
|
resolveDir: workersRootDir,
|
|
});
|
|
if (result.errors.length > 0) return { errors: result.errors };
|
|
return { path: result.path, namespace };
|
|
});
|
|
build.onLoad({ filter: /.*/, namespace }, async (args) => {
|
|
await runBuild({
|
|
platform: "node", // Marks `node:*` imports as external
|
|
format: "esm",
|
|
target: "esnext",
|
|
bundle: true,
|
|
sourcemap: true,
|
|
sourcesContent: false,
|
|
external: ["cloudflare:workers"],
|
|
entryPoints: [args.path],
|
|
minifySyntax: true,
|
|
outdir: workerOutputDir,
|
|
plugins: [],
|
|
});
|
|
|
|
let outPath = args.path.substring(workersRootDir.length + 1);
|
|
outPath = outPath.substring(0, outPath.lastIndexOf(".")) + ".js";
|
|
outPath = JSON.stringify(outPath);
|
|
const contents = `
|
|
import fs from "fs";
|
|
import path from "path";
|
|
import url from "url";
|
|
let contents;
|
|
export default function() {
|
|
if (contents !== undefined) return contents;
|
|
const filePath = path.join(__dirname, "workers", ${outPath});
|
|
contents = fs.readFileSync(filePath, "utf8") + "//# sourceURL=" + url.pathToFileURL(filePath);
|
|
return contents;
|
|
}
|
|
`;
|
|
return { contents, loader: "js" };
|
|
});
|
|
},
|
|
};
|
|
};
|
|
|
|
const distDir = resolve(__dirname, "../dist");
|
|
// When outputting the Worker, map to the structure of 'src'.
|
|
// This means the plugin will outout the build Workers to a `workers` dist in `dir`
|
|
const workerOutputDir = resolve(distDir, "workers");
|
|
const workersDir = resolve(__dirname, "../src/workers");
|
|
|
|
export async function buildPackage() {
|
|
console.log("Building the module");
|
|
await runBuild({
|
|
platform: "node",
|
|
target: "esnext",
|
|
format: "cjs",
|
|
bundle: true,
|
|
sourcemap: true,
|
|
entryPoints: ["src/index.ts"],
|
|
plugins: [
|
|
embedWorkersPlugin({
|
|
workersRootDir: workersDir,
|
|
workerOutputDir,
|
|
}),
|
|
],
|
|
external: ["@cloudflare/workers-types", "miniflare"],
|
|
outdir: distDir,
|
|
});
|
|
}
|
|
|
|
buildPackage().catch((exc) => {
|
|
console.error("Failed to build external package", `${exc}`);
|
|
});
|