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

Electron+TypeScript应用中contextBridge调用auth方法报Uncaught ReferenceError

Electron + TypeScript 按钮调用后台方法报错解决

核心问题原因

Uncaught ReferenceError 本质是渲染进程无法直接访问主进程模块/方法,Electron默认开启上下文隔离(contextIsolation),渲染进程运行在独立沙箱环境,不能直接调用Node.js模块或主进程自定义代码。TypeScript编译不报错是因为编译阶段仅做类型检查,不验证Electron的进程上下文限制。

具体解决步骤

1. 配置IPC通信(主进程侧)

假设auth模块属于主进程代码,需在主进程中注册IPC监听,暴露可被渲染进程调用的方法:

// src/main/main.ts
import { app, BrowserWindow, ipcMain } from 'electron';
import { login } from './auth'; // 引入auth模块的目标方法

let mainWindow: BrowserWindow | null;

function createWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: `${__dirname}/preload.js`, // 必须配置预加载脚本路径
      contextIsolation: true, // 保持默认开启,保障安全性
      nodeIntegration: false // 保持默认关闭,避免安全风险
    }
  });

  mainWindow.loadFile('index.html');

  // 注册IPC监听,处理渲染进程的登录请求
  ipcMain.handle('auth:login', async (_, username, password) => {
    try {
      const result = await login(username, password);
      return { success: true, data: result };
    } catch (err) {
      return { success: false, error: (err as Error).message };
    }
  });
}

app.whenReady().then(createWindow);

2. 编写预加载脚本(搭建通信桥梁)

预加载脚本运行在渲染进程上下文,但可访问Electron的IPC API,用于在渲染进程和主进程间建立安全通信通道:

// src/preload.ts
import { contextBridge, ipcRenderer } from 'electron';

// 通过contextBridge向渲染进程暴露安全API
contextBridge.exposeInMainWorld('electronAPI', {
  login: (username: string, password: string) => 
    ipcRenderer.invoke('auth:login', username, password)
});

3. 渲染进程调用暴露的API

在渲染进程的按钮点击事件中,调用预加载脚本暴露的electronAPI,而非直接引用auth模块:

// src/renderer/renderer.ts
const loginBtn = document.getElementById('login-btn');
const usernameInput = document.getElementById('username') as HTMLInputElement;
const passwordInput = document.getElementById('password') as HTMLInputElement;

loginBtn?.addEventListener('click', async () => {
  const username = usernameInput.value;
  const password = passwordInput.value;
  
  try {
    // 调用预加载脚本暴露的登录方法
    const result = await window.electronAPI.login(username, password);
    if (result.success) {
      console.log('登录成功:', result.data);
      // 处理登录成功逻辑
    } else {
      console.error('登录失败:', result.error);
    }
  } catch (err) {
    console.error('调用登录接口出错:', err);
  }
});

4. 补充TypeScript类型声明

在渲染进程的类型声明文件中添加electronAPI的类型,让TypeScript识别全局对象:

// src/renderer/types/electron-api.d.ts
declare global {
  interface Window {
    electronAPI: {
      login: (username: string, password: string) => Promise<{
        success: boolean;
        data?: any;
        error?: string;
      }>;
    };
  }
}

export {};

5. 验证编译配置

确保tsconfig.json正确配置编译选项,比如预加载脚本的编译目标:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "CommonJS",
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

关键注意事项

  • 禁止开启nodeIntegration: true或关闭contextIsolation,这会引入严重安全风险。
  • 渲染进程与主进程的所有通信必须通过contextBridge和IPC实现,不能直接跨进程引用模块。
  • 编译后需确认预加载脚本路径正确,主进程中配置的preload需指向编译后的preload.js文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 09:05:14