electron-vue 主进程完全指南:src/main目录结构、webpack 打包与__dirname路径陷阱
【免费下载链接】electron-vueAn Electron & Vue.js quick start boilerplate with vue-cli scaffolding, common Vue plugins, electron-packager/electron-builder, unit/e2e testing, vue-devtools, and webpack.项目地址: https://gitcode.com/gh_mirrors/el/electron-vue
本文基于 docs/ja/main-process.md(主进程章节)编写,讲解 electron-vue 脚手架中主进程(main process)的两大核心文件、开发与生产环境的差异,以及 webpack 打包后
__dirname/__filename不再可靠这一关键坑点,并深入__static静态资源路径变量的底层实现。
Electron 将运行package.json中main字段所指向脚本的进程称为主进程(main process)。主进程内运行的脚本可以通过创建 Web 页面来显示图形界面,它是整个桌面应用的"大脑"。在 electron-vue 这个以 Electron + Vue.js 快速起步的脚手架中,主进程代码被收敛在src/main目录下,全部业务起点都从这里展开。读完本文,你将掌握:src/main/index.js与src/main/index.dev.js各自承担的职责、开发与生产环境下应用启动路径的差异,以及为什么打包后__dirname/__filename会"失灵",以及如何用__static变量安全地访问静态资源。
主进程的本质:一个完整的 Node 环境
根据 docs/ja/main-process.md 的说明,Electron 主进程本质上是一个完整的 Node 环境,因此在初始化时除了以下两个文件之外,并不存在其他预先定义的项目结构:
| 文件 | 作用 | 运行环境 |
|---|---|---|
src/main/index.js | 应用主文件,electron启动的入口,也是生产构建时 webpack 的入口文件 | 开发 + 生产 |
src/main/index.dev.js | 仅在开发阶段加载,用于安装electron-debug与vue-devtools | 仅开发 |
这两个文件在模板仓库中分别对应 template/src/main/index.js 与 template/src/main/index.dev.js,下面逐一拆解。
src/main/index.js:应用的生命周期入口
该文件是应用的启动原点。从 template/src/main/index.js 的源码可以看到,它通过 ES Module 语法从electron中引入app与BrowserWindow,并依次完成以下工作:
import { app, BrowserWindow } from 'electron' let mainWindow const winURL = process.env.NODE_ENV === 'development' ? `http://localhost:9080` : `file://${__dirname}/index.html` function createWindow () { mainWindow = new BrowserWindow({ height: 563, useContentSize: true, width: 1000 }) mainWindow.loadURL(winURL) mainWindow.on('closed', () => { mainWindow = null }) } app.on('ready', createWindow) app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } }) app.on('activate', () => { if (mainWindow === null) { createWindow() } })这段源码展示了主进程的核心调用链,几点值得注意:
- 窗口创建:
createWindow()通过new BrowserWindow({ height: 563, useContentSize: true, width: 1000 })创建窗口,useContentSize: true表示宽高指的是页面内容区域尺寸而非整个窗口外框。 - 加载地址分流:
winURL根据process.env.NODE_ENV决定加载方式——开发环境加载http://localhost:9080(由.electron-vue/dev-runner.js启动的 webpack-dev-server),生产环境则通过file://${__dirname}/index.html直接读取打包产物。 - 生命周期事件:
ready事件触发窗口创建;window-all-closed事件在非 macOS 平台直接退出应用(macOS 遵循惯例保留应用);activate事件在 macOS 上 Dock 图标被点击且窗口为空时重新创建窗口。 {{#if_eq}}模板语法:文件中的{{#if_eq eslintConfig 'standard'}}、{{#isEnabled plugins 'vuex-electron'}}等是vue-cli脚手架(Handlebars 模板)的占位语法,会在vue-cli初始化时根据用户选择的配置(ESLint 规范、插件、打包器等)生成最终代码。例如选择 vuex-electron 插件时会在主进程中import '../renderer/store'。
生产打包的入口地位
在 template/package.json 中,main字段被设置为"./dist/electron/main.js",这正是src/main/index.js经过 webpack 打包后的产物路径,对应脚本:
"pack:main": "cross-env NODE_ENV=production webpack --progress --colors --config .electron-vue/webpack.main.config.js"也就是说:npm run pack:main(或npm run pack)会把src/main/index.js及其依赖编译为dist/electron/main.js,Electron 启动时读取的正是这份编译产物。这直接引出了下文__dirname的行为变化。
src/main/index.dev.js:仅限开发环境的增强入口
template/src/main/index.dev.js 专门用于开发阶段,它做的事情可以用注释原文概括:"This file is used specifically and only for development. It installselectron-debug&vue-devtools."(该文件专门且仅用于开发,负责安装electron-debug与vue-devtools)。
// Install `electron-debug` with `devtron` require('electron-debug')({ showDevTools: true }) // Install `vue-devtools` require('electron').app.on('ready', () => { let installExtension = require('electron-devtools-installer') installExtension.default(installExtension.VUEJS_DEVTOOLS) .then(() => {}) .catch(err => { console.log('Unable to install `vue-devtools`: \n', err) }) }) // Require `main` process to boot app require('./index')这段代码的关键作用有三个:
- 加载
electron-debug:启用开发调试能力,{ showDevTools: true }表示应用启动时自动打开 DevTools;该插件还内联集成了devtron(Electron 专用调试面板)。 - 安装
vue-devtools:通过electron-devtools-installer在app的ready事件中安装 Vue.js 开发者工具扩展,安装失败时仅在控制台打印错误而不阻断启动。 - 引导主进程:最后一行
require('./index')实际加载src/main/index.js,形成"开发入口 → 生产入口"的串联。
按文档建议,此文件一般无需修改,但可以按需扩展开发环境功能(例如注入更多调试工具或 mock 逻辑)。注意模板中的/* eslint-disable */注释表明该文件被有意排除在 ESLint 规范检查之外,以保留require等 CommonJS 写法。
__dirname与__filename:webpack 打包后的路径陷阱
这是主进程文档着重强调的一个坑点:由于main进程代码使用 webpack 打包,在开发环境中可用的__dirname与__filename,在生产环境中不会返回你预期的值。
原因在于 webpack 会把所有模块代码打包进单一的dist/electron/main.js,模块源码的物理路径信息在编译后不复存在,__dirname与__filename会被替换为打包环境下的值。参考 docs/ja/file-tree.md 中描述的生产构建结构,main.js位于dist/electron目录中:
app.asar ├─ dist │ └─ electron │ ├─ static/ │ ├─ index.html │ ├─ main.js │ └─ renderer.js ├─ node_modules/ └─ package.json因此在生产环境中,__dirname的实际值将是dist/electron(在app.asar归档内),而不是源码中src/main的位置。文档给出的建议是:基于"生产环境main.js位于dist/electron文件夹"这一事实,相应地正确使用__dirname与__filename。例如src/main/index.js中生产环境加载页面所用的file://${__dirname}/index.html,正是依赖这一打包后路径才能正确指向dist/electron/index.html。
__static:跨环境访问静态资源的便捷变量
如果你的主进程(或渲染进程)需要定位static/资源目录的完整路径,文档明确指引阅读 docs/ja/using-static-assets.md 中介绍的__static全局变量。
__static的实现在 template/src/main/index.js 的顶部,是主进程最早执行的逻辑之一:
if (process.env.NODE_ENV !== 'development') { global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\') }其工作方式如下:
- 开发环境:由
.electron-vue/dev-runner.js注入__static指向项目根目录的static/目录,与webpack-dev-server的静态服务配置保持一致。 - 生产环境:主进程把
__static设置为path.join(__dirname, '/static'),结合上文"main.js位于dist/electron"的事实,恰好指向dist/electron/static/;replace(/\\/g, '\\\\')是为了兼容 Windows 平台路径分隔符。
实际使用示例(来自 docs/ja/using-static-assets.md,主进程或渲染进程均可使用):
import fs from 'fs' import path from 'path' let fileContents = fs.readFileSync(path.join(__static, '/someFile.txt'), 'utf8') console.log(fileContents) // => "foobar"生产环境的 asar 注意点
文档同时提醒:生产构建默认会把所有文件打包进asar归档(强烈推荐的做法)。因此static/文件夹内的资源只能由 Electron 内部读取;如果需要把资源分发给用户(例如用外部程序打开),必须先把这些文件复制到用户的文档目录或桌面,再通过 Electron 的shell.openItem()API 打开。electron-vue 官方不计划支持通过配置electron-packager/electron-builder将特定文件从asar中"解包"的方案,相关 issue 会被关闭。
小结:主进程开发的四条实践准则
综合 docs/ja/main-process.md 与模板源码,可以把 electron-vue 主进程开发归纳为以下实践准则:
- 所有主进程工作从
src/main/index.js开始:业务逻辑、IPC、窗口管理等都应由此文件或其导入的模块承载。 - 开发专用逻辑放
src/main/index.dev.js:如调试工具、开发者扩展等,生产构建不会包含它。 - 慎用
__dirname/__filename:牢记生产环境打包后它们指向dist/electron目录,路径计算必须基于该事实。 - 访问静态资源优先用
__static:这是 electron-vue 提供的跨环境统一方案,避免手写脆弱的相对路径逻辑。
相关延伸阅读:项目文件结构、静态资源使用、应用打包构建、全局配置。
【免费下载链接】electron-vueAn Electron & Vue.js quick start boilerplate with vue-cli scaffolding, common Vue plugins, electron-packager/electron-builder, unit/e2e testing, vue-devtools, and webpack.项目地址: https://gitcode.com/gh_mirrors/el/electron-vue
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考