You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

设置moduleResolution: nodeNext致Chrome扩展右键菜单消失求助

问题原因分析

你遇到的核心矛盾是:Chrome扩展的背景脚本运行在浏览器环境而非Node.js环境,无法兼容NodeNext模块系统生成的代码。调整tsconfig解决了deepl-node的导入报错,但导致背景脚本无法被Chrome正常加载执行,右键菜单自然不会被创建。

另外,deepl-node是专门为Node.js设计的SDK,依赖Node.js内置模块(如http/https),本身就无法在浏览器/Chrome扩展环境中运行,这是你后续即使解决模块问题也会遇到的隐藏坑。


解决方案

1. 恢复tsconfig配置(适配Chrome扩展环境)

把module和moduleResolution改回Chrome扩展支持的配置,保留严格类型检查:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "strict": true,
    "outDir": "dist"
  },
  "include": ["public/background.ts"]
}

2. 替换deepl-node为DeepL REST API直接调用

因为deepl-node不支持浏览器环境,改用DeepL官方REST API通过fetch直接请求:

const authKey = "censored"; // 后续建议用Chrome扩展存储管理密钥,避免硬编码
const DEEPL_API_URL = "https://api-free.deepl.com/v2/translate"; // 付费版替换为api.deepl.com

async function translate(textToTranslate: string): Promise<string> {
  const response = await fetch(DEEPL_API_URL, {
    method: "POST",
    headers: {
      "Authorization": `DeepL-Auth-Key ${authKey}`,
      "Content-Type": "application/x-www-form-urlencoded"
    },
    body: new URLSearchParams({
      text: textToTranslate,
      target_lang: "ES" // 目标语言需大写
    })
  });

  const data = await response.json();
  return data.translations[0].text;
}

3. 修复右键菜单点击后的异步逻辑

原代码中翻译是异步操作,直接返回Promise会导致发送消息时拿到的不是翻译结果,调整onClicked监听逻辑:

chrome.contextMenus.create({
  id: "1",
  title: "Translate \"%s\"",
  contexts: ["selection"],
});

console.log("Context menus created yo!");

chrome.contextMenus.onClicked.addListener(async (info, tab) => {
  if (info.menuItemId === "1") {
    const toTranslate = info.selectionText;
    if (!toTranslate) return;

    try {
      const translatedText = await translate(toTranslate);
      // 创建新标签并直接记录ID,无需额外监听tab创建事件
      const newTab = await chrome.tabs.create({
        url: chrome.runtime.getURL("index.html"),
        active: true,
      });

      // 等待标签加载完成后发送消息
      const waitForTabLoad = setInterval(async () => {
        const tabStatus = await chrome.tabs.get(newTab.id!);
        if (tabStatus.status === "complete") {
          chrome.tabs.sendMessage(newTab.id!, { 
            action: "updateTranslation", 
            text: translatedText 
          }, () => {
            console.log("Message sent!");
          });
          clearInterval(waitForTabLoad);
        }
      }, 100);
    } catch (error) {
      console.error("Translation failed:", error);
      // 可在此添加错误提示逻辑
    }
  }
});

4. 额外注意事项

  • 不要把API密钥硬编码在代码里,后续用chrome.storage.local存储密钥更安全。
  • 若使用DeepL付费版,需将API地址替换为https://api.deepl.com/v2/translate。
  • 确保manifest.json中声明了contextMenus权限,且背景脚本路径指向编译后的文件(如dist/background.js)。

内容的提问来源于stack exchange,提问作者jacob040

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:33:17