Inline Worker Plugin for esbuild 0.17+
This is a plugin for esbuild which allows you to import module as bundled script text for usage in Web Workers.
Installation
npm install -D @aidenlx/esbuild-plugin-inline-worker
-- or --
yarn add -D @aidenlx/esbuild-plugin-inline-worker
-- or --
pnpm add -D @aidenlx/esbuild-plugin-inline-worker
Usage
By default the plugin intercepts all worker:*
imports and replaces them with the bundled script text. For example:
import WorkerCode from "worker:./worker.js";
import { fromScriptText } from "@aidenlx/esbuild-plugin-inline-worker/utils";
const worker = fromScriptText(
WorkerCode,
{ name: "i'm a worker" }
);
To enable the plugin, add it to the plugins
option of esbuild:
import { build } from "esbuild";
import inlineWorker from "@aidenlx/esbuild-plugin-inline-worker";
await build({
plugins: [inlineWorker()],
});
If you are using TypeScript, you can create a file named inline-worker.d.ts
in your source code folder with the following content :
declare module "worker:*" {
const inlineWorker: string;
export default inlineWorker;
}
Watch mode support
If you are using esbuild v0.17+ in watch mode, you can use the watch
option to enable watch mode support:
import { build } from "esbuild";
import inlineWorker from "@aidenlx/esbuild-plugin-inline-worker";
const isProd = process.env.NODE_ENV === "production";
const commonOptions = {
};
const mainOptions = {
...commonOptions,
plugins: [inlineWorker({ watch: !isProd })],
};
if (!isProd) {
const ctx = await context(mainOptions);
try {
await ctx.watch();
} catch (err) {
console.error(err);
await cleanup();
}
process.on("SIGINT", cleanup);
async function cleanup() {
await ctx.dispose();
}
} else {
await build(mainOptions);
}
Custom Worker Import Pattern
You can use the filter
option to customize the import pattern. For example, the default pattern worker:*
works like this:
await build({
plugins: [
inlineWorkerPlugin({
filter: {
pattern: /^worker:/,
transform: (path, pattern) => path.replace(pattern, ""),
},
}),
],
});
To only intercept *.worker.js
imports, you can use:
await build({
plugins: [inlineWorkerPlugin({ filter: { pattern: /\.worker\.js$/ } })],
});
Remember to change the inline-worker.d.ts
file to match the new pattern:
declare module "*.worker.js" {
const inlineWorker: string;
export default inlineWorker;
}
Custom Build Options
You can pass a function to the buildOptions
option to customize the build options for each worker file:
await build({
plugins: [
inlineWorkerPlugin({
buildOptions: ({ path, resolveDir, entryPoint }, resolve) => {
let tsconfig = "tsconfig.worker.json";
if (path.endsWith("worker-special.js")) {
tsconfig = "tsconfig.worker-special.json";
} else if (path.startsWith("@/worker/")) {
tsconfig = join(entryPoint, "..", "tsconfig.json");
}
return {
sourcemap: !isProd ? "inline" : undefined,
tsconfig,
}
},
}),
],
});