win.loadfile() 是唯一能保证相对路径 css 正常工作的加载方式,因其将 html 所在目录设为基准路径;loadurl('file://') 会丢失该上下文导致 404;@import 在 .asar 中静默失败因绕过 electron 解包逻辑;preload.js 注入 css 需用 process.resourcespath 读取并等待 dom 加载。

win.loadFile() 是唯一能保证相对路径 CSS 正常工作的加载方式,其他方案都绕不开它这个前提。
为什么 loadFile() 比 loadURL('file://') 关键
Chromium 解析 ./styles/main.css 依赖 HTML 所在“目录上下文”。win.loadFile('src/index.html') 会把 src/ 设为基准目录;而 loadURL('file://' + path.join(__dirname, 'src', 'index.html')) 会让 Chromium 丢失该上下文,所有相对路径都从根目录开始算,结果就是 404 或空白样式。
开发时检查控制台 Network 面板:如果 main.css 显示 file:///styles/main.css(缺了 src/),说明你误用了 loadURL。
- 打包进
.asar后仍有效——Electron 运行时自动解包并映射相对路径,前提是路径没写成/Users/xxx/app/src/styles/main.css这类绝对路径 - Windows 下路径分隔符不用手动转义:
./styles/main.css在所有平台都生效
@import 在 .asar 中为何静默失败
浏览器原生解析 @import 时,不经过 Electron 的 .asar 解包逻辑,而是直接按字面路径去文件系统找。所以 @import './theme.css'; 在打包后会尝试读取 file:///app.asar/src/styles/theme.css,但实际路径是 app.asar.unpacked/src/styles/theme.css 或已解压到临时目录,导致失败且无报错。
- 避免在 CSS 文件里嵌套
@import,尤其涉及跨目录引用时 - 构建阶段就合并 CSS(如用 PostCSS 或 Webpack 的
css-loader) - 若必须运行时加载,改用 JS 动态创建
<link>标签,并用path.join(app.getAppPath(), 'styles', 'theme.css')构造路径
preload.js 注入 CSS 字符串的实操要点
适合主题切换、暗色模式热更新等运行时控制场景,但不能替代主样式表——体积大了会阻塞渲染,且无法被 DevTools 的 Styles 面板完整追踪。
- 注入前必须等
document.addEventListener('DOMContentLoaded', () => { }),否则document.head可能不存在 - 读取文件要用
fs.readFileSync(path.join(process.resourcesPath, 'styles', 'main.css'), 'utf8').trim(),process.resourcesPath才能正确指向.asar或解包目录 - 不要用
__dirname拼路径:它指向 preload.js 所在目录,不是 HTML 所在目录 - 大体积 CSS 建议用
fs.readFileSync(, 'utf8').trim()清掉 BOM,避免解析失败
最易被忽略的是:主题切换时,nativeTheme.themeSource 只影响系统级 UI(菜单栏、托盘图标等),不会自动触发渲染进程中的 CSS 变更;必须配合类名切换(如 document.documentElement.classList.toggle('dark'))或 CSS 变量重设,否则样式不会响应。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











