perf(plugins): lazy-create jiti loader

This commit is contained in:
Peter Steinberger
2026-02-15 19:18:02 +00:00
parent a6158873f5
commit c25026f2b3
3 changed files with 39 additions and 24 deletions

View File

@@ -66,7 +66,7 @@ describe("loadOpenClawPlugins", () => {
id: "bundled", id: "bundled",
body: `export default { id: "bundled", register() {} };`, body: `export default { id: "bundled", register() {} };`,
dir: bundledDir, dir: bundledDir,
filename: "bundled.ts", filename: "bundled.js",
}); });
process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir; process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir;
@@ -121,9 +121,9 @@ describe("loadOpenClawPlugins", () => {
outbound: { deliveryMode: "direct" } outbound: { deliveryMode: "direct" }
} }
}); });
} };`, } };`,
dir: bundledDir, dir: bundledDir,
filename: "telegram.ts", filename: "telegram.js",
}); });
process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir; process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir;
@@ -150,7 +150,7 @@ describe("loadOpenClawPlugins", () => {
id: "memory-core", id: "memory-core",
body: `export default { id: "memory-core", kind: "memory", register() {} };`, body: `export default { id: "memory-core", kind: "memory", register() {} };`,
dir: bundledDir, dir: bundledDir,
filename: "memory-core.ts", filename: "memory-core.js",
}); });
process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir; process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir;
@@ -180,7 +180,7 @@ describe("loadOpenClawPlugins", () => {
name: "@openclaw/memory-core", name: "@openclaw/memory-core",
version: "1.2.3", version: "1.2.3",
description: "Memory plugin package", description: "Memory plugin package",
openclaw: { extensions: ["./index.ts"] }, openclaw: { extensions: ["./index.js"] },
}), }),
"utf-8", "utf-8",
); );
@@ -188,7 +188,7 @@ describe("loadOpenClawPlugins", () => {
id: "memory-core", id: "memory-core",
body: `export default { id: "memory-core", kind: "memory", name: "Memory (Core)", register() {} };`, body: `export default { id: "memory-core", kind: "memory", name: "Memory (Core)", register() {} };`,
dir: pluginDir, dir: pluginDir,
filename: "index.ts", filename: "index.js",
}); });
process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir; process.env.OPENCLAW_BUNDLED_PLUGINS_DIR = bundledDir;

View File

@@ -220,22 +220,30 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
}); });
pushDiagnostics(registry.diagnostics, manifestRegistry.diagnostics); pushDiagnostics(registry.diagnostics, manifestRegistry.diagnostics);
const pluginSdkAlias = resolvePluginSdkAlias(); // Lazy: avoid creating the Jiti loader when all plugins are disabled (common in unit tests).
const pluginSdkAccountIdAlias = resolvePluginSdkAccountIdAlias(); let jitiLoader: ReturnType<typeof createJiti> | null = null;
const jiti = createJiti(import.meta.url, { const getJiti = () => {
interopDefault: true, if (jitiLoader) {
extensions: [".ts", ".tsx", ".mts", ".cts", ".mtsx", ".ctsx", ".js", ".mjs", ".cjs", ".json"], return jitiLoader;
...(pluginSdkAlias || pluginSdkAccountIdAlias }
? { const pluginSdkAlias = resolvePluginSdkAlias();
alias: { const pluginSdkAccountIdAlias = resolvePluginSdkAccountIdAlias();
...(pluginSdkAlias ? { "openclaw/plugin-sdk": pluginSdkAlias } : {}), jitiLoader = createJiti(import.meta.url, {
...(pluginSdkAccountIdAlias interopDefault: true,
? { "openclaw/plugin-sdk/account-id": pluginSdkAccountIdAlias } extensions: [".ts", ".tsx", ".mts", ".cts", ".mtsx", ".ctsx", ".js", ".mjs", ".cjs", ".json"],
: {}), ...(pluginSdkAlias || pluginSdkAccountIdAlias
}, ? {
} alias: {
: {}), ...(pluginSdkAlias ? { "openclaw/plugin-sdk": pluginSdkAlias } : {}),
}); ...(pluginSdkAccountIdAlias
? { "openclaw/plugin-sdk/account-id": pluginSdkAccountIdAlias }
: {}),
},
}
: {}),
});
return jitiLoader;
};
const manifestByRoot = new Map( const manifestByRoot = new Map(
manifestRegistry.plugins.map((record) => [record.rootDir, record]), manifestRegistry.plugins.map((record) => [record.rootDir, record]),
@@ -312,7 +320,7 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
let mod: OpenClawPluginModule | null = null; let mod: OpenClawPluginModule | null = null;
try { try {
mod = jiti(candidate.source) as OpenClawPluginModule; mod = getJiti()(candidate.source) as OpenClawPluginModule;
} catch (err) { } catch (err) {
logger.error(`[plugins] ${record.id} failed to load from ${record.source}: ${String(err)}`); logger.error(`[plugins] ${record.id} failed to load from ${record.source}: ${String(err)}`);
record.status = "error"; record.status = "error";

View File

@@ -89,7 +89,14 @@ function buildCacheKey(params: {
plugins: NormalizedPluginsConfig; plugins: NormalizedPluginsConfig;
}): string { }): string {
const workspaceKey = params.workspaceDir ? resolveUserPath(params.workspaceDir) : ""; const workspaceKey = params.workspaceDir ? resolveUserPath(params.workspaceDir) : "";
return `${workspaceKey}::${JSON.stringify(params.plugins)}`; // The manifest registry only depends on where plugins are discovered from (workspace + load paths).
// It does not depend on allow/deny/entries enable-state, so exclude those for higher cache hit rates.
const loadPaths = params.plugins.loadPaths
.map((p) => resolveUserPath(p))
.map((p) => p.trim())
.filter(Boolean)
.toSorted();
return `${workspaceKey}::${JSON.stringify(loadPaths)}`;
} }
function safeStatMtimeMs(filePath: string): number | null { function safeStatMtimeMs(filePath: string): number | null {