普通视图

发现新文章,点击刷新页面。
昨天以前首页

Electron 发布 39 版本 ,这更新速度也变态了吧❓︎❓︎❓︎

作者 Moment
2025年10月31日 09:11

最近在使用 NestJs 和 NextJs 在做一个协同文档 DocFlow,如果感兴趣,欢迎 star,有任何疑问,欢迎加我微信进行咨询 yunmz777

Electron 39.0.0 于 2025 年 10 月 27 日发布。此版本带来了对 Chromium、Node.js 和 V8 引擎的更新,提升了性能和稳定性,同时也引入了一些新的功能和改进。以下是此版本的详细变化。

栈升级

  • Chromium: 更新到 142.0.7444.52,这意味着 Electron 在此版本中升级了其底层浏览器引擎。该版本修复了多个性能和安全漏洞,同时引入了一些新的 Web 标准。

  • Node.js: 更新到 22.20.0,这个版本包含了许多重要的 Node.js 修复和改进,包括性能优化和一些新的 API。

  • V8: 更新到 14.2,V8 引擎的升级提升了 JavaScript 执行的效率,使得应用程序的响应速度更快,内存占用更低。

破坏性更改

在这一版本中,有几个 API 和行为发生了变化,这可能会导致与以前版本的兼容性问题。

  • OffscreenSharedTexture:此 API 的签名进行了更新,新的版本提供了一个统一的 handle,用于持有原生句柄。这意味着开发者需要调整代码,以便正确使用这个新的接口。

  • window.open:该方法的行为得到修复,确保它创建的弹出窗口始终是可调整大小的。原本可能出现的不一致性问题已经被解决,确保符合标准规范。

新特性

  • Offscreen 渲染支持 RGBAF16:Electron 现在支持以 RGBAF16 格式输出图像数据。这意味着应用程序可以更好地支持高动态范围(HDR)图像,提供更高质量的图像渲染。

  • process.getSystemMemoryInfo() 增强:在 macOS 上,getSystemMemoryInfo 方法新增了 fileBackedpurgeable 字段,这让开发者能够获得更多关于系统内存的信息,包括哪些内存是文件映射的、哪些可以被清除以释放空间。

  • systemPreferences.getAccentColor:在 Linux 上,Electron 新增了一个方法 systemPreferences.getAccentColor,它返回操作系统的强调色。这对于需要与操作系统主题颜色匹配的应用程序很有用。

  • 托盘图标 guid 选项:在 macOS 上,Tray 构造函数现在支持一个新的 guid 选项。这个选项允许托盘图标在应用程序重新启动后保持相同的位置和状态,使得用户体验更加一致。

  • WebFrameMain API 增强:Electron 新增了 webFrameMain.fromFrameToken(processId, frameToken) 方法,开发者可以通过此方法从帧令牌获取 WebFrameMain 实例,这对于需要直接操作特定帧的应用程序非常有用。

  • 可访问性支持:Electron 引入了更细粒度的可访问性支持,包括为开发者提供更多的 API 来提高对残障人士的支持。这使得应用程序能更好地满足可访问性需求,提供更加友好的用户体验。

  • app.getRecentDocuments() 支持:在 Windows 和 macOS 上,Electron 现在支持 app.getRecentDocuments() 方法。通过这个方法,开发者可以获取到最近访问的文档列表,方便实现类似于“最近使用文件”的功能。

  • USB 设备 API 更新:Electron 新增了对 USBDevice.configurations 的支持。开发者现在可以获取到连接到设备的 USB 配置信息,这对于需要与 USB 设备交互的应用程序非常有用。

  • 文件系统 API 更新:在应用程序中持久化文件系统权限状态变得更加简单。Electron 允许在给定的会话内持久化文件系统授权状态,避免用户每次打开应用时重新授权。

  • 动态导入(ESM)支持:在非上下文隔离的预加载脚本中,Electron 现在支持动态导入 ECMAScript 模块(ESM)。这使得开发者能够在 Electron 中更灵活地使用 JavaScript 模块化。

修复

  • 系统配色问题修复:修复了 systemPreferences.getAccentColor 返回的颜色反转的问题,确保返回的颜色值符合预期。

  • 开发者工具:修复了在 Wayland 上调用 webContents.openDevTools({ mode: 'detach' }) 时可能导致的崩溃问题。Wayland 是 Linux 上的一种显示协议,这个修复对于在该平台上开发的 Electron 应用程序至关重要。

  • 会话管理问题:修复了访问 webContents.session 时可能导致崩溃的问题。这个修复增强了应用程序在多会话环境下的稳定性。

  • 窗口管理:修复了在调用 window.close() 后,执行某些操作可能导致崩溃的问题。这个修复提高了窗口管理的可靠性。

  • 命令行参数问题修复:修复了通过命令行参数传递特性参数时,可能导致的崩溃问题,确保应用程序能够稳定运行。

  • 文件对话框问题修复:修复了在 Windows 上调用 dialog.showOpenDialog 时,如果传入的扩展名过滤器数组为空,可能导致的崩溃问题。

其他更改

  • 资源定位:内部的资源定位机制发生了变化,现在 Electron 使用 DIR_ASSETS 来定位资产和资源。此外,app.getPath 方法现在支持返回一个新的 "assets" 键,用于获取应用程序资源路径。

  • 文档更新:官方文档得到了更新和补充,相关的 API 和功能进行了详细说明,开发者可以参考最新的文档了解更多实现细节。

总结

Electron 39.0.0 版本主要带来了对 Chromium、Node.js 和 V8 的升级,提升了性能和稳定性。此外,新增了对 Offscreen 渲染、系统主题色、USB 设备支持等的支持,也修复了多个与窗口管理、文件对话框等相关的 bug。对于开发者来说,这些更新和改进能够带来更高效、稳定的开发体验。

记录一次修改 PNPM 版本,部署 NextJs 服务时导致服务器崩溃的问题 😡😡😡

作者 Moment
2025年10月30日 08:17

最近在使用 NestJs 和 NextJs 在做一个协同文档 DocFlow,如果感兴趣,欢迎 star,有任何疑问,欢迎加我微信进行咨询 yunmz777

最近在使用 NextJs 开发 DocFlow 协同编辑这个项目,运行了很久都没有问题,最近终于在部署方面出现了问题了,早上的时候发现 ssh 连不上了,一开始并没有太在意,但后来打开京东云控制台,好家伙真的好家伙:

20251029202122

真的小母牛坐飞机牛逼上天了!原来是 CPU 爆了,怪不得连接不上了,当然网站也 502 了:

20251029202311

那是什么原因呢,接下来就要开始慢慢排查了,既然 vscode 连不上,那我们就在官方提供的 ssh 来连接:

20251029202432

输入命令 htop,罪魁祸首马上出现:

20251029202653

原来是 next-server 和 node(运行在 /home/DocFlow-Server/dist/main.js)占用了基本全部的 CPU,那这个原因就很清楚了,那么接下来就可以排查了这个问题的原因了。

首先,可以明确的一点是,之前一直都是同样的方式部署的,没有出现问题,但是为什么今天就一直出现这个问题呢,那肯定是在运行的进程出现了问题。

我项目使用的是 pm2 部署的,那打个日志看看咯:

20251029203101

问题找到了,原来是 pm2 一直在重启,把内存全部占用了,具体是什么原因的已经不好查了,有可能是安装了一些依赖,但是我的 Github Action 是有一些问题没有处理的:

name: Deploy Next.js to JD Cloud

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4.2.0

      - name: Deploy to server via SSH
        uses: appleboy/ssh-action@v1.2.1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USERNAME }}
          port: ${{ secrets.SERVER_PORT }}
          password: ${{ secrets.SERVER_PASSWORD }}
          script: |
            # 加载环境配置
            source ~/.bashrc 2>/dev/null || true
            source ~/.profile 2>/dev/null || true

            # 加载 NVM 环境
            export NVM_DIR="$HOME/.nvm"
            [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

            # 设置 PATH
            export PATH="$HOME/.nvm/versions/node/*/bin:/usr/local/bin:/usr/bin:/bin:$HOME/.npm-global/bin:$PATH"

            # 设置工作目录
            PROJECT_DIR="/home/DocFlow"
            mkdir -p $PROJECT_DIR
            cd $PROJECT_DIR

            # 克隆或更新代码
            if [ ! -d ".git" ]; then
              echo "Cloning repository..."
              rm -rf ./*
              git clone git@github.com:xun082/DocFlow.git .
            else
              echo "Updating repository..."
              git fetch origin main
              git reset --hard origin/main
            fi

            # 创建 .npmrc 文件 (如果不存在)
            if [ ! -f ".npmrc" ]; then
              echo "Creating .npmrc file..."
              echo "@tiptap-pro:registry=https://registry.tiptap.dev/" > .npmrc
              echo "//registry.tiptap.dev/:_authToken=${{ secrets.TIPTAP_AUTH_TOKEN }}" >> .npmrc
            else
              echo ".npmrc file already exists, skipping creation."
            fi

            # 安装全局依赖 (只在需要时安装)
            command -v pnpm >/dev/null 2>&1 || npm install -g pnpm@9.4.0
            command -v pm2 >/dev/null 2>&1 || npm install -g pm2

            # 安装项目依赖
            pnpm install

            # 构建项目
            pnpm run build

            # 重启应用
            pm2 restart DocFlow 2>/dev/null || pm2 start "pnpm start" --name DocFlow

我这个部署脚本是基本没问题的,至少能跑,现在查看这两天的 commit,想起来有一个这样的操作:

20251029204359

那基本就可以确定是这个问题了。

其他部署方案

PM2 是一种流行的进程管理工具,适用于 Node.js 应用,尤其在小型项目和单机部署时很有效。然而,PM2 的部署流程存在一些局限性:

  1. 依赖管理和版本控制:PM2 需要手动确保服务器上安装正确的 Node.js 和 pnpm 版本。每次代码更新后,你还需要在服务器上重新 构建项目(执行 pnpm run build),这可能会导致生产环境与开发环境之间的不一致,并增加了维护工作。

  2. 服务中断问题:每次代码更新时,PM2 需要 重启应用 来使新版本生效。如果没有正确配置或管理,应用在重启过程中可能会停机一段时间,这对于高可用性要求较高的生产环境来说是个问题。

与 PM2 相比,Docker 自动化部署 通过容器化解决了这些问题,提供了更简洁、更一致的部署流程,特别适用于云端和多环境部署。主要优势包括:

  1. 无需依赖管理和环境配置:Docker 将应用及其所有依赖、环境变量、构建过程封装在 Docker 镜像 中。这样,服务器上无需安装特定版本的 Node.js 或 pnpm,避免了手动配置和版本不一致的问题。你只需要在 构建镜像时 配置好所有的依赖和环境,部署时无需再进行任何安装或构建操作。

  2. 代码问题不会影响运行:如果代码有问题,Docker 使得应用 不会受到当前部署的影响。因为 Docker 镜像已经包含了所有必要的依赖,部署失败时,原先的镜像仍然可以继续运行,确保生产环境不受影响。而在 PM2 部署 时,更新代码后需要重启应用,如果代码有问题,应用会直接停机,导致服务中断。

  3. 无缝的 CI/CD 集成:Docker 完美集成 CI/CD 流程。例如,使用 GitHub Actions,你可以自动构建 Docker 镜像并推送到仓库。服务器只需要 拉取最新镜像,并启动新的容器。如果部署失败,不会影响当前运行的容器,你可以迅速恢复服务,且无需手动修复。相反,PM2 需要重新启动应用,且服务停机时需要手动修复代码。

  4. 快速回滚:由于 Docker 镜像的版本化机制,你可以轻松回滚到之前的稳定版本。即便遇到部署失败的情况,只需要拉取旧版本的镜像,应用立即恢复,不需要手动操作,这为应用提供了更高的可靠性。

总结

PM2 部署中,如果代码有问题,必须手动修复并重启应用,这可能会导致 服务中断,并影响用户体验。而且每次更新都需要在服务器上重新构建项目,这可能导致环境不一致,增加了部署的复杂性。

Docker 部署则通过 容器化 确保应用和环境的一致性,部署失败时不会影响生产环境的运行,原有容器仍可继续工作,且通过 CI/CD 流程可以自动恢复和快速回滚,不需要人工干预。即使代码存在问题,原有的容器仍可保持正常服务,确保应用的高可用性。

因此,对于生产环境,Docker 提供了比 PM2 更稳定、高效、自动化的部署方式,尤其适合大规模、高可用的应用部署。

❌
❌