制作文章时使用版本: Electron v39.1.2 Electron Builder v26.0.12 Express v5.1.0
在 Electron 应用开发中,很多开发者会选择集成 Express
然而,当使用 electron-builder 打包时,会遇到 ASAR 打包导致 Express 无法正常访问静态资源
更复杂的是,我们面临着两难选择:
将资源打包进 ASAR:导致 Express 无法访问
使用 extraResources:可能泄露敏感源码
这个问题的根源在于 ASAR 是一种特殊的归档格式,虽然能保护源码,但也改变了文件的访问方式
解决方案的核心思路
1. 理解 Electron 的特殊路径解析
Electron 提供了一个关键特性:即使在 ASAR 包内部,Node.js 的 fs 模块仍然可以读取文件。这意味着我们可以通过编程方式手动处理静态资源请求,而不是依赖 Express 的静态中间件。
2. 环境感知的路径策略
聪明的做法是根据运行环境动态调整资源路径:
开发环境:直接使用文件系统路径
生产环境:通过特殊处理访问 ASAR 内部资源
具体实现方案
const express = require('express');
const path = require('path');
const fs = require('fs');
const app= express();
app.use('/public', async (req, res) => {
try {
const relativePath = req.path.replace(/^\//, '');
const filePath = path.join(__dirname, 'public', relativePath);
if (!fs.existsSync(filePath)) {
return res.status(404).send('File not found');
}
if (fs.statSync(filePath).isDirectory()) {
return res.status(403).send('Forbidden');
}
const ext = path.extname(filePath).toLowerCase();
const mimeTypes = {
'.html': 'text/html',
'.js': 'text/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.gif': 'image/gif',
'.svg': 'image/svg+xml'
};
const contentType = mimeTypes[ext] || 'text/html';
res.set('Content-Type', contentType);
const data = fs.readFileSync(filePath);
res.send(data);
} catch (error) {
console.error('Error serving static file:', error);
res.status(500).send("Internal Server Error");
}
});项目结构
project/
├── public/ # 静态资源
│ ├── css/ # 样式文件
│ │ └── style.css # 主样式
│ ├── js/ # JS文件
│ │ └── index.js # 菜单配置
│ └── img/ # 图片
├── main.js # 入口文件
└── package.json # 项目配置