32. Claude code opus还是厉害,尝试修复微博龙虾助手插件在龙虾3.24版本不兼容的问题。微信也遇到了,对标微信解决方案。应该明天技术同学也会把微博的插件更新一下。# 微博龙虾助手插件 Windows ESM 加载器问题修复文档## 问题描述在 Windows 系统上,微博龙虾助手插件启动时报错:```Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'```错误导致插件不断重启失败:```22:05:12+08:00 [weibo] [default] auto-restart attempt 5/10 in 87s22:06:39+08:00 [weibo] [default] channel exited: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader...```## 问题根因Node.js ESM 模块在 Windows 上进行**动态导入** `import()` 时,需要使用 `file://` URL 格式,而不能直接使用 Windows 绝对路径(如 `C:\...`)。微博插件中使用了动态导入:```javascriptconst { monitorWeiboProvider } = await import("./monitor.js");```当 OpenClaw 在 Windows 上加载插件时,相对路径会被解析为 Windows 绝对路径,导致 ESM 加载器报错。## 解决方案参考微信插件(`openclaw-weixin`)的实现方式,将所有**动态导入**改为**静态导入**。微信插件使用静态导入,在 Windows 上运行正常:```typescriptimport { monitorWeixinProvider } from "./monitor/monitor.js";```## 修改的文件### 1. `src/channel.js`**修改内容:**- 移除动态导入 `await import("./monitor.js")`- 添加静态导入 `import { monitorWeiboProvider } from "./monitor.js"`- 移除不再需要的路径处理辅助代码**修改前:**```javascriptimport { resolveWeiboAccount, listWeiboAccountIds, resolveDefaultWeiboAccountId, } from "./accounts.js";import { weiboOutbound } from "./outbound.js";import { normalizeWeiboTarget, looksLikeWeiboId } from "./targets.js";import { sendMessageWeibo } from "./send.js";// ... 在 gateway.startAccount 中使用动态导入gateway: { startAccount: async (ctx) => { const { monitorWeiboProvider } = await import("./monitor.js"); ctx.setStatus({...}); return monitorWeiboProvider({...}); }}```**修改后:**```javascriptimport { resolveWeiboAccount, listWeiboAccountIds, resolveDefaultWeiboAccountId, } from "./accounts.js";import { weiboOutbound } from "./outbound.js";import { normalizeWeiboTarget, looksLikeWeiboId } from "./targets.js";import { sendMessageWeibo } from "./send.js";import { monitorWeiboProvider } from "./monitor.js"; // ✅ 改为静态导入// ... 在 gateway.startAccount 中直接使用gateway: { startAccount: async (ctx) => { ctx.setStatus({...}); return monitorWeiboProvider({...}); // ✅ 直接使用 }}```### 2. `src/bot.js`**修改内容:**- 移除动态导入 `await import("./send.js")`- 添加静态导入 `import { generateWeiboMessageId, sendMessageWeibo } from "./send.js"`- 移除不再需要的路径处理辅助代码**修改前:**```javascriptimport { createHash } from "node:crypto";import { pathToFileURL, fileURLToPath } from "url";import { dirname, join, isAbsolute } from "path";import { resolveWeiboAccount } from "./accounts.js";// ...// 复杂的路径处理逻辑function getDirname(metaUrl) {...}const __dirname = getDirname(import.meta.url);const toFileUrl = (relativePath) => pathToFileURL(join(__dirname, relativePath)).href;// 在函数内部使用动态导入const { generateWeiboMessageId } = await import(toFileUrl("./send.js"));const { sendMessageWeibo } = await import(toFileUrl("./send.js"));```**修改后:**```javascriptimport { createHash } from "node:crypto";import { resolveWeiboAccount } from "./accounts.js";// ...import { generateWeiboMessageId, sendMessageWeibo } from "./send.js"; // ✅ 改为静态导入// ✅ 直接使用静态导入的函数currentOutboundMessageId = generateWeiboMessageId();await sendMessageWeibo({...});```### 3. `src/client.js`**修改内容:**- 简化 `createRequire` 的使用方式- 移除不再需要的路径处理辅助代码**修改前:**```javascriptimport { createRequire } from "module";import { pathToFileURL, fileURLToPath } from "url";import { dirname, join, isAbsolute } from "path";import WebSocket from "ws";// 复杂的路径处理逻辑function getDirname(metaUrl) { if (metaUrl.startsWith("file:")) { return dirname(fileURLToPath(metaUrl)); } if (isAbsolute(metaUrl)) { return dirname(metaUrl); } // ...}const __dirname = getDirname(import.meta.url);const require = createRequire(pathToFileURL(join(__dirname, "dummy.js")).href);```**修改后:**```javascriptimport { createRequire } from "module";import WebSocket from "ws";// ✅ 简化为标准用法const require = createRequire(import.meta.url);```## 关键经验总结1. **避免动态导入**:在 ESM 模块中,尽量使用静态导入而不是动态导入 `import()`,特别是在跨平台场景下2. **参考成功案例**:微信插件使用静态导入,在 Windows 上运行正常,可以作为参考3. **`createRequire` 的正确用法**:直接使用 `createRequire(import.meta.url)` 即可,Node.js 会正确处理路径4. **Windows 路径问题**:Windows 使用反斜杠 `\` 作为路径分隔符,且驱动器号(如 `C:`)会被误认为 URL 协议## 验证结果修复后,插件在 Windows 上正常启动:```22:32:48+08:00 [plugins] weibo_token: Registered weibo_token tool22:32:48+08:00 [plugins] weibo_search: Registered weibo_search tool22:32:48+08:00 [plugins] weibo_status: Registered weibo_status tool22:32:48+08:00 [plugins] weibo_hot_search: Registered weibo_hot_search tool22:32:48+08:00 [plugins] weibo-openclaw-plugin: loaded```