← Back to PRs

#13109: fix(plugins): inject globalThis.require for CJS interop in jiti-loaded extensions

by mcaxtr open 2026-02-10 04:24 View on GitHub →
size: S trusted-contributor experienced-contributor
## Summary Fixes #12854 Extensions loaded via jiti run in an ESM context where `require` is unavailable. CJS dependencies that internally call `require()` (e.g. `@vector-im/matrix-bot-sdk` calling `require("events")`) crash at runtime with `ReferenceError: require is not defined`. This PR: - Injects a `globalThis.require` shim at module load time via `createRequire(import.meta.url)` so CJS packages always have a usable `require` - Re-anchors `globalThis.require` to each plugin's source path before `jiti()` evaluates it, so CJS dependencies resolve from the plugin's own `node_modules` - Saves/restores the pre-existing `globalThis.require` around the plugin loading loop so runtime code outside the loader is unaffected ## Test plan - [x] New test: `injects globalThis.require for CJS interop in jiti-loaded plugins` — verifies the shim exists and resolves built-in modules - [x] New test: `loads plugins whose CJS dependencies call require() at runtime` — creates a real CJS helper that calls `require("node:path")`, loads a plugin that depends on it, verifies `status === "loaded"` - [x] All 16 loader tests pass (TDD: both new tests fail before the fix, pass after) - [x] `pnpm build && pnpm check` clean <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This change adjusts the plugin loader so extensions evaluated via `jiti` (ESM context) have a `require` available for CommonJS interop. It injects a `globalThis.require` shim via `createRequire(import.meta.url)`, re-anchors `globalThis.require` to each plugin’s source path before `jiti()` evaluation so CJS dependencies resolve from the plugin’s own `node_modules`, and saves/restores any pre-existing `globalThis.require` around the plugin loading loop. Tests are added to verify the shim exists and can resolve built-in modules, and that plugins with CJS dependencies calling `require()` at runtime load successfully. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge with minimal risk. - The change is narrowly scoped to plugin loading, adds targeted tests that exercise the new behavior (globalThis.require injection and per-plugin require anchoring), and does not introduce broader behavioral changes beyond the loader’s evaluation context. - No files require special attention <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs