首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >轻画廊桌面版:Electron 跨平台图片查看器实践与鸿蒙适配

轻画廊桌面版:Electron 跨平台图片查看器实践与鸿蒙适配

作者头像
徐建国
发布2025-11-29 15:10:31
发布2025-11-29 15:10:31
2780
举报
文章被收录于专栏:个人路线个人路线
  • 项目定位:一个基于 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
    • 清理 build/;复制 app 的静态资源与第三方库。
    • 使用 rollup 打包 background.jsapp.jscjs
    • 目标:在现代 Node 环境下替代 gulp 3 的打包功能。
    • 核心步骤:

    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
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-11-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大前端之旅 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档