From 6a6605c233a2b085728ea23388794778b69502e7 Mon Sep 17 00:00:00 2001 From: fkwp Date: Thu, 17 Sep 2026 17:34:53 +0200 Subject: [PATCH] Let background effects run under the dev server - nodePolyfills rewrote MediaPipe's WASM loader, which mentions `process` - That loader is a classic script whose job is to set self.ModuleFactory; as an ES module it sets nothing, so the segmenter threw "ModuleFactory not set" and no effect could run under `pnpm dev` - Its transform now skips that one directory - Affects blur on main too, not only this feature: neither could be exercised locally before - Production was never affected, since the loader is emitted as an asset there; build still green and the assets still emitted Co-Authored-By: Claude Opus 5 (1M context) --- vite.config.ts | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index 678a86fab..de10137e7 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -24,6 +24,45 @@ import react, { reactCompilerPreset } from "@vitejs/plugin-react"; import { realpathSync } from "fs"; import * as fs from "node:fs"; +/** + * Keeps a plugin's transform off MediaPipe's WASM loader. + * + * nodePolyfills rewrites any module mentioning `process`, and that loader does. + * It is a classic script whose whole job is to set `self.ModuleFactory`; + * rewritten as an ES module it sets nothing on `self`, and background effects + * then fail at runtime with "ModuleFactory not set". A production build is + * unaffected, because there the loader is emitted as a static asset and never + * passes through a transform, which is why this only bites in dev. + */ +function exceptMediaPipeWasm(plugins: PluginOption): PluginOption { + const isLoader = (id: string): boolean => + id.includes("tasks-vision") && id.includes("wasm"); + return (Array.isArray(plugins) ? plugins : [plugins]).map((plugin) => { + if ( + !plugin || + typeof plugin !== "object" || + !("transform" in plugin) || + typeof plugin.transform !== "function" + ) + return plugin; + const transform = plugin.transform; + return { + ...plugin, + transform(this: unknown, code: string, id: string, options: unknown) { + if (isLoader(id)) return null; + return ( + transform as ( + this: unknown, + c: string, + i: string, + o: unknown, + ) => unknown + ).call(this, code, id, options); + }, + } as PluginOption; + }); +} + export const vitePluginsConfig = ({ mode, html = true, @@ -42,10 +81,12 @@ export const vitePluginsConfig = ({ }), react(), wasm(), - nodePolyfills({ - // Enables the 'events' module, which is required by the matrix-js-sdk - include: ["events"], - }), + exceptMediaPipeWasm( + nodePolyfills({ + // Enables the 'events' module, which is required by the matrix-js-sdk + include: ["events"], + }), + ), svgrPlugin({ svgrOptions: { // This enables ref forwarding on SVGR components, which is needed, for