字
字节笔记本
2026年2月22日
Electron + Vue.js 中正确导入 ipcRenderer 的完整指南
本文整理自 Stack Overflow 上的一个热门问题,介绍如何在 Vue.js 项目中正确导入 Electron 的 ipcRenderer,解决 __dirname is not defined 错误。
问题背景
在使用 Vue CLI Plugin Electron Builder 开发 Electron 应用时,开发者经常遇到如何在 Vue 组件中正确使用 ipcRenderer 的问题。特别是在启用 contextIsolation 的安全配置下,直接导入 ipcRenderer 会导致错误。
错误现象
当在 Vue 文件中尝试导入 ipcRenderer 时:
javascript
import { ipcRenderer } from 'electron'可能会遇到以下错误:
__dirname is not definedfs.existsSync is not a function
解决方案
1. 配置 vue.config.js
首先需要在项目根目录的 vue.config.js 中配置 preload 文件路径:
javascript
// vue.config.js
module.exports = {
pluginOptions: {
electronBuilder: {
preload: 'src/preload.js',
// 或者配置多个 preload 文件
// preload: { preload: 'src/preload.js', otherPreload: 'src/preload2.js' }
}
}
}2. 配置 background.js
在 src/background.js 中配置 webPreferences 使用 preload 文件:
javascript
// src/background.js
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
enableRemoteModule: true,
preload: path.join(__dirname, 'preload.js'),
},
})注意:默认情况下 nodeIntegration 是禁用的,contextIsolation 是启用的。
3. 创建 preload.js
在 src 目录下创建 preload.js 文件(注意不是 dist_electron 目录):
javascript
// src/preload.js
import { contextBridge, ipcRenderer } from 'electron'
// 将 ipcRenderer 暴露给客户端
contextBridge.exposeInMainWorld('ipcRenderer', {
send: (channel, data) => {
// 白名单通道
let validChannels = ['nameOfClientChannel']
if (validChannels.includes(channel)) {
ipcRenderer.send(channel, data)
}
},
receive: (channel, func) => {
let validChannels = ['nameOfElectronChannel']
if (validChannels.includes(channel)) {
// 故意剥离 event 对象,因为它包含 sender
ipcRenderer.on(channel, (event, ...args) => func(...args))
}
}
})4. 在 Vue 组件中使用
配置完成后,可以在 Vue 组件中通过 window.ipcRenderer 访问:
vue
// src/App.vue
<template>
<div>
<button @click="test">发送消息</button>
</div>
</template>
<script>
export default {
name: "App",
methods: {
test() {
window.ipcRenderer.send('channel', data)
}
}
}
</script>5. 在主进程中监听
在 background.js 中监听渲染进程发送的消息:
javascript
// background.js
ipcMain.on('channel', (event, args) => {
// 处理消息
})安全注意事项
使用 contextBridge 和 contextIsolation 是 Electron 推荐的安全实践:
- contextIsolation: 防止原型污染攻击
- contextBridge: 安全地将特定的 API 暴露给渲染进程
- 通道白名单: 限制可以使用的 IPC 通道,防止未授权访问
调试技巧
可以在 preload.js 中添加 alert 来验证 preload 脚本是否正常工作:
javascript
alert("Preload 脚本加载成功!") // 确认后删除此行参考资源
分享: