最简可靠方案是用 win.loadFile() 加载 HTML 并保持相对路径,需满足:HTML 与 CSS 物理位置匹配、主进程调用 win.loadFile('src/index.html')、打包时避免硬编码绝对路径;@import 在 .asar 中静默失效。

直接用 <link rel="stylesheet" href="./styles/main.css"> 就行,前提是 HTML 和 CSS 在文件系统里位置关系与路径一致,且主进程用 win.loadFile() 加载 HTML——其他方式要么失效,要么埋坑。
为什么相对路径能直接用,而 file:// 绝对路径常失败
Chromium 对 file:// 协议的拦截主要针对跨目录访问(比如从 file:///app/index.html 去请求 file:///styles/main.css),但对同项目树内解析的相对路径(如 ./styles/main.css)不触发跨域或协议级限制,走的是原生文件读取流程。
- 用
win.loadURL('file://' + path.join(...))会丢失当前目录上下文,./不再指向 HTML 所在目录,路径立刻解析失败 - 打包进
.asar后,Electron 会自动解包并映射相对路径,只要没硬编码绝对路径就仍然有效 -
@import './theme.css'在.asar中静默失败——浏览器执行@import时无法穿透 asar 包,路径解析直接跳过
必须满足的三个条件
缺一不可,否则看似能跑,上线或打包后大概率出问题:
- HTML 文件物理位置与
href中的路径严格匹配(例如index.html在src/下,CSS 在src/styles/main.css,就写./styles/main.css) - 主进程调用
win.loadFile('src/index.html'),不是loadURL - 构建或打包脚本中未将路径写死为绝对路径(如
path.resolve(__dirname, '...')或硬编码C:\...)
preload.js 注入本地 CSS 的适用场景和坑点
这不是常规引入方式,只适合小量运行时控制(比如主题切换、夜间模式开关),不能替代主样式表。
立即学习“前端免费学习笔记(深入)”;
- 路径必须用
path.join(__dirname, '../styles/main.css')——注意__dirname是preload.js所在目录,不是 HTML 所在目录 - 打包后
__dirname指向 asar 外层,读不到内部文件,得换成process.resourcesPath或app.getAppPath() - 注入必须等
document.addEventListener('DOMContentLoaded', ...),不能在 preload 脚本顶部执行 - 大文件建议用
fs.readFileSync(..., 'utf8').trim()清掉 BOM,否则 CSS 解析可能出错
最易被忽略的是 @import 在 asar 中完全失效这点——它不报错、不警告、也不加载,你改了 CSS 却看不到效果,往往以为是缓存或逻辑问题,实际是路径根本没走通。


















