From b2076f0a3f4a800d260d7dcb20c5fd1ea7267048 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Wed, 8 Apr 2026 10:24:07 +0100 Subject: [PATCH] perf(plugins): prefer require for source public artifacts --- src/plugins/public-surface-loader.test.ts | 43 +++++++++++++++++++++++ src/plugins/public-surface-loader.ts | 39 +++++++++++++++++++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/src/plugins/public-surface-loader.test.ts b/src/plugins/public-surface-loader.test.ts index 7e602574eb1..97f12412987 100644 --- a/src/plugins/public-surface-loader.test.ts +++ b/src/plugins/public-surface-loader.test.ts @@ -1,5 +1,6 @@ import fs from "node:fs"; import os from "node:os"; +import pathModule from "node:path"; import path from "node:path"; import { afterEach, describe, expect, it, vi } from "vitest"; import { importFreshModule } from "../../test/helpers/import-fresh.ts"; @@ -63,4 +64,46 @@ describe("bundled plugin public surface loader", () => { platformSpy.mockRestore(); } }); + + it("prefers source require for bundled source public artifacts when a ts require hook exists", async () => { + const createJiti = vi.fn(() => vi.fn(() => ({ marker: "jiti-should-not-run" }))); + vi.doMock("jiti", () => ({ + createJiti, + })); + const requireLoader = Object.assign( + vi.fn(() => ({ marker: "source-require-ok" })), + { + extensions: { + ".ts": vi.fn(), + }, + }, + ); + vi.doMock("node:module", async () => { + const actual = await vi.importActual("node:module"); + return { + ...actual, + createRequire: vi.fn(() => requireLoader), + }; + }); + + const publicSurfaceLoader = await importFreshModule< + typeof import("./public-surface-loader.js") + >(import.meta.url, "./public-surface-loader.js?scope=source-require-fast-path"); + const tempRoot = createTempDir(); + const bundledPluginsDir = path.join(tempRoot, "extensions"); + process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledPluginsDir; + + const modulePath = path.join(bundledPluginsDir, "demo", "secret-contract-api.ts"); + fs.mkdirSync(path.dirname(modulePath), { recursive: true }); + fs.writeFileSync(modulePath, 'export const marker = "source-require-ok";\n', "utf8"); + + expect( + publicSurfaceLoader.loadBundledPluginPublicArtifactModuleSync<{ marker: string }>({ + dirName: "demo", + artifactBasename: "secret-contract-api.js", + }).marker, + ).toBe("source-require-ok"); + expect(requireLoader).toHaveBeenCalledWith(pathModule.resolve(modulePath)); + expect(createJiti).not.toHaveBeenCalled(); + }); }); diff --git a/src/plugins/public-surface-loader.ts b/src/plugins/public-surface-loader.ts index d873c82f054..d2bdf7f87e7 100644 --- a/src/plugins/public-surface-loader.ts +++ b/src/plugins/public-surface-loader.ts @@ -1,4 +1,5 @@ import fs from "node:fs"; +import { createRequire } from "node:module"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { createJiti } from "jiti"; @@ -19,6 +20,7 @@ const OPENCLAW_PACKAGE_ROOT = moduleUrl: import.meta.url, }) ?? fileURLToPath(new URL("../..", import.meta.url)); const loadedPublicSurfaceModules = new Map(); +const sourceArtifactRequire = createRequire(import.meta.url); const publicSurfaceLocations = new Map< string, { @@ -29,6 +31,28 @@ const publicSurfaceLocations = new Map< const jitiLoaders = new Map>(); const sharedBundledPublicSurfaceJitiLoaders = new Map>(); +function isSourceArtifactPath(modulePath: string): boolean { + switch (path.extname(modulePath).toLowerCase()) { + case ".ts": + case ".tsx": + case ".mts": + case ".cts": + case ".mtsx": + case ".ctsx": + return true; + default: + return false; + } +} + +function canUseSourceArtifactRequire(params: { modulePath: string; tryNative: boolean }): boolean { + return ( + !params.tryNative && + isSourceArtifactPath(params.modulePath) && + typeof sourceArtifactRequire.extensions?.[".ts"] === "function" + ); +} + function createResolutionKey(params: { dirName: string; artifactBasename: string }): string { const bundledPluginsDir = resolveBundledPluginsDir(); return `${params.dirName}::${params.artifactBasename}::${bundledPluginsDir ? path.resolve(bundledPluginsDir) : ""}`; @@ -93,6 +117,19 @@ function getJiti(modulePath: string) { return loader; } +function loadPublicSurfaceModule(modulePath: string): unknown { + const { tryNative } = resolvePluginLoaderJitiConfig({ + modulePath, + argv1: process.argv[1], + moduleUrl: import.meta.url, + preferBuiltDist: true, + }); + if (canUseSourceArtifactRequire({ modulePath, tryNative })) { + return sourceArtifactRequire(modulePath); + } + return getJiti(modulePath)(modulePath); +} + function getSharedBundledPublicSurfaceJiti( modulePath: string, tryNative: boolean, @@ -156,7 +193,7 @@ export function loadBundledPluginPublicArtifactModuleSync(para const sentinel = {} as T; loadedPublicSurfaceModules.set(location.modulePath, sentinel); try { - const loaded = getJiti(location.modulePath)(location.modulePath) as T; + const loaded = loadPublicSurfaceModule(location.modulePath) as T; Object.assign(sentinel, loaded); return sentinel; } catch (error) {