1. 项目缘起与整体思路拆解
1.1 为什么会碰到这个组合
国产化替代的大背景下,越来越多的项目需要跑在银河麒麟V10系统上,而龙芯架构又是其中比较特殊的一支。我手头有个桌面端工具类项目,原本在x86的Windows和Linux上都跑得好好的,技术栈选的是Electron,原因很简单:前端那套东西复用率高,UI迭代快,跨平台打包也省心。结果迁移任务下来,要求必须适配银河麒麟V10加龙芯平台,这一下就撞上了硬骨头。
Electron官方预编译的二进制包,默认只覆盖Windows、macOS、Linux的x64和arm64,龙芯这种LoongArch或者早期MIPS系架构,压根不在官方分发列表里。你直接npm install electron,它去下载对应平台的zip包,大概率是404或者下到一个架构不匹配的二进制,运行起来直接报Exec format error。这不是配置问题,是根本没有现成的轮子。
所以这个项目的核心目标就一句话:在银河麒麟V10的龙芯机器上,让Electron应用能正常启动、渲染、打包。听起来简单,但中间涉及系统包管理、Node运行时、Electron二进制重编译、打包工具链适配等一连串环节,每一环都可能卡住。
1.2 整体方案选型与取舍
面对这种“官方不支持”的局面,通常有三条路可走。
第一条是源码编译Electron。从Chromium到Node再到Electron壳,整个编译链条极其庞大,对机器性能和磁盘空间要求很高,编译一次动辄几个小时甚至更久,而且龙芯平台的编译工具链、依赖库版本都得对齐,踩坑成本极高。除非你是要做发行版级别的维护,否则不推荐。
第二条是寻找社区或第三方预编译的龙芯版Electron二进制。这是最省事的路径,前提是能找到可信来源、版本匹配的包。很多国产化适配社区会维护这类产物,但版本往往滞后,需要你迁就它的Electron版本去调整项目依赖。
第三条是换思路,用系统自带或可安装的Node运行时配合轻量壳。比如放弃Electron,改用系统WebView加本地服务的方式。但这会推翻原有技术栈,改动量大,不到万不得已不走。
我最终选的是第二条为主、第一条为辅的策略:优先找匹配的预编译二进制,找不到就针对特定版本做最小化编译。这样能在可控时间内把项目跑起来,后续再考虑长期维护方案。
提示:选型时一定要先确认目标机器的具体架构标识,是loongarch64还是mips64el,这直接决定你找哪个包。很多人卡在这一步,拿错架构的包折腾半天。
1.3 适用人群与前置知识
这篇内容适合几类人:一是正在做国产化迁移、需要把Electron应用搬到麒麟系统的开发者;二是对Node原生模块编译、跨架构打包有兴趣的技术人员;三是运维或实施人员,需要在一线把环境搭起来。
前置知识方面,你至少得熟悉Linux基本命令、npm的安装机制、Node的版本管理,最好了解一点交叉编译和动态链接库的概念。如果这些都不熟,建议先补一下基础,否则后面每一步都会很吃力。
整个流程我会按“环境确认→运行时准备→Electron二进制处理→项目适配→打包验证”的顺序来讲,每一步都给出我实际操作的命令和判断依据,你可以直接对照着做。
2. 环境确认与基础依赖准备
2.1 确认系统版本与CPU架构
动手之前,先把机器的底细摸清楚。打开终端,执行几条命令。
cat /etc/kylin-release uname -m uname -a/etc/kylin-release会告诉你具体的麒麟版本,比如V10 SP1还是SP2,不同小版本的系统库有差异。uname -m是关键,输出可能是loongarch64、mips64el或者mips64。我这次遇到的是龙芯3A5000,系统识别为loongarch64,但项目标题里写的是mips,这里要说明一下:龙芯早期产品线确实有MIPS架构,后来转向自研的LoongArch。你实际拿到的机器是哪种,以uname -m为准,不要想当然。
同时确认一下系统的glibc版本:
ldd --version这个信息很重要,因为Electron二进制对glibc版本有最低要求。如果系统glibc太老,即使二进制架构对了,也可能跑不起来。
2.2 安装系统级依赖库
Electron本质上是Chromium加Node,运行时依赖大量系统库。麒麟V10默认安装可能缺一些,需要手动补。用系统包管理器安装,麒麟基于Debian系的话用apt,基于RPM系的话用yum或dnf。
sudo apt update sudo apt install -y libnss3 libatk1.0-0 libatk-bridge2.0-0 \ libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 \ libxfixes3 libxrandr2 libgbm1 libasound2 libpango-1.0-0 \ libcairo2 libgtk-3-0 libgdk-pixbuf2.0-0这些库覆盖了Electron渲染窗口、图形加速、音频、输入法等核心功能。少一个都可能导致启动时报error while loading shared libraries。
注意:麒麟系统的软件源里包名可能和标准Debian略有出入,如果某个包找不到,用
apt search搜一下关键词,找功能相近的替代包。不要跳过缺失的库,否则后面排查起来很痛苦。
2.3 Node运行时的选择与安装
Electron项目开发离不开Node和npm。麒麟系统自带的Node版本往往偏旧,建议自己装一个较新的LTS版本。但这里有个坑:Node官方预编译包同样不覆盖龙芯架构,你得找对应架构的Node二进制,或者用系统源里的版本。
先看看系统自带的:
node -v npm -v如果版本在14以上,基本够用。如果太低,去Node的官方分发页面找linux-loongarch64或对应架构的包。实在找不到,可以用系统源安装:
sudo apt install -y nodejs npm装完后确认npm能正常工作。有时候npm的registry访问慢,可以换成国内镜像源加速,这个大家都熟,不展开。
2.4 确认Electron版本策略
在动手装Electron之前,先定版本。原则是:优先选社区已有龙芯适配产物的Electron版本,而不是盲目追新。我当时的做法是,先去几个国产化适配社区和代码托管平台搜“electron loongarch”或“electron 麒麟”相关的仓库,看他们维护到了哪个版本。假设找到的是Electron 13或15的适配包,那项目里的Electron依赖就锁到对应大版本。
在package.json里这样写:
{ "devDependencies": { "electron": "15.3.0" } }版本号要精确,不要用^,避免npm自动升级到没有适配包的版本。
3. Electron二进制获取与替换实操
3.1 理解npm安装Electron的机制
很多人以为npm install electron是把整个Electron装下来,其实不是。npm装的是一个叫electron的npm包,它只是个下载器加壳。安装过程中会执行一个postinstall脚本,根据当前平台去下载对应的Electron二进制zip包,解压到node_modules/electron/dist目录。真正运行的是那个dist里的可执行文件。
所以问题的核心在于:postinstall下载不到龙芯架构的包。我们要做的就是绕过这个下载,手动把正确的二进制放进去。
3.2 跳过自动下载
设置环境变量,让安装时跳过二进制下载:
export ELECTRON_SKIP_BINARY_DOWNLOAD=1 npm install这样npm只装JS层的包,不会去拉二进制。装完后node_modules/electron/dist是空的或者不存在,没关系,我们手动补。
3.3 获取龙芯版Electron二进制
这一步是整个流程的关键。来源有几个方向:国产化适配社区维护的仓库、系统厂商提供的软件源、或者自己编译。我这次是从一个适配仓库拿到了对应版本的二进制压缩包,解压后是一堆文件,核心是可执行文件electron和一堆.so、.pak、.bin资源。
拿到后,把它放到node_modules/electron/dist目录下:
mkdir -p node_modules/electron/dist cp -r /path/to/electron-loongarch64/* node_modules/electron/dist/ chmod +x node_modules/electron/dist/electron然后验证一下这个二进制能不能跑:
./node_modules/electron/dist/electron --version如果输出了版本号,说明二进制本身没问题。如果报cannot execute binary file,那就是架构不对;如果报缺库,回到2.2节补依赖。
3.4 修正path.txt
Electron的npm包通过一个path.txt文件记录可执行文件的相对路径。检查node_modules/electron/path.txt,内容应该是electron。如果不是,手动改过来。这个文件决定了require('electron')时去哪里找可执行文件。
3.5 验证Electron能否启动
写一个最小的测试脚本:
const { app, BrowserWindow } = require('electron') app.whenReady().then(() => { const win = new BrowserWindow({ width: 800, height: 600 }) win.loadURL('data:text/html,<h1>Hello Kylin</h1>') }) app.on('window-all-closed', () => { app.quit() })用npx electron test.js运行。如果弹出一个窗口显示Hello Kylin,恭喜你,最难的坎过去了。如果窗口没出来但进程没报错,可能是显示环境的问题,检查DISPLAY变量是否设置,或者是不是在纯命令行环境下跑。
实操心得:我第一次跑的时候窗口一闪就没了,后来发现是GPU加速在龙芯的显卡驱动上不兼容。加
--disable-gpu参数后正常。这个参数在调试阶段很有用,正式打包时再根据目标机器的显卡情况决定是否保留。
4. 项目适配与常见兼容性问题处理
4.1 原生模块的重编译
Electron项目里如果用了原生模块,比如sqlite3、serialport、node-ffi这类,它们是用C++写的,需要针对Electron的ABI和龙芯架构重新编译。npm默认装的是x64的预编译版本,在龙芯上直接报错。
处理方式是强制从源码编译:
npm rebuild --runtime=electron --target=15.3.0 --arch=loongarch64 --dist-url=https://electronjs.org/headers--target填你的Electron版本,--arch填目标架构。--dist-url指向Electron的headers下载地址,编译原生模块需要这些头文件。如果网络访问不了,可以找离线的headers包,用--dist-url指向本地目录。
编译过程中如果报缺node-gyp或者Python,先装:
sudo apt install -y python3 make g++ npm install -g node-gyp4.2 打包工具electron-builder的适配
开发阶段跑通了,接下来要打包成可分发的安装包。electron-builder是常用工具,但它默认会去下载对应平台的Electron二进制,同样面临龙芯没有官方包的问题。
解决办法是在配置里指定本地已准备好的二进制,不让它去下载。在package.json或electron-builder.yml里配置:
{ "build": { "electronDist": "node_modules/electron/dist", "linux": { "target": ["deb"], "category": "Utility" } } }electronDist指向你手动放好的二进制目录,这样builder就不会重新下载。打包成deb包后,在麒麟系统上用dpkg -i安装即可。
4.3 常见启动报错与排查
实际过程中会遇到各种报错,我整理了一个速查表。
| 报错信息 | 可能原因 | 解决方向 |
|---|---|---|
| Exec format error | 二进制架构不匹配 | 确认uname -m与二进制架构一致 |
| error while loading shared libraries | 缺系统库 | 按2.2节补装依赖 |
| GPU process isn't usable | 显卡驱动不兼容 | 加--disable-gpu或--disable-software-rasterizer |
| Failed to load module | 原生模块ABI不匹配 | 重新编译原生模块 |
| White screen | 渲染进程崩溃 | 开--enable-logging看详细日志 |
| Cannot find module 'electron' | path.txt错误 | 检查path.txt内容 |
排查时养成看日志的习惯,加--enable-logging参数能把Chromium的详细日志打出来,很多问题一看日志就清楚了。
4.4 字体与中文显示问题
麒麟系统上跑Electron,有时候界面中文显示成方块。这是因为Electron自带的字体渲染依赖系统字体配置。装几个中文字体:
sudo apt install -y fonts-wqy-zenhei fonts-wqy-microhei fc-cache -fv然后在应用里指定字体族,或者用CSS的font-family兜底。这个问题在打包分发时尤其要注意,目标机器不一定装了中文字体。
注意:打包deb时可以把字体作为依赖写进去,或者在安装后脚本里检测并提示用户安装,避免装完打开一片方块。
5. 实操全流程复盘与经验沉淀
5.1 从零到跑通的完整命令序列
把前面的步骤串起来,给一个可以直接照着敲的流程。假设你已经拿到了龙芯版Electron二进制包,放在/opt/electron-loongarch64。
# 1. 确认架构 uname -m # 2. 装系统依赖 sudo apt update sudo apt install -y libnss3 libatk1.0-0 libgtk-3-0 libgbm1 libasound2 # 3. 装Node(如果系统自带够用可跳过) sudo apt install -y nodejs npm # 4. 进项目目录,跳过二进制下载装依赖 cd /path/to/your-project export ELECTRON_SKIP_BINARY_DOWNLOAD=1 npm install # 5. 放入龙芯版二进制 mkdir -p node_modules/electron/dist cp -r /opt/electron-loongarch64/* node_modules/electron/dist/ chmod +x node_modules/electron/dist/electron # 6. 确认path.txt echo "electron" > node_modules/electron/path.txt # 7. 重编译原生模块(如果有) npm rebuild --runtime=electron --target=15.3.0 --arch=loongarch64 # 8. 启动测试 npx electron . --disable-gpu --enable-logging这一套下来,大部分项目能跑起来。剩下的就是针对具体业务代码做兼容性调整。
5.2 几个容易忽视的细节
磁盘空间。Electron的二进制解压后有好几百MB,加上node_modules,项目目录轻松上G。龙芯机器的存储如果紧张,提前清理。
权限问题。麒麟系统对可执行文件的权限管得比较严,从别处拷来的二进制记得chmod +x,否则报权限拒绝。
环境变量污染。如果之前设过ELECTRON_MIRROR之类的变量指向x64的镜像,记得清掉,否则可能干扰。
版本一致性。Electron版本、原生模块编译target、打包工具配置里的版本,三者必须一致,差一个小版本都可能出问题。
5.3 性能调优的几点体会
龙芯平台的算力相比主流x64有差距,Electron应用跑起来可能感觉卡。几个优化方向:关闭不必要的动画和特效,减少渲染进程的复杂度,把耗时的计算放到主进程或Worker里,避免阻塞UI。另外,--disable-gpu虽然能解决兼容性问题,但会牺牲渲染性能,如果目标机器显卡驱动OK,还是尽量开启硬件加速。
内存方面,Electron本身比较吃内存,龙芯机器内存如果只有4G,跑起来会比较吃力。建议至少8G起步,或者优化应用的内存占用。
5.4 后续维护的思考
这种非官方支持的平台适配,最大的问题是可持续性。Electron升级了,你得重新找或编译对应版本的二进制;系统更新了,依赖库可能又变了。我的建议是:把适配过程脚本化,写成一个setup.sh,把二进制获取、依赖安装、模块编译都固化下来。这样换台机器或者重装系统,一条命令就能恢复环境。同时,把用到的二进制包和headers做好版本归档,避免哪天源站挂了找不到。
另外,关注国产化适配社区的动态,很多人在做类似的事情,互相参考能省不少力气。遇到问题先搜一搜,大概率有人踩过同样的坑。
这个项目从最开始的一头雾水到最终跑通打包,前后花了不少时间,但把流程理顺之后,后面再遇到类似需求就从容多了。希望这些记录能帮到正在做同样事情的你,少走点弯路。