今天我们一起来适配一个GitHub上有1kstar的开源项目到GitCode,一起来看一下适配的过程,以及这个应用升级的时候遇到的一些问题。

  • 项目定位:一个基于 Electron 与 Node.js 的现代图片查看器,借助 LightGallery 实现丰富的动效与缩略图体验。

  • 跨平台目标:统一代码在 macOS、Windows、Linux 运行;并给出 HarmonyOS NEXT 的集成思路。

  • 技术焦点:Electron 主进程与渲染进程协作、LightGallery 插件集成、菜单与国际化、打包脚本与签名发布。

效果预览

image-20251111075114857

实现过程

  • 主进程启动

    • app/background.js 创建 BrowserWindow,并启用 @electron/remote/main,以兼容新版 Electron 移除默认 remote 的变更。

    • 通过菜单配置与 webContents.send 实现渲染进程通信(如打开目录、更新配置项)。

  • 渲染层与 LightGallery 集成

    • app/app.html 引入 LightGallery 的 CSS/JS 与各插件(如 Autoplay、Thumbnail),并在页面中渲染图片容器。

    • app/app.js 负责将 defaults(主进程中的配置)透传到 LightGallery 初始化,绑定事件与控件逻辑。

  • 配置与菜单

    • background.js 维护 defaults,其中包含 mode/speed/zoom/thumbnail/autoplay 等所有参数;菜单项通过 updateConfig(key, value) 动态更新并通知渲染进程。

  • 国际化(i18n)

    • app/i18n.js 提供简易字典,默认语言 zh-CN,可用 setLocale('en-US') 切换。

    • 所有菜单标签使用 t('key') 获取翻译,避免硬编码英文。

示例代码(附注释)

  • app/i18n.js 核心方法与字典结构

export function setLocale(code) {
  // 切换当前语言,默认字典包含 zh-CN 与 en-US
}
​
export function t(key) {
  // 读取当前字典;如果未找到键,降级返回 key 本身,避免崩溃
}
  • 缩略图菜单国际化(摘自 background.js,已替换为 t()

{
  label: t('thumbnail'),       // 缩略图主开关
  type: 'checkbox',
  checked: defaults.thumbnail,
  click: (menuItem) => updateConfig('thumbnail', menuItem.checked)
},
{
  label: t('animateThumb'),    // 缩略图动效
  type: 'checkbox',
  checked: defaults.animateThumb,
  click: (menuItem) => updateConfig('animateThumb', menuItem.checked)
},
{
  label: t('toogleThumb'),     // 切换缩略图显示
  type: 'checkbox',
  checked: defaults.toogleThumb,
  click: (menuItem) => updateConfig('toogleThumb', menuItem.checked)
},
{
  label: t('enableThumbDrag'), // 启用缩略图拖拽
  type: 'checkbox',
  checked: defaults.enableThumbDrag,
  click: (menuItem) => updateConfig('enableThumbDrag', menuItem.checked)
}
  • 字典补充(摘自 app/i18n.js

'zh-CN': {
  thumbnail: '缩略图',
  animateThumb: '缩略图动画',
  toogleThumb: '切换缩略图',
  enableThumbDrag: '启用缩略图拖拽',
  // ...
},
'en-US': {
  thumbnail: 'Thumbnail',
  animateThumb: 'animateThumb',
  toogleThumb: 'toogleThumb',
  enableThumbDrag: 'enableThumbDrag',
  // ...
}

目录结构

  • app:应用主代码与资源

    • app.html:页面骨架与资源引入

    • app.js:渲染逻辑与 LightGallery 初始化

    • background.js:Electron 主进程、菜单、配置与事件转发

    • i18n.js:字典与翻译方法

    • lightgallery/:第三方库 CSS/JS/Sass 与字体、图片等

    • stylesheets/main.less:样式入口

    • config.json:默认配置与参数

  • tasks:构建与打包脚本

    • start.js:开发时独立构建并启动 Electron

    • build_standalone.js:独立构建,规避旧版 gulp 问题

    • release_standalone.js:按当前 OS 打包(推荐入口)

    • release_osx*.js:macOS 打包,支持 zip/DMG 与签名

    • release_windows.js:Windows 打包(NSIS 安装包)

    • release_linux.js:Linux 打包(DEB)

    • utils.js:通用工具(OS 检测、变量替换、签名参数等)

  • resources:平台打包素材

    • osx/:Info.plist、DMG 配置与图标

    • windows/:图标与 NSIS 安装脚本

    • linux/:DEBIAN/ 控制文件与 Desktop 文件模板

  • config:环境配置(development/test/production)

  • README.md:文档(含打包与升级说明)

启动与开发

  • 安装依赖(包含 Electron 与 app 内依赖)

npm install
  • 启动开发

npm start
  • 国内镜像加速下载 Electron(可选)

ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm install

打包流程

  • 基础打包(推荐)

npm run release
  • macOS(签名/DMG)

node ./tasks/release_osx.js --env=production --sign="Developer ID Application: 你的证书名称 (TEAMID)"
  • macOS(简化脚本,zip/DMG,不强制签名)

node ./tasks/release_osx_simple.js --env=production
  • Windows(NSIS)

node ./tasks/release_windows.js --env=production
  • Linux(DEB)

node ./tasks/release_linux.js --env=production
  • 发布前建议:

    • 更新 app/package.jsonversion/productName/identifier

    • 在应用中切换语言自查菜单文案(i18n)与主流程

升级过程中遇到的问题

  • electron-prebuilt → electron@^31

    • 新版 Electron 移除默认 remote,需在主进程启用 @electron/remote/main,渲染进程使用 @electron/remote

    • BrowserWindow 需设置 webPreferences: { nodeIntegration: true, contextIsolation: false } 以兼容旧代码。

  • gulp 3 与 Node 18 的兼容性

    • 典型报错:primordials is not defined

    • 处理方案:开发与构建走 build_standalone.js;发布脚本按平台拆分(可逐步迁移到 gulp v4)

    • 兜底方案:如暂时保留旧版脚本,打包时使用 Node 14 LTS

  • macOS 打包与签名

    • release_osx.js 支持签名与 DMG;需设置 --sign 指定 Developer ID

    • 简化版脚本 release_osx_simple.js 默认生成 zip 与 DMG,增强兼容性(优先 hdiutil,回退 appdmg

  • Windows 安装包

    • 需本地安装 NSIS,确保 makensisPATH

    • 使用 rcedit 替换图标与版本描述

  • Linux DEB

    • 依赖 fakerootdpkg-deb;脚本中处理了路径转义,避免空间字符导致命令失败

  • 国际化缺口修复

    • Autoplay 菜单与缩略图菜单存在英文硬编码:已补齐 Autoplay/autoplay/progressBar/fourceAutoplay/autoplayControls/ms 等键,并替换菜单标签为 t()

    • 缩略图菜单新增键:animateThumbtoogleThumbenableThumbDrag,对应中文翻译与英文占位

HarmonyOS 适配

  • 复用前端资源

    • 将构建后的 build/ 作为资源目录,在 ArkUI 的 Web 组件中加载

  • ArkTS 壳工程

    • 通过 Web 组件承载页面,映射键盘与鼠标事件(如缩放、全屏、拖拽)

    • 以 JSBridge 封装平台差异,统一文件选择与目录访问

  • 文案与单位

    • 继续沿用英文键名作字典键(t('thumbnail')),保持跨平台一致性;单位类(如 ms)按键值组合翻译,避免硬编码

  • 打包建议

    • HarmonyOS 侧生成 .hap;桌面端仍按上述流程输出安装包,形成多端共用前端代码的混合架构

开源项目地址

  • 项目仓库:gitcode.com:nutpi/lightgallery-desktop.git

  • 相关项目:

    • LightGallery for web: https://github.com/sachinchoolur/lightGallery

    • jQuery lightslider: https://github.com/sachinchoolur/lightslider

结语

  • 本项目以 Electron + LightGallery 打造跨平台图片查看器,并通过简易 i18n 与脚本化打包流程实现快速发布。

  • 在升级 Electron 与适配 HarmonyOS 的过程中,建议保持英文键名统一、用脚本替代手工流程,并在每次发布前用 npm start 做一次端到端自查。


架构与流程详解(更深入的技术细节)

  • 主进程与渲染进程边界

    • 主进程:负责窗口管理、菜单、系统能力(文件/目录选择)与配置下发;文件 app/background.js

    • 渲染进程:承载 UI 与 LightGallery 交互;文件 app/app.htmlapp/app.js

    • 事件通道:通过 webContents.send(channel, payload) 下发事件;渲染进程监听并应用配置。

  • 关键主进程代码(带注释)

// background.js 中的配置更新桥
var updateConfig = function(key, val) {
  // 1) 更新内存中的 defaults
  defaults[key] = val;
  // 2) 广播给渲染进程(LightGallery 的实例在渲染层)
  if (ready) {
    mainWindow.webContents.send('updateConfig', { key: key, val: val });
  }
};
​
// 菜单项示例(缩略图开关)
{
  label: t('thumbnail'),
  type: 'checkbox',
  checked: defaults.thumbnail,
  click: (menuItem) => updateConfig('thumbnail', menuItem.checked)
}
  • 渲染层初始化(要点)

    • 将主进程下发的 defaults 映射为 LightGallery 的初始化参数与插件选项。

    • 图片列表支持 dynamicEl,也可从目录读取并填充数组。

构建流水线详解(替代旧版 gulp 的方案)

  • 入口:tasks/start.js

    • 调用 build_standalone.js 完成打包,然后拉起 Electron:

var app = childProcess.spawn(electron, ['./build'], { stdio: 'inherit' });
  • 省略旧的 gulp watch;如需热更,可后续用 chokidar 恢复监听。

  • 独立构建:tasks/build_standalone.js

    • 目标:在现代 Node 环境下替代 gulp 3 的打包功能。

    • 核心步骤:

      • 清理 build/;复制 app 的静态资源与第三方库。

      • 使用 rollup 打包 background.jsapp.jscjs

rollup.rollup({ entry: src }).then((bundle) => {
  const result = bundle.generate({ format: 'cjs', sourceMap: true });
  const isolatedCode = '(function () {' + result.code + '}());';
  // 写入 bundle 及 source map
});
- 编译 Less:`stylesheets/main.less` → `build/stylesheets/main.css`。
- 写入 `build/package.json` 并注入环境配置:
manifest.env = projectDir.read('config/env_' + utils.getEnvName() + '.json', 'json');
destDir.write('package.json', manifest);

打包实现细节(按平台)

  • 通用入口:npm run releasetasks/release_standalone.js

    • 先执行独立构建,再根据当前 OS 路由到对应打包脚本:

const releaseForOs = { osx: require('./release_osx_simple'), linux: require('./release_linux'), windows: require('./release_windows') };
  • macOS:release_osx_simple.jsrelease_osx.js

    • 复制 Electron.app 到临时目录,打包 app.asar,替换 Info.plist 与图标。

    • 产物:.zip.dmg;优先使用系统 hdiutil,失败时回退到 appdmg

    • 可选签名:release_osx.js 支持 --sign="Developer ID Application: ... (TEAMID)"

  • Windows:release_windows.js

    • 复制 electron/dist,打包 app.asar,用 rcedit 替换图标与版本说明。

    • 生成 NSIS 安装包,需本地 makensis 可用。

  • Linux:release_linux.js

    • 复制 electron/dist,打包 app.asar,生成 .desktop 文件与图标。

    • 使用 fakeroot dpkg-deb 生成 amd64.deb

IPC 与安全策略(升级注意点)

  • remote 替换

    • 新版 Electron 移除默认 remote;主进程需 @electron/remote/main 初始化并在创建窗口后启用。

    • 渲染进程使用 @electron/remote 获取 app 等 API。

  • BrowserWindow 安全配置(现状与建议)

    • 当前为兼容旧代码,设置 nodeIntegration: true, contextIsolation: false

    • 建议后续迁移:开启 contextIsolation: truepreload,通过 contextBridge 暴露受控 API,降低 XSS 风险。

i18n 设计与扩展

  • 字典结构:dictionaries[locale][key];默认 zh-CN,支持 en-US

  • 回退策略:t(key) 未命中返回 key 本身,保证菜单不因缺失键而崩溃。

  • 单位翻译:诸如 ms 等单位作为独立键处理,避免字符串拼接硬编码。

  • 示例:补齐缩略图相关键并替换菜单标签为 t()(见上文代码片段)。

性能与体验细节(实践建议)

  • 图片目录加载

    • 大量图片时建议按批次分页加载到 LightGallery,避免一次性渲染导致卡顿。

  • 缩略图与动效

    • 在低端机或远程网络资源下,建议关闭 animateThumb 并降低 speed,以提升交互流畅性。

  • 资源体积

    • 构建时仅复制必要的 lightgallery 子目录与字体/图片,减少包体。

HarmonyOS 集成更细节(ArkTS/ETS)

  • Web 组件加载

    • ArkUI 提供 Web 组件承载 build/ 页面;通过 postMessage 或 JSBridge 与宿主交互。

  • 能力映射

    • 文件选择与目录访问在桌面与移动端差异较大,建议封装统一接口,内部桥接到平台实现。

  • 文案一致性

    • 继续沿用英文键名作为 i18n 字典键,与桌面端共享字典,减少维护成本。

问题清单与解决策略(升级踩坑)

  • primordials is not defined

    • 原因:gulp 3 与 Node 18 不兼容。

    • 方案:开发/构建改为独立脚本;若保留旧版任务,打包阶段用 Node 14 LTS 兜底。

  • Electron 下载缓慢/失败(国内网络)

    • 方案:ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ npm install

  • macOS Gatekeeper 限制

    • 现象:未签名 DMG 运行受限。

    • 方案:使用 --sign 进行签名,必要时按 Apple 流程进行公证(notarytool)。

  • Windows NSIS 缺失

    • 现象:spawn makensis ENOENT

    • 方案:安装 NSIS 并把 makensis 加入 PATH

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐