首页
/ Electron 应用在 Windows on Arm 上的构建与分发实战指南

Electron 应用在 Windows on Arm 上的构建与分发实战指南

2026-09-07 16:52:27作者:裴锟轩Denise

本指南面向需要在 ARM64 架构 Windows 设备(如基于骁龙处理器的 Windows 10/11 设备)上运行 Electron 应用的开发者。从 Electron 6.0.8 起即可为 Windows on Arm 构建应用,但需要处理架构判定、原生模块重编译、交叉编译工具链等系列问题。读完本文,你将掌握一套从开发机交叉编译到真机调试的完整 Windows on Arm 构建流程。

前提与适用范围

本文基于当前仓库的 docs/tutorial/windows-arm.md 编写。原文面向 Electron 6.0.x 时期的 Windows on Arm 支持生态,其描述的架构判定问题、原生模块重编译要求、交叉编译方法论以及 Chromium 沙箱行为等核心知识点,在今天依然适用于所有为 ARM64 Windows 打包 Electron 应用的场景。

需要特别说明的是,Windows on Arm 平台(x86_64 应用经模拟运行)在 Electron 时代早期性能损失明显,而原生 ARM64(arm64)二进制无需模拟、直接以原生速度运行,这也是该文档强调"为 arm64 重新编译一切"的根本原因。自 Electron 6.0.8 起即可将应用构建为 Windows 10 on Arm 的原生版本,这能显著改善性能,但代价是:

  • 应用中使用的任何原生 Node 模块都必须重新编译
  • 构建与打包脚本可能需要进行小幅修正(主要是架构判定逻辑);
  • 需要一套与 x86/x64 不同的交叉编译工具链。

运行一个最简应用

如果你的应用不使用任何原生模块,生成 ARM64 版本的过程非常简单,只需三步:

  1. 确保应用目录下的 node_modules 为空(避免沿用旧架构的产物)。
  2. 命令提示符(Command Prompt)中,先执行 set npm_config_arch=arm64,再像往常一样运行 npm install / yarn install
  3. 如果你把 Electron 作为开发依赖安装(参见 tutorial-2-first-app.md 的初始化 npm 项目部分),npm 会据此下载并解压 arm64 版本的 Electron 二进制。之后即可照常打包与分发你的应用。

环境变量生效的底层原理

为什么一个 npm_config_arch=arm64 就能让 npm 下载到正确架构的 Electron?答案在仓库的 npm/install.js 中:

const platform = process.env.ELECTRON_INSTALL_PLATFORM || process.env.npm_config_platform || process.platform;
let arch = process.env.ELECTRON_INSTALL_ARCH || process.env.npm_config_arch || process.arch;

Electron 的 npm 安装脚本(postinstall)在下载预编译二进制时,按以下优先级决定目标架构:

  1. ELECTRON_INSTALL_ARCH 环境变量(最高优先级,支持 electron .npm install 等多种调用方式,详见 docs/api/environment-variables.md);
  2. npm_config_arch(即 npm install --arch=arm64set npm_config_arch=arm64 写入的环境变量);
  3. 当前进程的 process.arch(兜底,即运行 npm 的机器自身架构)。

随后安装脚本调用 downloadArtifact@electron/get)以该 arch 下载对应架构的 zip 包,解压并写入指向 electron.exepath.txt。也就是说:只要让 npm_config_arch(或 ELECTRON_INSTALL_ARCH)等于 arm64,npm 安装 Electron 这一依赖时就会自动拉取 Windows on Arm 的二进制,与应用代码本身无关。

补充:官方支持的目标架构集合可参考 docs/tutorial/installation.md,其中明确列出 arm64 对应 "Apple silicon, Windows on ARM, ARM64 Linux",与本文讨论的 Windows on Arm 场景一致。

通用注意事项

架构相关代码的判定陷阱

大量 Windows 专属代码中存在着在 x64 与 x86 之间二选一的 if...else 逻辑:

if (process.arch === 'x64') {
  // 64 位逻辑...
} else {
  // 32 位逻辑...
}

如果要支持 arm64,这类写法几乎必然命中错误分支:arm64 既不是 x64,也不是"else"里隐含假设的 x86。因此需要仔细排查应用代码与构建脚本中所有类似的条件判断。在自定义构建与打包脚本中,应始终检查环境变量 npm_config_arch,而不是依赖当前运行进程的 process.arch——后者反映的是"脚本正在哪台机器上跑",前者才是"目标产物面向哪种架构"。仓库中真实存在大量基于 process.platform === 'win32' 的分支代码(如 lib/browser/api/auto-updater.tslib/common/init.ts),这提醒开发者:平台与架构判断散落在代码各处的项目,在迁移到 arm64 时必须系统性检索。

原生模块

若使用原生模块,必须确保它们使用 MSVC v142 工具集编译(即 Visual Studio 2017 提供)。同时要逐一核对:原生模块自带或引用的预编译 .dll / .lib 是否提供 Windows on Arm 版本。很多原生模块通过 node-pre-gyp / prebuild 分发预编译产物,若发布者未产出 win32-arm64 的二进制,就需要按后文的交叉编译流程从源码自行编译。

测试你的应用

在真机测试时请注意:

  • 使用运行 Windows 10(1903 或更高版本)的 Windows on Arm 设备
  • 务必将整个应用目录复制到目标设备本地磁盘后再运行。

最后一点很关键:Chromium 的沙箱在从网络位置(UNC 路径、共享目录)加载应用资源时无法正常工作。这与 docs/tutorial/security.md 中反复强调的沙箱工作原理一脉相承——沙箱要求进程与其资源具备本地、可控的访问边界。

开发环境准备

Node.js / node-gyp

官方建议使用 Node.js v12.9.0 或更高版本(该版本起内置了对 ARM64 原生模块编译所需变更的 node-gyp)。如果无法升级 Node,可以手动把 npm 内置的 node-gyp 更新到 5.0.2 或更高版本,该版本同样包含为 Arm 编译原生模块所需的关键改动。

对当前 Electron 源码树而言,仓库以 node-gyp 12.x 作为开发依赖(见 package.json),并在 script/nan-spec-runner.js 等测试脚本中显式向子进程注入 npm_config_arch 环境变量以控制目标架构——这说明通过环境变量把 arch 贯穿到 node-gyp 整个编译链路,正是官方测试自身也在依赖的标准机制。

Visual Studio 2017

交叉编译原生模块需要 Visual Studio 2017(任意版本)。建议通过微软 Visual Studio Dev Essentials 计划获取 Community 2017。安装后,在 命令提示符 中运行以下命令补装 ARM 相关组件:

vs_installer.exe ^
--add Microsoft.VisualStudio.Workload.NativeDesktop ^
--add Microsoft.VisualStudio.Component.VC.ATLMFC ^
--add Microsoft.VisualStudio.Component.VC.Tools.ARM64 ^
--add Microsoft.VisualStudio.Component.VC.MFC.ARM64 ^
--includeRecommended

各参数含义:

组件 ID 用途
Microsoft.VisualStudio.Workload.NativeDesktop 使用 C++ 的桌面开发工作负载(基础编译工具)
Microsoft.VisualStudio.Component.VC.ATLMFC ATL / MFC 运行库(若原生模块依赖 MFC)
Microsoft.VisualStudio.Component.VC.Tools.ARM64 ARM64 目标编译器与工具集(交叉编译的关键)
Microsoft.VisualStudio.Component.VC.MFC.ARM64 面向 ARM64 的 MFC 组件

创建交叉编译命令提示符

这里有一个容易踩坑的细节:设置 npm_config_arch=arm64 确实会让编译器产出正确的 arm64 .obj 文件,但标准的 Developer Command Prompt for VS 2017(开发人员命令提示符)默认使用 x64 链接器,链接阶段仍会失败。解决办法是创建一个专用的交叉编译提示符:

  1. 在开始菜单中找到 x64_x86 Cross Tools Command Prompt for VS 2017 快捷方式,右键选择 打开文件位置,把该快捷方式复制一份到方便的位置。
  2. 右键新快捷方式,选择 属性
  3. 目标(Target)字段末尾的 vcvarsamd64_x86.bat 改为 vcvarsamd64_arm64.bat

启动成功后,提示符会打印类似如下的信息:

**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.9.15
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64_arm64'

最后一行 Environment initialized for: 'x64_arm64' 是判断交叉编译环境是否就绪的关键标志。

若你想直接在 Windows on Arm 设备上开发,则将 目标 字段替换为 vcvarsx86_arm64.bat——这样可借助设备的 x86 模拟(Windows on Arm 的 x86 仿真)完成交叉编译。

链接正确的 node.lib

这是原生模块交叉编译中最常见的"静默失败"点。默认情况下,node-gyp 会解压 Electron 的 node 头文件,并把 x86 与 x64 版 node.lib 下载到 %APPDATA%\..\Local\node-gyp\Cache,但不会下载 arm64 版本(此问题官方已有跟踪修复)。手工补救方法:

  1. 从 Electron 官方 headers 分发地址下载 arm64 版 node.lib(对应目录结构形如 v6.0.9/win-arm64/node.lib)。
  2. 将其移动到 %APPDATA%\..\Local\node-gyp\Cache\6.0.9\arm64\node.lib

其中 6.0.9 需替换为你实际使用的 Electron 版本。node.lib 是原生模块在链接阶段必须导入的"Electron 导出符号表",如果缺失或架构不符,链接器会报出大量未解析外部符号或架构不匹配错误。

交叉编译原生模块

完成上述全部准备后,进入交叉编译环节:

  1. 打开上一节创建的交叉编译命令提示符(注意是改造过的那个,而非普通 VS 提示符);
  2. 执行 set npm_config_arch=arm64
  3. 照常运行 npm install 构建项目。

与交叉编译 x86 模块时的经验一致:如果某些原生模块此前曾为其他架构编译过,可能需要删除 node_modules 强制其重新编译,避免 node-gyp 命中缓存中架构不符的 .obj 产物。该流程与 docs/tutorial/using-native-node-modules.md 中描述的 Electron 原生模块编译规范完全同源——无论是通过 npm_config_target / npm_config_arch / npm_config_disturl 等环境变量驱动 npm 编译,还是用 node-gyp rebuild --target=<版本> --arch=<架构> 手动构建,核心都是让 node-gyp 使用 Electron 的 node 头文件与目标架构工具链完成编译。

调试原生模块

原生模块的调试需要"开发机 + 目标机"两端配合:

  1. 目标设备端:在 命令提示符 中启动你的应用 .exe,并传入 --inspect-brk 参数,让进程在加载任何原生模块之前暂停,等待调试器接入。
  2. 开发机端:启动 Visual Studio 2017。
  3. 选择 调试 > 附加到进程(Debug > Attach to Process...),输入目标设备的 IP 地址与 Visual Studio 远程调试器(Remote Debugger)显示的端口号
  4. 点击 刷新(Refresh),选择要附加的 Electron 进程——具体应附加主进程还是渲染进程,可参考 docs/development/debugging-on-windows.md 中对各进程类型的说明。
  5. 符号配置:确保应用中原生模块的符号能正确加载。在 VS 2017 中进入 调试 > 选项(Debug > Options...),在 调试 > 符号(Debugging > Symbols)下添加存放 .pdb 符号文件的文件夹。
  6. 附加成功后设置所需断点,并使用 Chrome 面向 Node 的远程调试工具(docs/tutorial/debugging-main-process.md)恢复 JavaScript 执行。

疑难排查与获取帮助

如果你在使用本文档过程中遇到问题,或出现"应用在 x86 下正常、一到 arm64 就失败"的情况,可以在仓库的 docs/development/issues.md 中查看提交规范,并在标题中以 "Windows on Arm" 开头提交 issue,便于维护者快速识别分类。

结合仓库中的同类文档(如 docs/development/build-instructions-gn.md),还可以确认一个通用的排查思路:先用 process.arch / npm_config_arch 双重打印确认目标架构是否正确贯穿到编译与打包脚本;再检查 node-gyp 缓存中 node.lib 的架构与版本;最后核对 MSVC 工具集与链接器是否来自交叉编译命令提示符环境。

登录后查看全文
热门项目推荐
相关项目推荐