我正在尝试构建一个 vue 3 应用程序,使用 vite 编译并使用 Electron 打包,无需任何插件。这是我到目前为止所拥有的:
文件夹结构:
Project
|
+-- electron
| |
| +-- main.js
| +-- preload.js
|
+-- src
| |
| +-- main.js
| +-- App.vue
|
+-- package.json
|
+-- vite.config.js
电子/main.js
import { app, BrowserWindow } from "electron";
import path from "path"
const __dirname = path.resolve();
const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
contextIsolation: true,
enableRemoteModule: false,
preload: path.join(app.getAppPath(), 'preload.js'),
},
});
if (app.isPackaged) {
try {
mainWindow.loadFile('app://./index.html').catch(e => console.log(e));
}
catch (e) {
console.log(e);
}
}
else {
mainWindow.loadURL('http://localhost:3000');
}
};
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
app.whenReady().then(createWindow);
预加载.js
window.addEventListener('DOMContentLoaded', () => {
console.log('Preload script loaded');
});
src/main.js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
createApp(App).mount('#app')
package.json
{
"name": "testme",
"version": "0.0.1",
"description": "demo app",
"scripts": {
"dev": "vite",
"build": "vite build",
"electron:start": "electron electron/main.js",
"start": "vite & electron electron/main.js",
"buildElectron": "npx electron-builder build --mac"
},
"dependencies": {
"vue": "^3.5.10"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.4",
"electron": "^33.0.0-beta.8",
"electron-builder": "^25.1.7",
"vite": "^5.4.8"
},
"main": "electron/main.js",
"type": "module",
"build": {
"appId": "com.ex.me",
"productName": "TEST 1",
"files": [
"dist/**/*",
"electron/**/*",
"preload.js"
],
"directories": {
"buildResources": "assets"
},
"mac": {
"target": [
{
"target": "zip",
"arch": ["x64"]
}
]
}
}
}
vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path';
export default defineConfig({
plugins: [vue()],
base: './',
server: {
port: 3000,
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
build: {
outDir: 'dist',
sourcemap: true,
rollupOptions: {
input: {
main: 'src/main.js',
preload: './electron/preload.js',
},
external: ['electron'],
},
},
});
当我运行 npm start 时,该应用程序可以完美运行。换句话说,vite & electro electro/main.js 工作得很好。但是当我运行 buildElectron 时,它成功构建了应用程序,但我收到两个错误:
看来 __dirname 可能引起了一些问题?由于找不到 preload.js。打包时查找或打开 index.html 似乎存在问题。有人知道如何调试这个吗?我尝试了很多组合来尝试使预加载可见,但没有成功。
您在 Electron 构建过程中遇到的问题源于打包应用程序时如何处理路径,特别是关于
preload.js
和 index.html
文件。在打包的 Electron 应用程序中,像 preload.js
和 index.html
这样的文件被捆绑到 app.asar
存档中,并且使用 __dirname
(指向构建环境)访问它们不再像开发期间那样工作。
以下是解决这两个问题的方法:
preload.js
文件的问题可能是由于您在打包环境中解析其路径的方式造成的。打包时,__dirname
并不指向与开发时相同的位置。您需要调整生产版本的路径分辨率。
修改您的
electron/main.js
以根据应用程序是打包还是正在开发来以不同方式处理此问题:
import { app, BrowserWindow } from "electron";
import path from "path";
import fs from "fs";
const isDevelopment = !app.isPackaged;
const createWindow = () => {
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
contextIsolation: true,
enableRemoteModule: false,
preload: isDevelopment
? path.join(__dirname, '../electron/preload.js') // in development
: path.join(app.getAppPath(), 'electron', 'preload.js'), // when packaged
},
});
if (isDevelopment) {
mainWindow.loadURL('http://localhost:3000');
} else {
mainWindow.loadFile(path.join(app.getAppPath(), 'dist', 'index.html'));
}
};
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit();
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createWindow();
});
app.whenReady().then(createWindow);
Electron 打包应用程序时,需要确保使用正确的路径来加载
index.html
文件。在生产中,index.html
通常捆绑在 dist
文件夹中。您的 main.js
应使用 mainWindow.loadFile
而不是 loadURL
来加载它。
更改打包时处理加载 HTML 文件的代码:
if (isDevelopment) {
mainWindow.loadURL('http://localhost:3000');
} else {
mainWindow.loadFile(path.join(app.getAppPath(), 'dist', 'index.html')); // load from packaged app
}
在您的
package.json
构建配置中,确保包含必要的文件,尤其是 preload.js
和 index.html
。您可能需要调整 files
字段以包含适当的路径:
"files": [
"dist/**/*", // include all built Vue files
"electron/**/*", // include the Electron-related files
"preload.js" // ensure preload.js is included
],
您还可以在构建后使用
preload.js
等工具检查 app.asar
内容来确认 app.asar
和其他文件是否已正确复制到 asar
。
确保 Vite 在打包时正确配置为为应用程序提供服务。将
base
中的 vite.config.js
选项设置为 ./
,这可确保使用相对路径:
export default defineConfig({
plugins: [vue()],
base: './', // Ensure relative paths are used for production build
...
});
要调试打包的 Electron 应用程序,您可以在
mainWindow.webContents.openDevTools()
函数中临时设置 createWindow
。这将帮助您直接在打包环境中检查问题。
通过这些更改,您的预加载脚本应该正确加载,并且打包应用程序时应该正确找到
index.html
文件。