skip to content

Electron
Electron Builder 构建配置问题

问题背景

在尝试调整 electron-builder 的打包配置以包含特定的 node_modules 目录时,出现了构建失败或关键文件(如入口文件 out/main/index.js)丢失的问题。

原始需求

在打包时,需要强制包含某些被排除规则覆盖的 node_modules 路径:

  • resources/packages/pkg-x/libs/core/node_modules
  • 等其他平台的对应目录。

报错现象

构建过程中报错,提示无法找到应用程序入口文件:

Error: Application entry file "out/main/index.js" in the ".../app.asar" is corrupted: Error: "out/main/index.js" was not found in this archive

根因分析

该问题由 electron-builderfiles 字段的解析规则引起。

规则核心机制

electron-builder 使用 Glob 模式匹配来决定哪些文件会被打包到 ASAR 中。其核心逻辑如下:

  1. 隐式全包含(Implicit Include All): 如果 files 数组中所有规则都以 !(排除)开头,electron-builder 会默认假设你希望包含项目根目录下的所有文件,即隐式地在数组头部添加 "**/*"

  2. 显式包含覆盖(Explicit Include Override): 一旦 files 数组中出现任何一条! 开头的规则(即显式包含规则),上述的“隐式全包含”行为立即失效。此时,electron-builder 变为白名单模式:只有被显式匹配的文件,以及未被排除的文件才会被打包。

问题复盘

  1. 修改前:配置仅包含排除规则(如 !src, !scripts 等)。系统默认行为是 ['**/*', '!src', ...]。构建正常。
  2. 修改后:我们在配置末尾添加了显式包含规则(如 resources/.../node_modules/**/*)。
  3. 后果:由于出现了显式包含规则,隐式的 **/* 被移除。系统只打包了我们显式列出的 node_modules,而忽略了项目根目录下的其他文件(包括 package.json 和构建输出目录 out/),导致构建失败。

解决方案

通过在配置数组的最前面显式添加 "**/*",手动恢复“包含所有文件”的基准行为,然后再利用规则的顺序性进行精细控制。

修复后的代码结构

const platformSpecificFiles = {
  windows: [
    '**/*',                                             // 1. 基准:显式声明包含所有文件
    '!resources/packages/*/{linux,darwin}/**/*',        // 2. 排除:排除不属于当前平台的资源
    'resources/packages/pkg-x/**/node_modules/**/*'    // 3. 捞回:强制包含特定路径下的 node_modules
  ],
  // mac 和 linux 配置同理...
};

关键点解析

  • 顺序至关重要electron-builder 按顺序处理规则。
    • **/* 把所有东西加进来。
    • !resources/... 把不需要的大文件夹剔除。
    • 最后 resources/.../node_modules/**/* 把刚才被剔除文件夹里的一小部分内容“捞回来”。

最佳实践 (Best Practices)

在配置 electron-builderfiles 字段时,建议遵循以下原则以避免此类问题:

  1. 始终以 "**/*" 起手: 除非你非常确定只想打包极少数特定文件,否则总是显式写上 "**/*"。这能防止因添加一条包含规则而意外丢失整个项目上下文。

  2. 利用“排除-再包含”模式: 当需要保留某个大目录下的小部分文件时,不要试图写复杂的排除正则。

    • ✅ 推荐:先排除整个大目录 !dir/**/*,再在后面添加需要保留的文件 dir/keep-me
    • ❌ 不推荐:试图用 Glob 的反向否定语法(难以维护且易错)。
  3. Glob 模式技巧

    • 使用 ** 匹配任意层级的子目录。
    • 使用 {a,b} 匹配多个选项。