<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Electron Blog</title>
        <link>https://electronjs.org/zh/blog</link>
        <description>Electron Blog</description>
        <lastBuildDate>Tue, 17 Mar 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh</language>
        <item>
            <title><![CDATA[Tech Talk: How Electron went Wayland-native, and what it means for your apps]]></title>
            <link>https://electronjs.org/zh/blog/tech-talk-wayland</link>
            <guid>https://electronjs.org/zh/blog/tech-talk-wayland</guid>
            <pubDate>Tue, 17 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron recently switched to Wayland by default on Linux, bringing dozens of popular desktop apps along with it. Here's what changed and how it affects developers and users.]]></description>
            <content:encoded><![CDATA[<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p>Tech talks are a new blog post series where we share glimpses into our work on Electron. If you find this work interesting, please consider <a href="https://github.com/electron/electron/" target="_blank" rel="noopener noreferrer" class="">contributing</a>!</p></div></div>
<p>When Electron switched to <a href="https://wayland.freedesktop.org/" target="_blank" rel="noopener noreferrer" class="">Wayland</a> on Linux last fall, most people didn't notice.</p>
<p>Major Linux distributions adopted the modern display protocol years ago, and both the KDE Plasma and GNOME desktop environments are in the process of <a href="https://blogs.kde.org/2025/11/26/going-all-in-on-a-wayland-future/" target="_blank" rel="noopener noreferrer" class="">dropping X11 support</a> <a href="https://www.phoronix.com/news/GNOME-50-Alpha/" target="_blank" rel="noopener noreferrer" class="">completely</a>.</p>
<p>But a platform migration isn't complete without apps, and a large part of the Linux app ecosystem went through a second Wayland transition last August — well after most distros had changed their defaults. That's when Chromium <a href="https://chromium-review.googlesource.com/c/chromium/src/+/6819616" target="_blank" rel="noopener noreferrer" class="">turned on Wayland by default</a>, bringing Electron and dozens of Linux desktop apps along with it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-third-impact-electron-goes-wayland-native">The third impact: Electron goes Wayland-native<a href="https://electronjs.org/zh/blog/tech-talk-wayland#the-third-impact-electron-goes-wayland-native" class="hash-link" aria-label="链接到 The third impact: Electron goes Wayland-native" title="链接到 The third impact: Electron goes Wayland-native" translate="no">​</a></h2>
<p>Wayland is supported out of the box in <a href="https://releases.electronjs.org/release/v38.2.0" target="_blank" rel="noopener noreferrer" class="">Electron 38.2</a> and newer. As long as your apps are up-to-date, it just works. (If you were previously launching your Electron apps with very long commands like <code>CONFUSING_OZONE_VARIABLE --ozone-platform=wayland</code>, you no longer need to do that.)</p>
<p>This change was possible because the Chromium and Electron projects have been <a href="https://github.com/electron/electron/pull/26022" target="_blank" rel="noopener noreferrer" class="">working on Wayland support</a> for more than half a decade. But until recently, Chrome and Electron apps continued to use X11 by default, even when launched in a Wayland session. This wasn’t a big issue, since X11 apps still work fairly well on Wayland by running inside an invisible X server called <a href="https://wayland.freedesktop.org/docs/html/ch05.html" target="_blank" rel="noopener noreferrer" class="">Xwayland</a>.</p>
<p><a href="https://electronjs.org/zh/assets/files/xwayland-8fc6983c43adb7294e26749d678d1b60.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Screenshot of an Electron app running in X11 compatibility mode (XWayland) in a Wayland session on Ubuntu" src="https://electronjs.org/zh/assets/images/xwayland-8fc6983c43adb7294e26749d678d1b60.png" width="1280" height="960" class="img_ev3q"></a></p>
<p>Running apps through a compatibility layer is not the same as running them directly on Wayland. On Wayland, there’s less sitting between your app and the compositor, so there's lower overhead and much stronger isolation between applications. Modern Wayland compositors also let apps take advantage of newer platform and display features like variable refresh rates, HiDPI and fractional scaling, and HDR.</p>
<p><a href="https://electronjs.org/zh/assets/files/hdr-f6b141a7502024160f550c614c947608.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Screenshot of an Electron app running natively on Wayland, demonstrating support for wide gamut color and HDR" src="https://electronjs.org/zh/assets/images/hdr-f6b141a7502024160f550c614c947608.png" width="1295" height="1076" class="img_ev3q"></a></p>
<p>These are all good reasons for Electron to make the switch. In late September, Electron followed Chromium’s lead and began <a href="https://www.electronjs.org/blog/electron-38-0#removed-electron_ozone_platform_hint-environment-variable" target="_blank" rel="noopener noreferrer" class="">defaulting to Wayland</a>. And as apps began to update, people who had been “using Wayland” without issues for months or years started to find out what it was really like to experience their apps on Wayland for the first time.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="waylands-house-waylands-rules">Wayland’s house, Wayland’s rules<a href="https://electronjs.org/zh/blog/tech-talk-wayland#waylands-house-waylands-rules" class="hash-link" aria-label="链接到 Wayland’s house, Wayland’s rules" title="链接到 Wayland’s house, Wayland’s rules" translate="no">​</a></h2>
<p>Supporting Wayland required dozens of changes throughout <a href="https://chromium-review.googlesource.com/q/subject:%22wayland%22" target="_blank" rel="noopener noreferrer" class="">Chromium</a> and <a href="https://github.com/electron/electron/pulls?q=is%3Apr+wayland" target="_blank" rel="noopener noreferrer" class="">Electron</a>, from internals to developer-facing APIs. It also required a different way of thinking about what desktop apps should be able to do.</p>
<p>Wayland reconsiders assumptions made by older systems and asks whether apps should be able to:</p>
<ul>
<li class="">Take focus away from other apps</li>
<li class="">View and interact with windows from other apps</li>
<li class="">Respond to mouse and keyboard input when not focused</li>
<li class="">Choose where to position their own windows on the screen (and which physical monitor to appear on)</li>
<li class="">Resize their windows at any time</li>
</ul>
<p>Wayland's answer to these questions is essentially “no.” When you open a window, the compositor — not the app developer — decides where it goes. Apps cannot unilaterally move, resize, or focus their windows without user input, and they can only interact with the rest of the desktop through optional <a href="https://wayland.app/protocols/" target="_blank" rel="noopener noreferrer" class="">protocol extensions</a> and <a href="https://flatpak.github.io/xdg-desktop-portal/" target="_blank" rel="noopener noreferrer" class="">XDG portals</a>.</p>
<p>These kinds of rules are understandable; no one likes it when a misbehaving app steals focus or loads halfway off the screen. But it can still surprise people when their apps suddenly lose access to familiar affordances on Wayland. This is especially the case for a cross-platform framework like Electron, which exists to help developers achieve consistent results everywhere.</p>
<p>Some widely used Electron APIs that work on X11, macOS, and Windows are not available on Wayland. For example, <a href="https://www.electronjs.org/docs/latest/api/base-window#winsetpositionx-y-animate" target="_blank" rel="noopener noreferrer" class=""><code>win.setPosition(x, y)</code></a> and <a href="https://www.electronjs.org/docs/latest/api/screen#screengetcursorscreenpoint" target="_blank" rel="noopener noreferrer" class=""><code>screen.getCursorScreenPoint()</code></a> aren't supported, as Wayland <a href="https://lists.freedesktop.org/archives/wayland-devel/2015-September/024410.html" target="_blank" rel="noopener noreferrer" class="">deliberately forbids</a> apps from accessing global screen coordinates.</p>
<p>Other features work differently: recording the screen with <a href="https://www.electronjs.org/docs/latest/api/desktop-capturer" target="_blank" rel="noopener noreferrer" class=""><code>desktopCapturer</code></a> and setting keyboard shortcuts with <a href="https://www.electronjs.org/docs/latest/api/global-shortcut" target="_blank" rel="noopener noreferrer" class=""><code>globalShortcut</code></a> are more restricted, and both heavily depend on the desktop environment and portal versions. Here's what it looks like when screen sharing in Signal Desktop on GNOME 48.</p>
<p><a href="https://electronjs.org/zh/assets/files/signalscreenshare-4f0031952ec13722d28814608d871c25.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Screenshot of Signal Desktop requesting permission to share the screen on GNOME" src="https://electronjs.org/zh/assets/images/signalscreenshare-4f0031952ec13722d28814608d871c25.png" width="1627" height="1198" class="img_ev3q"></a></p>
<p>Making this more complicated for developers is the fact that Wayland isn't a single piece of software, but a protocol. Every <a href="https://en.wikipedia.org/wiki/Wayland_(protocol)#Wayland_compositors" target="_blank" rel="noopener noreferrer" class="">compositor</a> implements it a little differently, almost like browser engines. (There are even <a href="https://absurdlysuspicious.github.io/wayland-protocols-table/" target="_blank" rel="noopener noreferrer" class="">protocol support trackers</a> that look like they came from MDN or CanIUse.)</p>
<p>So when Slack tries to focus its main window with <a href="https://www.electronjs.org/docs/latest/api/browser-window#winfocus" target="_blank" rel="noopener noreferrer" class=""><code>win.focus()</code></a>, GNOME's compositor (Mutter) shows a notification. On KDE Plasma (KWin), the app icon flashes in the panel instead. Neither outcome is what the app's developers had in mind, but both are valid interpretations of the <a href="https://wayland.app/protocols/xdg-activation-v1" target="_blank" rel="noopener noreferrer" class="">activation spec</a>.</p>
<p><a href="https://electronjs.org/zh/assets/files/focus-bd12b1a8eb0999cba0edfb16934505d4.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Screenshot comparing what happens when Slack tries to focus itself on GNOME and KDE" src="https://electronjs.org/zh/assets/images/focus-bd12b1a8eb0999cba0edfb16934505d4.png" width="1280" height="720" class="img_ev3q"></a></p>
<p>Some capabilities simply work better on Wayland than on X11, including anything to do with colors, transparency, and hardware-accelerated rendering. <a href="https://www.electronjs.org/docs/latest/api/base-window#winsetopacityopacity-windows-macos" target="_blank" rel="noopener noreferrer" class=""><code>win.setOpacity(n)</code></a> is an example of an Electron API which hasn't been available on Linux in the past, but which will now be feasible to support.</p>
<p>Even the stricter restrictions can benefit apps. When 1Password runs on Wayland, its <a href="https://developer.1password.com/docs/ssh/agent/" target="_blank" rel="noopener noreferrer" class="">SSH agent</a> lets users confirm requests with a single click instead of asking them to enter their passwords. This is safe because Wayland's input isolation is strong enough to prevent the prompt from being skipped with <a href="https://en.wikipedia.org/wiki/Clickjacking" target="_blank" rel="noopener noreferrer" class="">clickjacking</a> — only a real human being can click the button.</p>
<p><a href="https://electronjs.org/zh/assets/files/1passwordssh-6ef79e1c3174043cb11571d3874802bf.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Screenshot of the 1Password SSH agent showing a prompt with an Authorize button, floating over a terminal with an SSH command." src="https://electronjs.org/zh/assets/images/1passwordssh-6ef79e1c3174043cb11571d3874802bf.png" width="1641" height="1293" class="img_ev3q"></a></p>
<p>The basic tradeoff is that Wayland restricts some of what apps can do but also enables them to be more capable and secure. And in one area, Wayland gives developers more flexibility and more responsibility than before: client-side decorations (CSD).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="understanding-csd-or-when-a-window-isnt-a-window">Understanding CSD, or when a window isn’t a window<a href="https://electronjs.org/zh/blog/tech-talk-wayland#understanding-csd-or-when-a-window-isnt-a-window" class="hash-link" aria-label="链接到 Understanding CSD, or when a window isn’t a window" title="链接到 Understanding CSD, or when a window isn’t a window" translate="no">​</a></h2>
<p>The Wayland protocol is very lightweight, and its simplicity extends to the way it draws window frames. On X11, the window manager typically supplies a window’s title bar and frame decorations. But when you create a window (<a href="https://wayland.app/protocols/xdg-shell" target="_blank" rel="noopener noreferrer" class=""><code>xdg_toplevel</code></a>) on Wayland, all you get back from the compositor is a plain rectangle.</p>
<p><a href="https://electronjs.org/zh/assets/files/waylandnocsd-1fda0479eb87487d13ce5473ed32277f.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Screenshot of a blank app window on Wayland with no decorations. It&amp;#39;s just a white rectangle." src="https://electronjs.org/zh/assets/images/waylandnocsd-1fda0479eb87487d13ce5473ed32277f.png" width="1280" height="960" class="img_ev3q"></a></p>
<p>That rectangle is a powerful canvas. On a modern compositor like GNOME’s Mutter, it’s triple-buffered and GPU-accelerated. But if you want any of the trimmings users might expect — title bar buttons, drop shadows, even resize handles — you have to add them yourself. This requirement is called client-side decorations (CSD), and it’s one of the major differences between X11 and Wayland.</p>
<p>Electron already had some support for client-side decorations, provided by a class called <code>ClientFrameViewLinux</code> which uses GTK to paint convincing native window frames. These look very similar to the ones GNOME used to supply on X11, but they are produced entirely in-framework.</p>
<p><a href="https://electronjs.org/zh/assets/files/clientframeviewlinux-cfd509bc5a3099a12009bb9aa9da3749.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Screenshot of a ClientFrameViewLinux with client-side decorations on GNOME" src="https://electronjs.org/zh/assets/images/clientframeviewlinux-cfd509bc5a3099a12009bb9aa9da3749.png" width="1280" height="960" class="img_ev3q"></a></p>
<p>But client-side window frames are not an exact match for server-side decorations (SSD) from X11 window managers. They need to be implemented by each app or framework, so the details can look noticeably different when you put apps side by side, from their title bar areas right down to their drop shadows and corner shapes.</p>
<p><a href="https://electronjs.org/zh/assets/files/csdcomparison-92a791c2382c1f4c96e8cd20d932276d.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Screenshot of four apps with CSD from different frameworks (clockwise from top-left: Adwaita, Qt, Electron, and Firefox)" src="https://electronjs.org/zh/assets/images/csdcomparison-92a791c2382c1f4c96e8cd20d932276d.png" width="1728" height="1296" class="img_ev3q"></a></p>
<p>The differences are usually minor, but when CSD is completely absent from a window, the result can be visually jarring.</p>
<p>Many popular apps, including Visual Studio Code, Obsidian, and Discord, use <a href="https://www.electronjs.org/docs/latest/tutorial/custom-window-styles" target="_blank" rel="noopener noreferrer" class="">frameless windows</a> with <a href="https://www.electronjs.org/docs/latest/tutorial/custom-title-bar" target="_blank" rel="noopener noreferrer" class="">custom title bars</a>. Prior to <a href="https://www.electronjs.org/blog/electron-41-0" target="_blank" rel="noopener noreferrer" class="">Electron 41</a>, frameless windows did not support CSD at all, so they looked like featureless rectangles on Wayland.</p>
<p><a href="https://electronjs.org/zh/assets/files/vscodenocsd-6f2013f1656e09eff0cfca1e94fa0a71.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Screenshot of VS Code on KDE with no CSD" src="https://electronjs.org/zh/assets/images/vscodenocsd-6f2013f1656e09eff0cfca1e94fa0a71.png" width="1731" height="1300" class="img_ev3q"></a></p>
<p>Improving coverage for CSD was a task with framework-wide consequences. The biggest obstacle involved window sizes and how to measure and set them accurately. Electron already manages two different kinds of window boundaries:</p>
<ul>
<li class=""><strong>“window bounds”</strong>, the size of the window, including its titlebar, menubar, and frame.</li>
<li class=""><strong>“content bounds”</strong>, the size of the internal web view which hosts the app’s web content.</li>
</ul>
<p>Both values can be controlled independently. If a developer calls for an 800x600 window, Electron calculates the height of the title bar and shrinks the web app to something like 800x540. (It also works the other way around for <a href="https://www.electronjs.org/docs/latest/api/base-window#new-basewindowoptions" target="_blank" rel="noopener noreferrer" class="">content-sized</a> windows.)</p>
<p><a href="https://electronjs.org/zh/assets/files/windowbounds-b41c7193d91e6981b341bb9acabdc6a6.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Diagram of an Electron app&amp;#39;s window and content bounds without CSD" src="https://electronjs.org/zh/assets/images/windowbounds-b41c7193d91e6981b341bb9acabdc6a6.png" width="1650" height="1275" class="img_ev3q"></a></p>
<p>To support CSD, Electron also needed to keep track of a new kind of boundary:</p>
<ul>
<li class=""><strong>“widget bounds”</strong>, the size of the transparent widget which draws everything inside of it, including the window frame and its external decorations.</li>
</ul>
<p>When CSD is required, Electron first takes the window's underlying <a href="https://wayland.app/protocols/xdg-shell#xdg_surface" target="_blank" rel="noopener noreferrer" class="">surface</a> (accessed internally via a Chromium <a href="https://source.chromium.org/chromium/chromium/src/+/main:ui/ozone/platform/wayland/host/wayland_window.cc;l=94;drc=ac4eed7b549169cd64f0e15b503f4f0635dc1bd9" target="_blank" rel="noopener noreferrer" class="">accelerated widget</a>) and inflates it so it's large enough to fit all the decorations.</p>
<p>The framework then paints the opaque bits of the window (title bar, frame, and web content) at their appropriate sizes and positions inside the transparent widget. The outermost areas are filled in with drop shadows and resize hit targets, creating the look and feel of a native, three-dimensional window without relying on server-side decorations.</p>
<p>With CSD, a "logical" window at 800x600 might be inset into a 840x640 widget. The exact geometries depend on the user's theme and the window's state: whether it is currently active, maximized, tiled, or fullscreen can affect the size and presence of decorations.</p>
<p><a href="https://electronjs.org/zh/assets/files/widgetbounds-e2921ef22f4dad4281d9cb74357b3d83.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Diagram of an Electron app&amp;#39;s full CSD bounds, including the transparent widget surrounding the window" src="https://electronjs.org/zh/assets/images/widgetbounds-e2921ef22f4dad4281d9cb74357b3d83.png" width="1650" height="1275" class="img_ev3q"></a></p>
<p>Of course, widget bounds should never leak into the public API. The framework needs to abstract this complexity away from app developers, who are generally not thinking about the extents of resize targets or shadow insets changing underneath them.</p>
<p>The good news is that much of this was sorted out between last September and March, and as a result, Electron 41 supports CSD on Wayland in all window configurations, including frameless windows with <a href="https://www.electronjs.org/docs/latest/api/structures/base-window-options" target="_blank" rel="noopener noreferrer" class="">Window Controls Overlay</a>.</p>
<p><a href="https://electronjs.org/zh/assets/files/vscodecsd-26e13ece78b184484cc8e27f122e3e99.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Screenshot of VS Code using a prerelease version of Electron 41.x with CSD shadows." src="https://electronjs.org/zh/assets/images/vscodecsd-26e13ece78b184484cc8e27f122e3e99.png" width="1813" height="1316" class="img_ev3q"></a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="whats-next--and-how-you-can-help">What’s next — and how you can help<a href="https://electronjs.org/zh/blog/tech-talk-wayland#whats-next--and-how-you-can-help" class="hash-link" aria-label="链接到 What’s next — and how you can help" title="链接到 What’s next — and how you can help" translate="no">​</a></h2>
<p>Wayland is an everyday reality for Linux users in 2026, so a great Wayland experience is now just what it means to support Linux.</p>
<p>Electron reached an important milestone last month with the creation of a <a href="https://github.com/electron/electron/pull/49908" target="_blank" rel="noopener noreferrer" class="">Wayland test job in CI</a>. More tests still need to be ported over, but it’s now much easier to catch regressions.</p>
<p>Now that the basic support is in place, Wayland opens up new possibilities for Electron apps. CSD in particular offers developers more ways to customize window frames and integrate them with both their web content and the platform. <a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">Let us know</a> what you'd like to see; one feature that's high on my own shortlist is rounded corners.</p>
<p><a href="https://electronjs.org/zh/assets/files/roundedcorners-da8eb9a58504779605f9f315f9a55392.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Screenshot of a frameless window with rounded corners (not currently possible in Electron, but soon?)" src="https://electronjs.org/zh/assets/images/roundedcorners-da8eb9a58504779605f9f315f9a55392.png" width="1840" height="1439" class="img_ev3q"></a></p>
<p>The framework is only part of the story. If you develop an Electron app and you haven’t thoroughly tested it on Linux in a while (even as recently as last fall), give it a spin with Electron 41+ on a modern distribution like Ubuntu 25.10 or Fedora 43. Try your app on both KDE Plasma and GNOME, and maybe something more exotic like <a href="https://github.com/niri-wm/niri" target="_blank" rel="noopener noreferrer" class="">Niri</a>.</p>
<p>You may discover changes you could make to accommodate Wayland's unique constraints. Some differences are covered in the <a href="https://www.electronjs.org/docs/latest/api/browser-window" target="_blank" rel="noopener noreferrer" class="">Electron documentation</a>, but the best way to understand the new environment is to use it.</p>
<p>And if you’d like to see faster progress and support for more platform features, consider <a href="https://github.com/electron/electron/blob/main/CONTRIBUTING.md" target="_blank" rel="noopener noreferrer" class="">becoming a contributor</a>. Like Linux itself, Electron is a community-run <a href="https://openjsf.org/blog/electron-joins-the-openjs-foundation" target="_blank" rel="noopener noreferrer" class="">free software project</a> that’s open to everyone, and we're actively looking for Linux contributors and maintainers.</p>
<p>Electron powers many of the most popular desktop apps across platforms, so getting involved is an effective way to help make desktop Linux more viable for millions of people.</p>]]></content:encoded>
            <category>Tech Talk</category>
            <category>Electron Internals</category>
        </item>
        <item>
            <title><![CDATA[Electron 41]]></title>
            <link>https://electronjs.org/zh/blog/electron-41-0</link>
            <guid>https://electronjs.org/zh/blog/electron-41-0</guid>
            <pubDate>Tue, 10 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 41 has been released! It includes upgrades to Chromium 146.0.7680.65, V8 14.6, and Node v24.14.0.]]></description>
            <content:encoded><![CDATA[<p>Electron 41 has been released! It includes upgrades to Chromium 146.0.7680.65, V8 14.6, and Node v24.14.0.</p>
<hr>
<p>The Electron team is excited to announce the release of Electron 41! 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://bsky.app/profile/electronjs.org" target="_blank" rel="noopener noreferrer" class="">Bluesky</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p>After publishing the initial 41.0.0 package, we integrated some high-priority
bugs into follow-up patch releases. We recommend installing <strong>41.0.2</strong> when
upgrading to Electron 41.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重要变化">重要变化<a href="https://electronjs.org/zh/blog/electron-41-0#%E9%87%8D%E8%A6%81%E5%8F%98%E5%8C%96" class="hash-link" aria-label="链接到 重要变化" title="链接到 重要变化" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="asar-integrity-digest-for-improved-security">ASAR Integrity digest for improved security<a href="https://electronjs.org/zh/blog/electron-41-0#asar-integrity-digest-for-improved-security" class="hash-link" aria-label="链接到 ASAR Integrity digest for improved security" title="链接到 ASAR Integrity digest for improved security" translate="no">​</a></h3>
<p>As of Electron 41, macOS Electron apps can now embed a digest of their <a href="https://www.electronjs.org/docs/latest/tutorial/asar-integrity" target="_blank" rel="noopener noreferrer" class="">ASAR Integrity</a> information. This adds an additional layer of tamper detection for apps that use ASAR Integrity by validating the integrity information itself at app launch.</p>
<p>To enable the feature for your app, you can run the following command with <code>@electron/asar</code> v4.1.0 and above:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">asar integrity-digest on /path/to/YourApp.app</span><br></span></code></pre></div></div>
<p>You <strong><em>must</em></strong> re-sign your app afterwards. For more information, see <a href="https://github.com/electron/asar/blob/v4.1.0/README.md#integrity-digest" target="_blank" rel="noopener noreferrer" class="">the <code>@electron/asar</code> CLI documentation.</a></p>
<p>Support for this feature in <a href="https://electronforge.io/" target="_blank" rel="noopener noreferrer" class="">Electron Forge</a> is planned for the near future (<a href="https://github.com/electron/forge/pull/4159" target="_blank" rel="noopener noreferrer" class="">electron/forge#4159</a>).</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="improved-wayland-support">Improved Wayland support<a href="https://electronjs.org/zh/blog/electron-41-0#improved-wayland-support" class="hash-link" aria-label="链接到 Improved Wayland support" title="链接到 Improved Wayland support" translate="no">​</a></h3>
<p>On Wayland (Linux), frameless windows now have drop shadows and extended resize boundaries. To create fully frameless windows with no decorations, set <code>hasShadow: false</code> in the window constructor. <a href="https://github.com/electron/electron/pull/49885" target="_blank" rel="noopener noreferrer" class="">#49885</a></p>
<p><a href="https://github.com/mitchchn" target="_blank" rel="noopener noreferrer" class="">Mitchell Cohen</a> is writing a blog article about recent work to improve Electron's support of Wayland and client-side decorations on Linux. Watch this space!</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="added-support-for-msix-auto-updating">Added support for MSIX auto-updating<a href="https://electronjs.org/zh/blog/electron-41-0#added-support-for-msix-auto-updating" class="hash-link" aria-label="链接到 Added support for MSIX auto-updating" title="链接到 Added support for MSIX auto-updating" translate="no">​</a></h3>
<p>The Electron team recently added MSIX auto-updater support according to <a href="https://github.com/electron/rfcs/pull/21" target="_blank" rel="noopener noreferrer" class="">RFC #21</a>. You can now ship both MSIX and Squirrel.Mac in your update server essentially with the same JSON response format. See the <a href="https://www.electronjs.org/docs/latest/api/auto-updater" target="_blank" rel="noopener noreferrer" class="">autoUpdater documentation</a> for more information.</p>
<p>This was added in Electron 41 by <a href="https://github.com/electron/electron/pull/49586" target="_blank" rel="noopener noreferrer" class="">#49586</a> and has also been backported to Electron 39.5.0 (<a href="https://github.com/electron/electron/pull/49585" target="_blank" rel="noopener noreferrer" class="">#49585</a>) and 40.2.0 (<a href="https://github.com/electron/electron/pull/49587" target="_blank" rel="noopener noreferrer" class="">#49587</a>).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-41-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">
<p>Chromium <code>146.0.7680.65</code></p>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-146/" target="_blank" rel="noopener noreferrer" class="">146 新功能</a></li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-145/" target="_blank" rel="noopener noreferrer" class="">145 新功能</a></li>
</ul>
</li>
<li class="">
<p>Node <code>v24.14.0</code></p>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v24.14.0" target="_blank" rel="noopener noreferrer" class="">Node 24.14.0 博客</a></li>
<li class=""><a href="https://nodejs.org/en/blog/release/v24.13.1" target="_blank" rel="noopener noreferrer" class="">Node 24.13.1 博客</a></li>
<li class=""><a href="https://nodejs.org/en/blog/release/v24.13.0" target="_blank" rel="noopener noreferrer" class="">Node 24.13.0 博客</a></li>
<li class=""><a href="https://nodejs.org/en/blog/release/v24.12.0" target="_blank" rel="noopener noreferrer" class="">Node 24.12.0 博客</a></li>
</ul>
</li>
<li class="">
<p>V8 <code>14.4</code></p>
<ul>
<li class=""><a href="https://chromium.googlesource.com/v8/v8.git/+/3f4b2d428486d982bf51d7c0487adcd9f73f5fd8" target="_blank" rel="noopener noreferrer" class="">V8 roll increment</a></li>
</ul>
</li>
</ul>
<p>Electron 41 upgrades Chromium from <code>144.0.7559.60</code> to <code>146.0.7680.65</code>, Node.js from <code>v24.11.1</code> to <code>v24.14.0</code>, and V8 from <code>14.4</code> to <code>14.6</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-features-and-improvements">New Features and Improvements<a href="https://electronjs.org/zh/blog/electron-41-0#new-features-and-improvements" class="hash-link" aria-label="链接到 New Features and Improvements" title="链接到 New Features and Improvements" translate="no">​</a></h2>
<ul>
<li class="">Added <code>--disable-geolocation</code> command-line flag for macOS apps to disable location services. <a href="https://github.com/electron/electron/pull/45934" target="_blank" rel="noopener noreferrer" class="">#45934</a></li>
<li class="">Added NV12 support for import shared texture. <a href="https://github.com/electron/electron/pull/48922" target="_blank" rel="noopener noreferrer" class="">#48922</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/49040" target="_blank" rel="noopener noreferrer" class="">40</a>)</sup></li>
<li class="">Added a <code>disclaim</code> option to the <code>utilityProcess</code> API to allow for TCC disclaiming on macOS. <a href="https://github.com/electron/electron/pull/49693" target="_blank" rel="noopener noreferrer" class="">#49693</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/49696" target="_blank" rel="noopener noreferrer" class="">39</a>, <a href="https://github.com/electron/electron/pull/49695" target="_blank" rel="noopener noreferrer" class="">40</a>)</sup></li>
<li class="">Added a <code>reason</code> property to the <code>Notification</code> <code>'closed'</code> event on Windows to allow developers to know the reason the notification was dismissed. <a href="https://github.com/electron/electron/pull/50029" target="_blank" rel="noopener noreferrer" class="">#50029</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/50030" target="_blank" rel="noopener noreferrer" class="">40</a>)</sup></li>
<li class="">Added an <code>usePrinterDefaultPageSize</code> option to <code>webContents.print()</code> to allow using the printer's default page size. <a href="https://github.com/electron/electron/pull/49812" target="_blank" rel="noopener noreferrer" class="">#49812</a></li>
<li class="">Added support for WebSocket authentication through the <code>login</code> event on <code>webContents</code>. <a href="https://github.com/electron/electron/pull/48512" target="_blank" rel="noopener noreferrer" class="">#48512</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/49065" target="_blank" rel="noopener noreferrer" class="">39</a>, <a href="https://github.com/electron/electron/pull/49064" target="_blank" rel="noopener noreferrer" class="">40</a>)</sup></li>
<li class="">Added support for the Node.js <a href="https://nodejs.org/docs/latest-v22.x/api/cli.html#--experimental-transform-types" target="_blank" rel="noopener noreferrer" class=""><code>--experimental-transform-types</code></a> flag. <a href="https://github.com/electron/electron/pull/49882" target="_blank" rel="noopener noreferrer" class="">#49882</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/49881" target="_blank" rel="noopener noreferrer" class="">39</a>, <a href="https://github.com/electron/electron/pull/49883" target="_blank" rel="noopener noreferrer" class="">40</a>)</sup></li>
<li class="">Added support for <code>long-animation-frame</code> script attribution (via <code>--enable-features=AlwaysLogLOAFURL</code>). <a href="https://github.com/electron/electron/pull/49773" target="_blank" rel="noopener noreferrer" class="">#49773</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/49771" target="_blank" rel="noopener noreferrer" class="">39</a>, <a href="https://github.com/electron/electron/pull/49772" target="_blank" rel="noopener noreferrer" class="">40</a>)</sup></li>
<li class="">Added the ability to disable auto-focusing of <code>WebContents</code> on navigation using <code>webPreferences.focusOnNavigation</code>. <a href="https://github.com/electron/electron/pull/49511" target="_blank" rel="noopener noreferrer" class="">#49511</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/49512" target="_blank" rel="noopener noreferrer" class="">40</a>)</sup></li>
<li class="">Irrelevant errors from the Chromium DevTools frontend are now silenced in the main process. <a href="https://github.com/electron/electron/pull/49292" target="_blank" rel="noopener noreferrer" class="">#49292</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/49359" target="_blank" rel="noopener noreferrer" class="">40</a>)</sup></li>
<li class="">Enable V8 trap handlers for WASM behind <code>WasmTrapHandlers</code> <a href="https://www.electronjs.org/docs/latest/tutorial/fuses" target="_blank" rel="noopener noreferrer" class="">fuse</a>. <a href="https://github.com/electron/electron/pull/49839" target="_blank" rel="noopener noreferrer" class="">#49839</a></li>
<li class="">Extended actions support for Windows notifications to include buttons, select dropdowns, and replies. <a href="https://github.com/electron/electron/pull/49787" target="_blank" rel="noopener noreferrer" class="">#49787</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/49786" target="_blank" rel="noopener noreferrer" class="">40</a>)</sup></li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-41-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-pdfs-no-longer-create-a-separate-webcontents">Behavior Changed: PDFs no longer create a separate WebContents<a href="https://electronjs.org/zh/blog/electron-41-0#behavior-changed-pdfs-no-longer-create-a-separate-webcontents" class="hash-link" aria-label="链接到 Behavior Changed: PDFs no longer create a separate WebContents" title="链接到 Behavior Changed: PDFs no longer create a separate WebContents" translate="no">​</a></h4>
<p>Previously, PDF resources created a separate guest <a href="https://www.electronjs.org/docs/latest/api/web-contents" target="_blank" rel="noopener noreferrer" class=""><code>WebContents</code></a> for rendering. Now, PDFs are rendered within the same <code>WebContents</code> instead. If you have code to detect PDF resources, use the <a href="https://www.electronjs.org/docs/latest/api/web-frame-main" target="_blank" rel="noopener noreferrer" class="">frame tree</a> instead of <code>WebContents</code>.</p>
<p>Under the hood, Chromium <a href="https://chromium-review.googlesource.com/c/chromium/src/+/7239572" target="_blank" rel="noopener noreferrer" class="">enabled</a> a feature that changes PDFs to use out-of-process iframes (OOPIFs) instead of the <code>MimeHandlerViewGuest</code> extension.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-updated-cookie-change-cause-in-the-cookie-changed-event">Behavior Changed: Updated Cookie Change Cause in the Cookie <code>'changed'</code> Event<a href="https://electronjs.org/zh/blog/electron-41-0#behavior-changed-updated-cookie-change-cause-in-the-cookie-changed-event" class="hash-link" aria-label="链接到 behavior-changed-updated-cookie-change-cause-in-the-cookie-changed-event" title="链接到 behavior-changed-updated-cookie-change-cause-in-the-cookie-changed-event" translate="no">​</a></h4>
<p>We have updated the cookie change cause in the cookie <a href="https://www.electronjs.org/docs/latest/api/cookies#event-changed" target="_blank" rel="noopener noreferrer" class=""><code>'changed'</code> event</a>.
When a new cookie is set, the change cause is <code>inserted</code>.
When a cookie is deleted, the change cause remains <code>explicit</code>.
When the cookie being set is identical to an existing one (same name, domain, path, and value, with no actual changes), the change cause is <code>inserted-no-change-overwrite</code>.
When the value of the cookie being set remains unchanged but some of its attributes are updated, such as the expiration attribute, the change cause will be <code>inserted-no-value-change-overwrite</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="终止对-38xy-的支持">终止对 38.x.y 的支持<a href="https://electronjs.org/zh/blog/electron-41-0#%E7%BB%88%E6%AD%A2%E5%AF%B9-38xy-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 终止对 38.x.y 的支持" title="链接到 终止对 38.x.y 的支持" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 38.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。 See <a href="https://releases.electronjs.org/schedule" target="_blank" rel="noopener noreferrer" class="">https://releases.electronjs.org/schedule</a> to see the timeline for supported versions of Electron.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-41-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
        <item>
            <title><![CDATA[Electron 40.0.0]]></title>
            <link>https://electronjs.org/zh/blog/electron-40-0</link>
            <guid>https://electronjs.org/zh/blog/electron-40-0</guid>
            <pubDate>Tue, 13 Jan 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 40.0.0 已发布！ 它包括对 Chromium 144.0.7559.60、V8 14.4 和 Node 24.11.1 的升级。]]></description>
            <content:encoded><![CDATA[<p>Electron 40.0.0 已发布！ 它包括对 Chromium 144.0.7559.60、V8 14.4 和 Node 24.11.1 的升级。</p>
<hr>
<p>Electron 团队很高兴发布了 Electron 40.0.0 ！ 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://bsky.app/profile/electronjs.org" target="_blank" rel="noopener noreferrer" class="">Bluesky</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-40-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">
<p>Chromium <code>144.0.7559.60</code></p>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-144/" target="_blank" rel="noopener noreferrer" class="">144 新功能</a></li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-143/" target="_blank" rel="noopener noreferrer" class="">143 新功能</a></li>
</ul>
</li>
<li class="">
<p>Node <code>v24.11.1</code></p>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v24.11.1/" target="_blank" rel="noopener noreferrer" class="">Node 24.11.1 博客</a></li>
</ul>
</li>
<li class="">
<p>V8 <code>14.4</code></p>
<ul>
<li class=""><a href="https://chromium.googlesource.com/v8/v8.git/+/e4746e7564d601ae4dfb8355c0d7af00d1178694" target="_blank" rel="noopener noreferrer" class="">V8 roll increment</a></li>
</ul>
</li>
</ul>
<p>Electron 40 upgrades Chromium from <code>142.0.7444.52</code> to <code>144.0.7559.60</code>, Node.js from <code>v22.20.0</code> to <code>v24.11.1</code>, and V8 from <code>14.2</code> to <code>14.4</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-features-and-improvements">New Features and Improvements<a href="https://electronjs.org/zh/blog/electron-40-0#new-features-and-improvements" class="hash-link" aria-label="链接到 New Features and Improvements" title="链接到 New Features and Improvements" translate="no">​</a></h3>
<ul>
<li class="">Added <code>"memory-eviction"</code> as a possible reason for a child process to exit. <a href="https://github.com/electron/electron/pull/48362" target="_blank" rel="noopener noreferrer" class="">#48362</a></li>
<li class="">Added <code>bypassCustomProtocolHandlers</code> option to <code>net.request</code>. <a href="https://github.com/electron/electron/pull/48883" target="_blank" rel="noopener noreferrer" class="">#48883</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/48881" target="_blank" rel="noopener noreferrer" class="">38</a>, <a href="https://github.com/electron/electron/pull/48882" target="_blank" rel="noopener noreferrer" class="">39</a>)</sup></li>
<li class="">Added support to import external shared texture as <code>VideoFrame</code>. <a href="https://github.com/electron/electron/pull/48831" target="_blank" rel="noopener noreferrer" class="">#48831</a></li>
<li class="">Automatically focus DevTools when element is inspected or breakpoint is triggered. <a href="https://github.com/electron/electron/pull/46386" target="_blank" rel="noopener noreferrer" class="">#46386</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/48703" target="_blank" rel="noopener noreferrer" class="">37</a>, <a href="https://github.com/electron/electron/pull/48701" target="_blank" rel="noopener noreferrer" class="">38</a>, <a href="https://github.com/electron/electron/pull/48702" target="_blank" rel="noopener noreferrer" class="">39</a>)</sup></li>
<li class="">Enabled resetting accent color to follow system accent settings if a previous color has been set via <code>window.setAccentColor(null)</code>. <a href="https://github.com/electron/electron/pull/48274" target="_blank" rel="noopener noreferrer" class="">#48274</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/48853" target="_blank" rel="noopener noreferrer" class="">38</a>, <a href="https://github.com/electron/electron/pull/48852" target="_blank" rel="noopener noreferrer" class="">39</a>)</sup></li>
<li class="">Updated <code>nativeImage.createFromNamedImage</code> to support SF Symbol names. <a href="https://github.com/electron/electron/pull/48772" target="_blank" rel="noopener noreferrer" class="">#48772</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/48773" target="_blank" rel="noopener noreferrer" class="">39</a>)</sup></li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-40-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="deprecated-clipboard-api-access-from-renderer-processes">Deprecated: clipboard API access from renderer processes<a href="https://electronjs.org/zh/blog/electron-40-0#deprecated-clipboard-api-access-from-renderer-processes" class="hash-link" aria-label="链接到 Deprecated: clipboard API access from renderer processes" title="链接到 Deprecated: clipboard API access from renderer processes" translate="no">​</a></h4>
<p>Using the <code>clipboard</code> API directly in the renderer process is deprecated. If you want to call this API from a renderer process, place the API call in your preload script and expose it using the <code>contextBridge</code> API.</p>
<h4 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-macos-dsym-files-now-compressed-with-tarxz">Behavior Changed: macOS dSYM files now compressed with tar.xz<a href="https://electronjs.org/zh/blog/electron-40-0#behavior-changed-macos-dsym-files-now-compressed-with-tarxz" class="hash-link" aria-label="链接到 Behavior Changed: macOS dSYM files now compressed with tar.xz" title="链接到 Behavior Changed: macOS dSYM files now compressed with tar.xz" translate="no">​</a></h4>
<p>Debug symbols for macOS (dSYM) now use xz compression in order to handle larger file sizes. <code>dsym.zip</code> files are now <code>dsym.tar.xz</code> files. End users using debug symbols may need to update their zip utilities.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="终止对-37xy-的支持">终止对 37.x.y 的支持<a href="https://electronjs.org/zh/blog/electron-40-0#%E7%BB%88%E6%AD%A2%E5%AF%B9-37xy-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 终止对 37.x.y 的支持" title="链接到 终止对 37.x.y 的支持" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 37.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。</p>
<table><thead><tr><th>E40 (Jan'26)</th><th>E41 (Mar'26)</th><th>E42 (May'26)</th></tr></thead><tbody><tr><td>40.x.y</td><td>41.x.y</td><td>42.x.y</td></tr><tr><td>39.x.y</td><td>40.x.y</td><td>41.x.y</td></tr><tr><td>38.x.y</td><td>39.x.y</td><td>40.x.y</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-40-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
        <item>
            <title><![CDATA[Tech Talk: Improving Window Resize Behavior]]></title>
            <link>https://electronjs.org/zh/blog/tech-talk-window-resize-behavior</link>
            <guid>https://electronjs.org/zh/blog/tech-talk-window-resize-behavior</guid>
            <pubDate>Wed, 17 Dec 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[We're launching a new blog post series where we share glimpses into our work on Electron. If you find this work interesting, please consider contributing!]]></description>
            <content:encoded><![CDATA[<p><em>We're launching a new blog post series where we share glimpses into our work on Electron. If you find this work interesting, please consider <a href="https://github.com/electron/electron/" target="_blank" rel="noopener noreferrer" class="">contributing</a>!</em></p>
<hr>
<p>Recently, I worked on improving Electron and Chromium's window resize behavior.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-bug">The bug<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#the-bug" class="hash-link" aria-label="链接到 The bug" title="链接到 The bug" translate="no">​</a></h2>
<p>We were seeing an issue on Windows where old frames would become visible while resizing a window:</p>
<p><img decoding="async" loading="lazy" alt="Animated GIF showing the issue where old frames would be shown while resizing windows" src="https://electronjs.org/zh/assets/images/window-resize-bug-showing-old-frames-4d3f73d4b7d13e44539ca65120662a43.gif" width="860" height="493" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-made-this-bug-particularly-interesting">What made this bug particularly interesting?<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#what-made-this-bug-particularly-interesting" class="hash-link" aria-label="链接到 What made this bug particularly interesting?" title="链接到 What made this bug particularly interesting?" translate="no">​</a></h2>
<ol>
<li class="">It was challenging.</li>
<li class="">It was deep in a large codebase.</li>
<li class="">As you'll see later, there were two different bugs under the hood.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="fixing-the-bug">Fixing the bug<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#fixing-the-bug" class="hash-link" aria-label="链接到 Fixing the bug" title="链接到 Fixing the bug" translate="no">​</a></h2>
<p>With a bug like this, the first challenge is figuring out where to start looking.</p>
<p>Electron builds upon Chromium, the open source version of Google Chrome. When compiling Electron, Electron's source code is added into the Chromium source tree as a subdirectory. Electron then relies on Chromium's code to provide most of the functionality of a modern browser.</p>
<p>Chromium has about 36 million lines of code. Electron is a large project, too. That is a lot of code that could be causing this issue.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="narrowing-down-the-root-cause">Narrowing down the root cause<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#narrowing-down-the-root-cause" class="hash-link" aria-label="链接到 Narrowing down the root cause" title="链接到 Narrowing down the root cause" translate="no">​</a></h2>
<p>I did a lot of experimentation.</p>
<p>First, I noticed that the issue occurred in Google Chrome, too:</p>
<p><img decoding="async" loading="lazy" alt="Screenshot of Google Chrome also showing the resize issue" src="https://electronjs.org/zh/assets/images/google-chrome-repro-4fdc95d866a64783be6bb64eef2f2cab.png" width="3022" height="1818" class="img_ev3q"></p>
<p>This suggested that the issue was likely in Chromium, not in Electron.</p>
<p>Additionally, the issue was not visible on macOS. That suggested that it was in Windows-specific source code.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-crucial-lead">The crucial lead<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#the-crucial-lead" class="hash-link" aria-label="链接到 The crucial lead" title="链接到 The crucial lead" translate="no">​</a></h2>
<p>I tried a lot of different command line flags and configuration options.</p>
<p>I noticed that <a class="" href="https://electronjs.org/zh/docs/latest/api/app#appdisablehardwareacceleration"><code>app.disableHardwareAcceleration()</code></a> fixed the issue. Without hardware acceleration, the issue was gone.</p>
<p>Here is some context: Chromium supports various different graphics APIs for showing pixels on screen (OpenGL, Vulkan, Metal, and more). On Windows, it uses different graphics APIs than on macOS or Linux. Even on Windows, Chromium can work with multiple different graphics backends.</p>
<p>Which graphics backend Chromium uses depends on the user's hardware. For example, some graphics backends require the computer to have a GPU.</p>
<p>I tried various graphics backends and noticed that the following flags fixed the issue:</p>
<ul>
<li class=""><code>--use-angle=warp</code></li>
<li class=""><code>--use-angle=vulkan</code></li>
<li class=""><code>--use-gl=desktop</code></li>
<li class=""><code>--use-gl=egl</code></li>
<li class=""><code>--use-gl=osmesa</code></li>
<li class=""><code>--use-gl=swiftshader</code></li>
</ul>
<p>The following flags reproduced the issue:</p>
<ul>
<li class=""><code>--use-angle=d3d11</code> (this is currently the default on Windows)</li>
<li class=""><code>--use-angle=gl</code> (falls back to Direct3D 11 on Windows, see <code>chrome://gpu/</code>)</li>
</ul>
<p>None of the working flags were good enough to be used as the default in Electron apps on Windows. They were either too slow or lacked broad driver support.</p>
<p>However, these workarounds pointed me into the right direction. They showed that the issue was in a code path that was only used with the ANGLE Direct3D 11 backend.</p>
<p><a href="https://en.wikipedia.org/wiki/Direct3D" target="_blank" rel="noopener noreferrer" class="">Direct3D</a> is a Windows API for hardware-accelerated graphics.</p>
<p><a href="https://en.wikipedia.org/wiki/ANGLE_(software)" target="_blank" rel="noopener noreferrer" class="">ANGLE</a> is a library that translates OpenGL calls into calls to the native graphics API of the given operating system, here Direct3D. ANGLE allows Chromium developers to write OpenGL calls on all platforms. ANGLE then translates them into Direct3D, Vulkan, or Metal API calls, depending on which graphics API is used.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="locating-the-relevant-chromium-component">Locating the relevant Chromium component<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#locating-the-relevant-chromium-component" class="hash-link" aria-label="链接到 Locating the relevant Chromium component" title="链接到 Locating the relevant Chromium component" translate="no">​</a></h2>
<p>Chromium references Direct3D in tens of thousands of places. It wasn't realistic to go through all of them.</p>
<p>By chance, I stumbled across a few helpful debugging flags in the Chromium source code:</p>
<ul>
<li class=""><code>--ui-show-paint-rects</code></li>
<li class=""><code>--ui-show-property-changed-rects</code></li>
<li class=""><code>--ui-show-surface-damage-rects</code></li>
<li class=""><code>--ui-show-composited-layer-borders</code></li>
<li class=""><code>--tint-composited-content</code></li>
<li class=""><code>--tint-composited-content-modulate</code></li>
<li class="">(And more)</li>
</ul>
<p>They highlight areas of the browser window that were redrawn or updated by different parts of the Chromium graphics stack.</p>
<p>That allowed me to see which part of the graphics stack was producing which output.</p>
<p>In particular, the combination of <code>--tint-composited-content</code> and <code>--tint-composited-content-modulate</code> was really helpful. The former adds a tint to the output of the compositor. The latter changes the tint color on every frame.</p>
<p><img decoding="async" loading="lazy" alt="Screenshot of Chromium with the --tint-composited-content flag" src="https://electronjs.org/zh/assets/images/tinting-composited-content-07a6dd4403f9d11c087c76cbc0a21d85.png" width="3022" height="1810" class="img_ev3q"></p>
<p>In the screenshot, the cyan-tinted frame was the last frame that was being drawn.</p>
<p>The jank to the right of that frame was not tinted cyan. It was tinted in different colors that were still there from previous frames. This indicated that the jank was not coming from the compositor. The compositor was sending the right output.</p>
<p>The compositor is part of Chromium's graphics stack. The following is very simplified, but for the purpose of this blog post you can imagine it like this:</p>
<ol>
<li class="">The compositor <code>cc</code> produces a <code>CompositorFrame</code>, which contains draw instructions.</li>
<li class=""><code>cc</code> sends that <code>CompositorFrame</code> to the display compositor <code>viz</code>.</li>
<li class=""><code>viz</code> then draws the frame and shows it on screen.</li>
</ol>
<p>Tinting each <code>CompositorFrame</code> showed that the compositor produced the right output. So the issue had to be in the display compositor <code>viz</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="locating-the-relevant-viz-code">Locating the relevant <code>viz</code> code<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#locating-the-relevant-viz-code" class="hash-link" aria-label="链接到 locating-the-relevant-viz-code" title="链接到 locating-the-relevant-viz-code" translate="no">​</a></h2>
<p>From there, I started searching for mentions of Direct3D in the <code>viz</code> source code.</p>
<p><em>Note: From here on, the post will get a bit more technical and reference source code symbols.</em></p>
<p>I found that on the ANGLE Direct3D 11 backend, Chromium uses the Windows <a href="https://learn.microsoft.com/en-us/windows/win32/directcomp/directcomposition-portal" target="_blank" rel="noopener noreferrer" class="">DirectComposition</a> API for drawing the window contents.</p>
<p>Chromium's DirectComposition <code>OutputSurface</code> differs from most other output surfaces in Chromium. It has the capability <code>supports_viewporter</code> (<a href="https://source.chromium.org/chromium/chromium/src/+/main:ui/gl/dcomp_presenter.cc;l=144-146;drc=1cffe9643e1e70f1f369bbb28e015d9c5f968546" target="_blank" rel="noopener noreferrer" class="">source link 1</a>, <a href="https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/output_surface.h;l=100-103;drc=c96a878b1cb45f60aac2285ffbdbd6b53dc92415" target="_blank" rel="noopener noreferrer" class="">source link 2</a>).</p>
<p>An output surface is a bitmap that can be drawn to, often backed by a GPU texture.</p>
<p>Without <code>supports_viewporter</code>, whenever the window size changes, Chromium will create a new output surface matching the new window size. Then it will draw on that surface and show it.</p>
<p><code>supports_viewporter</code> tries to reduce these costly surface allocations. With <code>supports_viewporter</code>, Chromium will not allocate a new surface on every resize. Instead, it will allocate a surface that is too large for what we need to draw. Then it will only paint to and show a certain sub-rectangle (the "viewport") of that surface on screen. The other parts of the surface are not supposed to be shown on screen.</p>
<p>This is supposed to make resizing more efficient because all Chromium needs to do is pad the surface to the proper width and height instead of allocating a new surface on every resize. This surface resize logic lives in <a href="https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/direct_renderer.cc;l=1082;drc=c96a878b1cb45f60aac2285ffbdbd6b53dc92415" target="_blank" rel="noopener noreferrer" class=""><code>direct_renderer.cc</code></a>.</p>
<p>Here's what that looks like:</p>
<p><img decoding="async" loading="lazy" alt="Visualization showing the surface, viewport, and clip rect" src="https://electronjs.org/zh/assets/images/visualization-1-da8acf1dbc52d6530cc4d1654c396a46.png" width="2363" height="1074" class="img_ev3q"></p>
<p>Let me explain:</p>
<ul>
<li class="">The blue rectangle is our surface.</li>
<li class="">The green area is our viewport, i.e., the area of the surface that is supposed to be visible and that we actively draw to.</li>
<li class="">The red rectangle is our clip rect(angle), i.e., the part of the surface that is actually being shown on screen.</li>
</ul>
<p>As a performance optimization, only the viewport (the green area) is repainted when we get a new frame. The rest is left unchanged. This is important. We only ever repaint the green viewport. We don't update the areas outside of the viewport.</p>
<p>When we resize the window, what's supposed to happen is that in an atomic transaction (= at the exact same time) we repaint the viewport (= the area that's supposed to be visible on screen) and then update the clip rect to clip the surface to the new viewport size.</p>
<p>After the resize, it should look like this:</p>
<p><img decoding="async" loading="lazy" alt="Visualization with updated viewport and clip rect" src="https://electronjs.org/zh/assets/images/visualization-2-c94901caccb784bed5548e159abf88d8.png" width="2363" height="1074" class="img_ev3q"></p>
<p>And that's where we get to the first of our two bugs.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="first-bug">First bug<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#first-bug" class="hash-link" aria-label="链接到 First bug" title="链接到 First bug" translate="no">​</a></h2>
<p>Sometimes these operations can get out of sync. For example, the clip rect might get updated before the viewport is repainted. Then we get a result like this:</p>
<p><img decoding="async" loading="lazy" alt="Visualization where the clip rect was updated before the viewport" src="https://electronjs.org/zh/assets/images/visualization-3-591fc7ac330ff6a128a21a77c1d7a5a7.png" width="2363" height="1074" class="img_ev3q"></p>
<p>We still show the old frame in the green viewport. But the clip rect has become larger and we show areas of the surface that we haven't repainted yet.</p>
<p>On the first resize of a window, these areas would be black. On the second resize, those areas would be filled with old pixel values. They would show whatever we had previously painted in those areas.</p>
<p>Similarly, in a certain edge case while making the window smaller, we would sometimes repaint the viewport before we would update the clip rect.</p>
<p><img decoding="async" loading="lazy" alt="Visualization where the viewport was repainted before the clip rect was updated" src="https://electronjs.org/zh/assets/images/visualization-4-f3426cb7df0dcf75d76bf465c5f9c8fe.png" width="2363" height="1074" class="img_ev3q"></p>
<p>Then parts of the clip rect would still show the previous frame because the new frame was smaller and we did not repaint any areas beyond the new viewport.</p>
<p>Now why do these operations not happen in sync?</p>
<p>We use two different Windows APIs here:</p>
<ul>
<li class=""><a href="https://source.chromium.org/chromium/chromium/src/+/main:gpu/command_buffer/service/shared_image/dxgi_swap_chain_image_backing.cc;l=283;drc=92e802d8fa66bafb0cca9ed32143d6148d8e0411" target="_blank" rel="noopener noreferrer" class=""><code>IDXGISwapChain1::Present1</code></a> — This shows the new pixels on screen / updates the new viewport.</li>
<li class=""><a href="https://source.chromium.org/chromium/chromium/src/+/main:ui/gl/dc_layer_tree.cc;l=1034;drc=35d26d364efb57d0386b98312ba739f7f65ae97e" target="_blank" rel="noopener noreferrer" class=""><code>IDCompositionDevice::Commit</code></a> — This updates the clip rect.</li>
</ul>
<p>Here's what's important to understand: both functions return synchronously on the CPU. However, they schedule tasks that run asynchronously on the GPU at a later time. Windows and its services (such as <a href="https://en.wikipedia.org/wiki/Desktop_Window_Manager" target="_blank" rel="noopener noreferrer" class="">DWM</a>) decide when these tasks will run and in which order. So they take effect asynchronously, and not always within the same frame.</p>
<p>Unfortunately, Windows provides no way for us to synchronize those operations. So I had to find other approaches to fix this.</p>
<p>There were two options that I evaluated with the Chromium maintainers:</p>
<ol>
<li class="">While resizing, paint all previously drawn areas outside of the viewport transparent. This makes those areas invisible. It fixes the artifacts.</li>
<li class="">While resizing, switch from an <code>IDXGISwapChain1</code> to a DirectComposition surface which synchronizes updates with <code>IDCompositionDevice::Commit</code>. This also fixes the artifacts.</li>
</ol>
<p>We went with the first option because it leads to faster resizes than the second option.</p>
<p>I landed a <a href="https://crrev.com/c/7115438" target="_blank" rel="noopener noreferrer" class="">patch</a> in Chromium that implemented that first solution.</p>
<p>I also submitted two other patches in preparation for the main patch:</p>
<ol>
<li class="">The <a href="https://crrev.com/c/7129658" target="_blank" rel="noopener noreferrer" class="">first one</a> fixed a bug in existing code that would make CI fail in combination with the main patch. It also made launching Electron apps and Chrome a tiny bit faster.</li>
<li class="">The <a href="https://crrev.com/c/7210913" target="_blank" rel="noopener noreferrer" class="">second one</a> was split off to make code review easier on the main patch.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="second-bug">Second bug<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#second-bug" class="hash-link" aria-label="链接到 Second bug" title="链接到 Second bug" translate="no">​</a></h2>
<p>In addition to this first bug, there was a second bug which also led to stale pixels.</p>
<p>Here's what was going on there:</p>
<p>When the user resizes the window, Chromium needs to redraw the contents of the window for the new window size. This takes some time. The new frame isn't ready immediately.</p>
<p>Here's a sequence of frames that demonstrates this:</p>
<p><img decoding="async" loading="lazy" alt="First frame of the Chromium resize sequence" src="https://electronjs.org/zh/assets/images/chromium-resize-sequence-1-1506e1883e774679eb634cc3015ed384.png" width="3248" height="2120" class="img_ev3q">
<img decoding="async" loading="lazy" alt="Second frame of the Chromium resize sequence" src="https://electronjs.org/zh/assets/images/chromium-resize-sequence-2-222088171e9defb86b9c67a1844d9ef0.png" width="3248" height="2120" class="img_ev3q">
<img decoding="async" loading="lazy" alt="Third frame of the Chromium resize sequence" src="https://electronjs.org/zh/assets/images/chromium-resize-sequence-3-3195950f19df4d5e2d5554d2318f28d9.png" width="3248" height="2120" class="img_ev3q">
<img decoding="async" loading="lazy" alt="Fourth frame of the Chromium resize sequence" src="https://electronjs.org/zh/assets/images/chromium-resize-sequence-4-5368a92b507d2201821905db0418caa7.png" width="3248" height="2120" class="img_ev3q">
<img decoding="async" loading="lazy" alt="Fifth frame of the Chromium resize sequence" src="https://electronjs.org/zh/assets/images/chromium-resize-sequence-5-f924ee4ceedd3fc9b0546740ed2d5893.png" width="3248" height="2120" class="img_ev3q"></p>
<p>At a certain time during the resize, Windows tells us: "The window is 1,000 pixels wide." But the frames that the browser compositor produces are lagging behind. The last frame that we have painted might be 600 pixels wide.</p>
<p>Historically, Chromium used to skip frames where the width of the window did not match the width of the frame that it last painted. It would decide to just not update the window.</p>
<p>However, that would often lead to the window contents not being updated at all until the resize operation was finished.</p>
<p>So <a href="https://crrev.com/1426453006" target="_blank" rel="noopener noreferrer" class="">in 2015</a> someone decided: "Why not show these frames? They might not match the window size perfectly, but at least we can show <em>something</em>."</p>
<p>It would lead to gutter, but at that time the gutter was black. So that was better than the previous implementation.</p>
<p>Now, 10 years later with DirectComposition, that gutter was often filled with stale pixels.</p>
<p>Let's look at what was happening there:</p>
<p>Every frame consists of multiple render passes. These render passes represent the various things that should be drawn on screen. From complicated bitmaps to rectangles filled with solid colors.</p>
<p>Every frame has a root render pass, which contains all other render passes and glues them together. (Render passes are arranged in a tree structure and the root render pass is the root of that tree.)</p>
<p>So now during a resize, we'd get to a point where we know the window is 1,000 pixels wide. Accordingly, we'd adjust the viewport of our output surface to also be 1,000 pixels wide. But the frame that we just received is only 600 pixels wide.</p>
<p>The <a href="https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/display.cc;l=1053-1062;drc=152a83bb9fcba4ea3a7b9f8efbe0f6204f95eadd" target="_blank" rel="noopener noreferrer" class="">optimization from 2015</a> would then go and change the width of the root render pass to also be 1,000 pixels. But it wouldn't change what the render passes would actually draw on screen. They'd still only contain instructions to draw a picture that is 600 pixels wide.</p>
<p>Here's what that would look like:</p>
<p><img decoding="async" loading="lazy" alt="Visualization where the frame is smaller than the viewport" src="https://electronjs.org/zh/assets/images/visualization-5-5b9be2d5809799e6576c0e3b344c8c7a.png" width="2363" height="1074" class="img_ev3q"></p>
<p>The yellow area is the area in which the render passes of the frame actually drew something. It's 600 pixels wide.</p>
<p>However, our green viewport and our red clip rect are 1,000 pixels wide. That's the area that we show on screen. (After all, the width attribute of the root render pass claimed that it would redraw the full area of 1,000 pixels.)</p>
<p>But because we had no draw instructions for the 400 pixels on the right, those areas didn't get updated.</p>
<p>On the first resize, we'd show black pixels there. (That's the color that we initialize the surface with.)</p>
<p>On subsequent resizes, those areas would show whatever was drawn to them before. We'd see stale pixels.</p>
<p>I landed a fix for this issue in <a href="https://crrev.com/c/7156576" target="_blank" rel="noopener noreferrer" class="">crrev.com/c/7156576</a>.</p>
<p>The fix changes what we do when we receive a frame with a different size than our window. Instead of resizing the frame and adding gutter that contains stale pixels, we <a href="https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc;l=555-556;drc=78bd63326c0a2489e6b016140aa4d84014af077a" target="_blank" rel="noopener noreferrer" class="">resize our viewport</a> and our clip rect.</p>
<p><img decoding="async" loading="lazy" alt="Visualization where the clip rect and viewport size are adjusted to the frame size" src="https://electronjs.org/zh/assets/images/visualization-6-182bf0c8c2f7577069b24e766535e5d9.png" width="2363" height="1074" class="img_ev3q"></p>
<p>We clip our surface to the size of the frame that we received. We don't show anything beyond the 600 pixels that we have draw instructions for.</p>
<p>Voilà, no more gutter, no more stale pixels!</p>
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>note</div><div class="admonitionContent_BuS1"><p>Without <code>supports_viewporter</code>, this would be an expensive operation because it would allocate a new output surface. However, with DirectComposition, we use the "viewporter" feature. So we don't reallocate the surface when we change the viewport size. We just make a different portion of it visible. Thus, it is a cheap operation.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="backporting-the-patches-to-electron">Backporting the patches to Electron<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#backporting-the-patches-to-electron" class="hash-link" aria-label="链接到 Backporting the patches to Electron" title="链接到 Backporting the patches to Electron" translate="no">​</a></h2>
<p>Once the fixes made it into Chromium, we had to pull them into Electron, too.</p>
<p>On the <code>main</code> branch, Electron updates its Chromium version constantly. As a result, the patches were merged into <code>main</code> in a <a href="https://github.com/electron/electron/pull/49145" target="_blank" rel="noopener noreferrer" class="">Chromium roll PR</a>.</p>
<p>However, commits that make it into <code>main</code> right now will only be included in an Electron release in about three months. Our existing release and pre-release <a class="" href="https://electronjs.org/zh/docs/latest/tutorial/electron-versioning#stabilization-branches">branches</a> run on older Chromium versions.</p>
<p>Thus, the next step was to backport the patches to <a href="https://github.com/electron/electron/pull/49138" target="_blank" rel="noopener noreferrer" class="">Electron 39</a> and <a href="https://github.com/electron/electron/pull/49191" target="_blank" rel="noopener noreferrer" class="">Electron 40</a>.</p>
<p>Electron keeps a list of Chromium patches in the <a href="https://github.com/electron/electron/tree/a90ccc753b4d38266323dd054db2b98a45917117/patches/chromium" target="_blank" rel="noopener noreferrer" class=""><code>patches/chromium</code> directory</a>. When we backport a Chromium patch, we add it there. When building Electron, these patches are applied to the Chromium source code.</p>
<p>(In general, we try to <a class="" href="https://electronjs.org/zh/docs/latest/development/patches#patch-justification">keep the number</a> of Chromium patches low. Every patch can lead to merge conflicts during Chromium updates. The maintenance burden from patches is real.)</p>
<p>The Electron 39 <a href="https://github.com/electron/electron/pull/49138" target="_blank" rel="noopener noreferrer" class="">backport PR</a> was merged pretty quickly. The fix became part of <a href="https://releases.electronjs.org/release/v39.2.6" target="_blank" rel="noopener noreferrer" class="">Electron 39.2.6</a>. 🎉</p>
<p>If you resize a window on Electron 39.2.6 or later, you'll see no more stale pixels.</p>
<p><em>(The patches are also part of <a href="https://www.google.com/chrome/canary/" target="_blank" rel="noopener noreferrer" class="">Google Chrome Canary</a>. They should be part of a stable Google Chrome release in February 2026.)</em></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="谢谢">谢谢！<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#%E8%B0%A2%E8%B0%A2" class="hash-link" aria-label="链接到 谢谢！" title="链接到 谢谢！" translate="no">​</a></h2>
<p>Big thanks to <a href="https://www.plasticity.xyz/" target="_blank" rel="noopener noreferrer" class="">Plasticity</a> for funding this work!</p>
<p>Thanks to Michael Tang and Vasiliy Telezhnikov from the Chromium team for their help.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="final-thoughts">Final thoughts<a href="https://electronjs.org/zh/blog/tech-talk-window-resize-behavior#final-thoughts" class="hash-link" aria-label="链接到 Final thoughts" title="链接到 Final thoughts" translate="no">​</a></h2>
<p>This was the hardest bug I have ever worked on (and I have worked on many hard bugs in 18 years of writing software).</p>
<p>But it was also one of the most fun projects I have ever worked on.</p>
<p>If you found this interesting, please consider <a href="https://github.com/electron/electron/" target="_blank" rel="noopener noreferrer" class="">contributing to Electron</a>! We love seeing new faces.</p>]]></content:encoded>
            <category>Tech Talk</category>
            <category>Electron Internals</category>
        </item>
        <item>
            <title><![CDATA[12月安静期(2025年12月)]]></title>
            <link>https://electronjs.org/zh/blog/dec-quiet-period-25</link>
            <guid>https://electronjs.org/zh/blog/dec-quiet-period-25</guid>
            <pubDate>Fri, 28 Nov 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Starting December 1, the Electron project will enter a quiet period before picking back up at full capacity in January 2026. For full details, see the Policies section below.]]></description>
            <content:encoded><![CDATA[<p>Starting December 1, the Electron project will enter a quiet period before picking back up at full capacity in January 2026. For full details, see the <a class="" href="https://electronjs.org/zh/blog/dec-quiet-period-25#quiet-period-policies">Policies</a> section below.</p>
<div style="width:100%;height:0;padding-bottom:56%;position:relative;margin:2rem 0"><iframe src="https://giphy.com/embed/xUA7b5i7joquX9Cp8I" width="100%" height="100%" style="position:absolute" frameborder="0"></iframe></div>
<p>Since 2020, December has been a time for project maintainers to take a breather from regular maintenance duties in order to take a break or focus on heads-down work. This break helps us rest up and come back energized for the year to come.</p>
<p>That said, a month-long pause like this one is only achievable when an open-source project is in a healthy state—we’d like to thank all maintainers and external contributors for all of their continued efforts to keep the project moving. ❤️</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2025-in-review">2025 in review<a href="https://electronjs.org/zh/blog/dec-quiet-period-25#2025-in-review" class="hash-link" aria-label="链接到 2025 in review" title="链接到 2025 in review" translate="no">​</a></h2>
<p>As we close out the year, we’d like to highlight some of the projects we’ve accomplished. Here are some things we were proud of in 2025:</p>
<ul>
<li class="">⚛️&nbsp;Shipped 6 new major versions of Electron in tandem with every other Chromium major version.</li>
<li class="">🌿&nbsp;Migrated Electron’s build tooling from Ninja to Chromium’s new <a href="https://groups.google.com/a/chromium.org/g/chromium-dev/c/v-WOvWUtOpg" target="_blank" rel="noopener noreferrer" class="">siso</a> build system, which adds native remote execution support.</li>
<li class="">✨&nbsp;Revamped the <a href="http://releases.electronjs.org/" target="_blank" rel="noopener noreferrer" class="">releases.electronjs.org</a> page with a fresh new design.</li>
<li class="">✅&nbsp;Accepted four new <a href="https://github.com/electron/rfcs" target="_blank" rel="noopener noreferrer" class="">RFCs</a> and implemented two others into <code>electron/electron</code>.</li>
<li class="">☀️&nbsp;Completed two new <a href="https://summerofcode.withgoogle.com/" target="_blank" rel="noopener noreferrer" class="">Google Summer of Code</a> projects:<!-- -->
<ul>
<li class="">The <a href="https://github.com/electron/devtron/" target="_blank" rel="noopener noreferrer" class="">Devtron</a> DevTools IPC tracker Extension is now available via <code>npm install --save-dev @electron/devtron</code>.</li>
<li class="">The <a href="https://github.com/electron/rfcs/blob/main/text/0016-save-restore-window-state.md" target="_blank" rel="noopener noreferrer" class="">Save/Restore Window State API</a> for Electron’s <code>BaseWindow</code> module was accepted as an RFC and is awaiting its final merge in Electron core.</li>
</ul>
</li>
<li class="">📦&nbsp;Released modernized major versions for all <code>@electron/</code> npm packages as ECMAScript modules requiring at least Node 22.</li>
<li class="">🔒&nbsp;Moved package publishing from <a href="https://docs.continuousauth.dev/" target="_blank" rel="noopener noreferrer" class="">Continuous Auth</a> to the new token-less OIDC-based <a href="https://docs.npmjs.com/trusted-publishers" target="_blank" rel="noopener noreferrer" class="">trusted publishing</a> system in light of security incidents in the npm ecosystem.</li>
<li class="">🧑‍💻 Onboarded five new maintainers who help us ship great software every day and keep the project running long-term.</li>
</ul>
<p><strong>Thanks for a great year, and see you in 2026!</strong></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="quiet-period-policies">Quiet period policies<a href="https://electronjs.org/zh/blog/dec-quiet-period-25#quiet-period-policies" class="hash-link" aria-label="链接到 Quiet period policies" title="链接到 Quiet period policies" translate="no">​</a></h2>
<p>Not much has changed from previous years, but we changed some of the wording around issue and pull request reviews to temper expectations but allow maintainers to continue to engage with the project as much as they want.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="12月保持不变的内容">12月保持不变的内容<a href="https://electronjs.org/zh/blog/dec-quiet-period-25#12%E6%9C%88%E4%BF%9D%E6%8C%81%E4%B8%8D%E5%8F%98%E7%9A%84%E5%86%85%E5%AE%B9" class="hash-link" aria-label="链接到 12月保持不变的内容" title="链接到 12月保持不变的内容" translate="no">​</a></h3>
<ol>
<li class="">必要时将发布零日和其他与安全相关的主版本。 Security incidents should be reported via the escalation policy outlined in the <a href="https://github.com/electron/electron/blob/main/SECURITY.md" target="_blank" rel="noopener noreferrer" class="">SECURITY.md</a> document.</li>
<li class=""><a href="https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md" target="_blank" rel="noopener noreferrer" class="">Code of Conduct</a> reports and moderation will continue.</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="12月变动的内容">12月变动的内容<a href="https://electronjs.org/zh/blog/dec-quiet-period-25#12%E6%9C%88%E5%8F%98%E5%8A%A8%E7%9A%84%E5%86%85%E5%AE%B9" class="hash-link" aria-label="链接到 12月变动的内容" title="链接到 12月变动的内容" translate="no">​</a></h3>
<ol>
<li class="">The last stable branch releases of the year for Electron 37, 38, and 39 will occur on the week of December 1st. 12月没有额外的计划发行版本。</li>
<li class="">There will be no nightly, alpha and beta releases for the last two weeks of December.</li>
<li class="">Regular <a href="https://github.com/electron/governance" target="_blank" rel="noopener noreferrer" class="">Working Group</a> meetings will be paused.</li>
<li class="">Issue triage may be delayed.</li>
<li class="">Pull request reviews and merges may be delayed.</li>
</ol>]]></content:encoded>
            <category>Project News</category>
        </item>
        <item>
            <title><![CDATA[Electron 39.0.0]]></title>
            <link>https://electronjs.org/zh/blog/electron-39-0</link>
            <guid>https://electronjs.org/zh/blog/electron-39-0</guid>
            <pubDate>Tue, 28 Oct 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 39.0.0 已发布！ 它包括对 Chromium 142.0.7444.52、V8 14.2 和 Node 22.20.0 的升级。]]></description>
            <content:encoded><![CDATA[<p>Electron 39.0.0 已发布！ 它包括对 Chromium 142.0.7444.52、V8 14.2 和 Node 22.20.0 的升级。</p>
<hr>
<p>Electron 团队很高兴发布了 Electron 39.0.0 ！ 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://bsky.app/profile/electronjs.org" target="_blank" rel="noopener noreferrer" class="">Bluesky</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重要变化">重要变化<a href="https://electronjs.org/zh/blog/electron-39-0#%E9%87%8D%E8%A6%81%E5%8F%98%E5%8C%96" class="hash-link" aria-label="链接到 重要变化" title="链接到 重要变化" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="asar-integrity-graduates-to-stable">ASAR Integrity graduates to stable<a href="https://electronjs.org/zh/blog/electron-39-0#asar-integrity-graduates-to-stable" class="hash-link" aria-label="链接到 ASAR Integrity graduates to stable" title="链接到 ASAR Integrity graduates to stable" translate="no">​</a></h3>
<p>A long-standing "experimental" feature -- ASAR integrity -- is now stable in Electron 39. When you enable this feature, it validates your packaged <code>app.asar</code> at runtime against a build-time hash to detect any tampering. 如果没有提供哈希值或者哈希值不一致，应用将会被强制终止运行。</p>
<p>See <a href="https://www.electronjs.org/docs/latest/tutorial/asar-integrity" target="_blank" rel="noopener noreferrer" class="">the ASAR integrity documentation</a> for full information on how on the feature works, on how to use it in your application, and how to use it in Electron Forge and Electron Packager.</p>
<p>In related news, <a href="https://github.com/electron/packager" target="_blank" rel="noopener noreferrer" class="">Electron Packager</a> v19 now enables ASAR by default. <a href="https://github.com/electron/packager/pull/1841" target="_blank" rel="noopener noreferrer" class="">#1841</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-39-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">Chromium <code>142.0.7444.52</code>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-142" target="_blank" rel="noopener noreferrer" class="">142 新功能</a></li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-141" target="_blank" rel="noopener noreferrer" class="">141 新功能</a></li>
</ul>
</li>
<li class="">Node <code>22.20.0</code>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v22.20.0" target="_blank" rel="noopener noreferrer" class="">v22.20.0 Announcement</a></li>
<li class=""><a href="https://nodejs.org/en/blog/release/v22.19.0" target="_blank" rel="noopener noreferrer" class="">v22.19.0 Announcement</a></li>
</ul>
</li>
<li class="">V8 <code>14.2</code>
<ul>
<li class=""><a href="https://chromium.googlesource.com/v8/v8.git/+/bb294624702efbb17691b642333f06bf5108e600" target="_blank" rel="noopener noreferrer" class="">V8 roll increment</a></li>
</ul>
</li>
</ul>
<p>Electron 39 upgrades Chromium from <code>140.0.7339.41</code> to <code>142.0.7444.52</code>, Node.js from <code>22.18.0</code> to <code>v22.20.0</code>, and V8 from <code>14.0</code> to <code>14.2</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-features-and-improvements">New Features and Improvements<a href="https://electronjs.org/zh/blog/electron-39-0#new-features-and-improvements" class="hash-link" aria-label="链接到 New Features and Improvements" title="链接到 New Features and Improvements" translate="no">​</a></h2>
<ul>
<li class="">添加 <code>app.isHardwareAccelerationEnabled()</code>。 <a href="https://github.com/electron/electron/pull/48680" target="_blank" rel="noopener noreferrer" class="">#48680</a></li>
<li class="">Added <code>RGBAF16</code> output format with scRGB HDR color space support to Offscreen Rendering. <a href="https://github.com/electron/electron/pull/48504" target="_blank" rel="noopener noreferrer" class="">#48504</a></li>
<li class="">Added methods to enable more granular accessibility support management. <a href="https://github.com/electron/electron/pull/48625" target="_blank" rel="noopener noreferrer" class="">#48625</a></li>
<li class="">Added support for <code>USBDevice.configurations</code>. <a href="https://github.com/electron/electron/pull/47459" target="_blank" rel="noopener noreferrer" class="">#47459</a></li>
<li class="">Added the ability to retrieve the system accent color on Linux using <code>systemPreferences.getAccentColor</code>. <a href="https://github.com/electron/electron/pull/48628" target="_blank" rel="noopener noreferrer" class="">#48628</a></li>
<li class="">Allowed for persisting File System API grant status within a given session. <a href="https://github.com/electron/electron/pull/48326" target="_blank" rel="noopener noreferrer" class="">#48326</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/48328" target="_blank" rel="noopener noreferrer" class="">37</a>, <a href="https://github.com/electron/electron/pull/48327" target="_blank" rel="noopener noreferrer" class="">38</a>)</sup></li>
<li class="">Support dynamic ESM imports in non-context isolated preloads. <a href="https://github.com/electron/electron/pull/48488" target="_blank" rel="noopener noreferrer" class="">#48488</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/48487" target="_blank" rel="noopener noreferrer" class="">37</a>, <a href="https://github.com/electron/electron/pull/48489" target="_blank" rel="noopener noreferrer" class="">38</a>)</sup></li>
<li class="">Marked the <a href="https://www.electronjs.org/docs/latest/tutorial/asar-integrity" target="_blank" rel="noopener noreferrer" class="">ASAR integrity</a> feature as stable. It had previously been experimental. <a href="https://github.com/electron/electron/pull/48434" target="_blank" rel="noopener noreferrer" class="">#48434</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-39-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deprecated---host-rules-command-line-switch">Deprecated: <code>--host-rules</code> command line switch<a href="https://electronjs.org/zh/blog/electron-39-0#deprecated---host-rules-command-line-switch" class="hash-link" aria-label="链接到 deprecated---host-rules-command-line-switch" title="链接到 deprecated---host-rules-command-line-switch" translate="no">​</a></h3>
<p>Chromium is deprecating the <code>--host-rules</code> switch.</p>
<p>You should use <code>--host-resolver-rules</code> instead.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-windowopen-popups-are-always-resizable">Behavior Changed: <code>window.open</code> popups are always resizable<a href="https://electronjs.org/zh/blog/electron-39-0#behavior-changed-windowopen-popups-are-always-resizable" class="hash-link" aria-label="链接到 behavior-changed-windowopen-popups-are-always-resizable" title="链接到 behavior-changed-windowopen-popups-are-always-resizable" translate="no">​</a></h3>
<p>Per current <a href="https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-open-dev" target="_blank" rel="noopener noreferrer" class="">WHATWG spec</a>, the <code>window.open</code> API will now always create a resizable popup window.</p>
<p>To restore previous behavior:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">setWindowOpenHandler</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">details</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">action</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'allow'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token literal-property property" style="color:#36acaa">overrideBrowserWindowOptions</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">resizable</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> details</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">features</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">includes</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'resizable=yes'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-nsaudiocaptureusagedescription-should-be-included-in-your-apps-infoplist-file-to-use-desktopcapturer--macos-142">Behavior Changed: <code>NSAudioCaptureUsageDescription</code> should be included in your app's Info.plist file to use <code>desktopCapturer</code> (🍏 macOS ≥14.2)<a href="https://electronjs.org/zh/blog/electron-39-0#behavior-changed-nsaudiocaptureusagedescription-should-be-included-in-your-apps-infoplist-file-to-use-desktopcapturer--macos-142" class="hash-link" aria-label="链接到 behavior-changed-nsaudiocaptureusagedescription-should-be-included-in-your-apps-infoplist-file-to-use-desktopcapturer--macos-142" title="链接到 behavior-changed-nsaudiocaptureusagedescription-should-be-included-in-your-apps-infoplist-file-to-use-desktopcapturer--macos-142" translate="no">​</a></h3>
<p>Due to a <a href="https://source.chromium.org/chromium/chromium/src/+/ad17e8f8b93d5f34891b06085d373a668918255e" target="_blank" rel="noopener noreferrer" class="">Chromium update</a> which enables Apple's newer <a href="https://developer.apple.com/documentation/CoreAudio/capturing-system-audio-with-core-audio-taps#Configure-the-sample-code-project" target="_blank" rel="noopener noreferrer" class="">CoreAudio Tap API</a> by default, you now must have <code>NSAudioCaptureUsageDescription</code> defined in your <code>Info.plist</code> to use <code>desktopCapturer</code>.</p>
<p>Electron's <code>desktopCapturer</code> will create a dead audio stream if the new permission is absent. However, no errors or warnings will occur. This is partially a side-effect of Chromium not falling back to the older <code>Screen &amp; System Audio Recording</code> permissions system if the new system fails.</p>
<p>To restore previous behavior:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">//main.js (right beneath your require/import statments)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">commandLine</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">appendSwitch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string" style="color:#e3116c">'disable-features'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string" style="color:#e3116c">'MacCatapLoopbackAudioForScreenShare'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-shared-texture-osr-paint-event-data-structure">Behavior Changed: shared texture OSR <code>paint</code> event data structure<a href="https://electronjs.org/zh/blog/electron-39-0#behavior-changed-shared-texture-osr-paint-event-data-structure" class="hash-link" aria-label="链接到 behavior-changed-shared-texture-osr-paint-event-data-structure" title="链接到 behavior-changed-shared-texture-osr-paint-event-data-structure" translate="no">​</a></h3>
<p>When using the shared texture offscreen rendering feature, the <code>paint</code> event now emits a more structured object.
It moves the <code>sharedTextureHandle</code>, <code>planes</code>, <code>modifier</code> into a unified <code>handle</code> property.
See <a href="https://www.electronjs.org/docs/latest/api/structures/offscreen-shared-texture" target="_blank" rel="noopener noreferrer" class="">the <code>OffscreenSharedTexture</code> documentation</a> for more details.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="终止对-36xy-的支持">终止对 36.x.y 的支持<a href="https://electronjs.org/zh/blog/electron-39-0#%E7%BB%88%E6%AD%A2%E5%AF%B9-36xy-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 终止对 36.x.y 的支持" title="链接到 终止对 36.x.y 的支持" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 36.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。</p>
<table><thead><tr><th>E39 (Oct'25)</th><th>E40 (Jan'26)</th><th>E41 (Feb'26)</th></tr></thead><tbody><tr><td>39.x.y</td><td>40.x.y</td><td>41.x.y</td></tr><tr><td>38.x.y</td><td>39.x.y</td><td>40.x.y</td></tr><tr><td>37.x.y</td><td>38.x.y</td><td>39.x.y</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-39-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
        <item>
            <title><![CDATA[Electron 38.0.0]]></title>
            <link>https://electronjs.org/zh/blog/electron-38-0</link>
            <guid>https://electronjs.org/zh/blog/electron-38-0</guid>
            <pubDate>Tue, 09 Sep 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 38.0.0 已发布！ 它包括对 Chromium 140.0.7339.41、V8 14.0 和 Node 22.16.0 的升级。]]></description>
            <content:encoded><![CDATA[<p>Electron 38.0.0 已发布！ 它包括对 Chromium 140.0.7339.41、V8 14.0 和 Node 22.16.0 的升级。</p>
<hr>
<p>Electron 团队很高兴发布了 Electron 38.0.0 ！ 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://bsky.app/profile/electronjs.org" target="_blank" rel="noopener noreferrer" class="">Bluesky</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-38-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">Chromium <code>140.0.7339.41</code>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-140/" target="_blank" rel="noopener noreferrer" class="">140 新功能</a></li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-139/" target="_blank" rel="noopener noreferrer" class="">139 新功能</a></li>
</ul>
</li>
<li class="">Node <code>22.18.0</code>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v22.18.0/" target="_blank" rel="noopener noreferrer" class="">Node 22.18.0 博客</a></li>
</ul>
</li>
<li class="">V8 <code>14.0</code>
<ul>
<li class=""><a href="https://chromium.googlesource.com/v8/v8.git/+/fdb12b460f148895f6af2ff0e0d870ff8889f154" target="_blank" rel="noopener noreferrer" class="">V8 roll increment</a></li>
</ul>
</li>
</ul>
<p>Electron 38 将 Chromium 从 <code>138.0.7204.35</code> 升级到 <code>140.0.7339.41</code>， Node 从 <code>22.16.0</code> 升级到 <code>22.18.0</code> 以及 V8 从 <code>13.8</code> 升级到 <code>14.0</code>。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-features-and-improvements">New Features and Improvements<a href="https://electronjs.org/zh/blog/electron-38-0#new-features-and-improvements" class="hash-link" aria-label="链接到 New Features and Improvements" title="链接到 New Features and Improvements" translate="no">​</a></h2>
<ul>
<li class="">Added support for customizing system accent color and highlighting of active window border. <a href="https://github.com/electron/electron/pull/47285" target="_blank" rel="noopener noreferrer" class="">#47285</a> (Also in <a href="https://github.com/electron/electron/pull/47537" target="_blank" rel="noopener noreferrer" class="">37</a>)</li>
<li class="">Added <code>fileBacked</code> and <code>purgeable</code> fields to <code>process.getSystemMemoryInfo()</code> for macOS. <a href="https://github.com/electron/electron/pull/48146" target="_blank" rel="noopener noreferrer" class="">#48146</a> (Also in <a href="https://github.com/electron/electron/pull/48143" target="_blank" rel="noopener noreferrer" class="">37</a>)</li>
<li class="">Added support for <code>guid</code> <code>Tray</code> constructor option on macOS to allow tray icons to maintain position across launches. <a href="https://github.com/electron/electron/pull/48077" target="_blank" rel="noopener noreferrer" class="">#48077</a> (Also in <a href="https://github.com/electron/electron/pull/48076" target="_blank" rel="noopener noreferrer" class="">37</a>)</li>
<li class="">Added <code>webFrameMain.fromFrameToken(processId, frameToken)</code> to get a <code>WebFrameMain</code> instance from its frame token. <a href="https://github.com/electron/electron/pull/47942" target="_blank" rel="noopener noreferrer" class="">#47942</a></li>
<li class="">Added support for <code>app.getRecentDocuments()</code> on Windows and macOS. <a href="https://github.com/electron/electron/pull/47924" target="_blank" rel="noopener noreferrer" class="">#47924</a> (Also in <a href="https://github.com/electron/electron/pull/47923" target="_blank" rel="noopener noreferrer" class="">37</a>)</li>
<li class="">Internally switched to using <code>DIR_ASSETS</code> instead of <code>DIR_MODULE</code>/<code>DIR_EXE</code> to locate assets and resources, and added "assets" as a key that can be queried via <code>app.getPath</code>. <a href="https://github.com/electron/electron/pull/47950" target="_blank" rel="noopener noreferrer" class="">#47950</a> (Also in <a href="https://github.com/electron/electron/pull/47951" target="_blank" rel="noopener noreferrer" class="">37</a>)</li>
<li class="">Fixed an issue where <code>dialog.showMessageDialog</code> showed a window incorrectly centered to monitor instead of parent window when passed. <a href="https://github.com/electron/electron/pull/48215" target="_blank" rel="noopener noreferrer" class="">#48215</a></li>
<li class="">Fixed an issue where users on macOS were unable to interact with a webpage loaded via <code>loadURL</code>. <a href="https://github.com/electron/electron/pull/47575" target="_blank" rel="noopener noreferrer" class="">#47575</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-38-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="移除macos-11-支持">移除：macOS 11 支持<a href="https://electronjs.org/zh/blog/electron-38-0#%E7%A7%BB%E9%99%A4macos-11-%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 移除：macOS 11 支持" title="链接到 移除：macOS 11 支持" translate="no">​</a></h3>
<p>macOS 11 (Big Sur) is no longer supported by <a href="https://chromium-review.googlesource.com/c/chromium/src/+/6594615" target="_blank" rel="noopener noreferrer" class="">Chromium</a>.</p>
<p>Older versions of Electron will continue to run on Big Sur, but macOS 12 (Monterey)
or later will be required to run Electron v38.0.0 and higher.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="removed-electron_ozone_platform_hint-environment-variable">Removed: <code>ELECTRON_OZONE_PLATFORM_HINT</code> environment variable<a href="https://electronjs.org/zh/blog/electron-38-0#removed-electron_ozone_platform_hint-environment-variable" class="hash-link" aria-label="链接到 removed-electron_ozone_platform_hint-environment-variable" title="链接到 removed-electron_ozone_platform_hint-environment-variable" translate="no">​</a></h3>
<p>The default value of the <code>--ozone-platform</code> flag <a href="https://chromium-review.googlesource.com/c/chromium/src/+/6775426" target="_blank" rel="noopener noreferrer" class="">changed to <code>auto</code></a>.</p>
<p>Electron now runs as a native Wayland app by default when launched in a Wayland session on Linux. Some features and APIs behave differently in Wayland and X11.
You can force Electron to run in X11 compatibility mode (Xwayland), like it did in older versions, by appending the flag <code>--ozone-platform=x11</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="removed-plugin-crashed-event">Removed: <code>plugin-crashed</code> event<a href="https://electronjs.org/zh/blog/electron-38-0#removed-plugin-crashed-event" class="hash-link" aria-label="链接到 removed-plugin-crashed-event" title="链接到 removed-plugin-crashed-event" translate="no">​</a></h3>
<p>The <code>plugin-crashed</code> event has been removed from <code>webContents</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deprecated-webframeroutingid-property">Deprecated: <code>webFrame.routingId</code> property<a href="https://electronjs.org/zh/blog/electron-38-0#deprecated-webframeroutingid-property" class="hash-link" aria-label="链接到 deprecated-webframeroutingid-property" title="链接到 deprecated-webframeroutingid-property" translate="no">​</a></h3>
<p>The <code>routingId</code> property will be removed from <code>webFrame</code> objects.</p>
<p>You should use <code>webFrame.frameToken</code> instead.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deprecated-webframefindframebyroutingidroutingid">Deprecated: <code>webFrame.findFrameByRoutingId(routingId)</code><a href="https://electronjs.org/zh/blog/electron-38-0#deprecated-webframefindframebyroutingidroutingid" class="hash-link" aria-label="链接到 deprecated-webframefindframebyroutingidroutingid" title="链接到 deprecated-webframefindframebyroutingidroutingid" translate="no">​</a></h3>
<p>The <code>webFrame.findFrameByRoutingId(routingId)</code> function will be removed.</p>
<p>You should use <code>webFrame.findFrameByToken(frameToken)</code> instead.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="google-summer-of-code-concludes">Google Summer of Code Concludes<a href="https://electronjs.org/zh/blog/electron-38-0#google-summer-of-code-concludes" class="hash-link" aria-label="链接到 Google Summer of Code Concludes" title="链接到 Google Summer of Code Concludes" translate="no">​</a></h2>
<p>Our two <a href="https://summerofcode.withgoogle.com/" target="_blank" rel="noopener noreferrer" class="">Google Summer of Code</a> contributors have just completed their summer projects!</p>
<ul>
<li class=""><a href="https://github.com/nilayarya" target="_blank" rel="noopener noreferrer" class="">@nilayarya</a> crafted a new <a href="https://github.com/electron/rfcs/pull/16/" target="_blank" rel="noopener noreferrer" class="">Save/Restore Window State API</a> in Electron core. The new APIs will provide a built-in, standardized way
to handle window state persistence. See Nilay's original RFC at <a href="https://github.com/electron/rfcs/pull/16" target="_blank" rel="noopener noreferrer" class="">electron/rfcs#16</a>.</li>
<li class=""><a href="https://github.com/hitarth-gg" target="_blank" rel="noopener noreferrer" class="">@hitarth-gg</a> put a lot of hard work into modernizing the long-dormant <a href="https://github.com/electron-userland/devtron" target="_blank" rel="noopener noreferrer" class="">Devtron</a> extension using Chrome Manifest V3 APIs.
This project provides tooling for developers to debug IPC communication, track event listeners, and visualize module dependencies in their Electron applications.</li>
</ul>
<p>Stay tuned for a more detailed blog post outlining their projects and the outcomes.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="终止对-35xy-的支持">终止对 35.x.y 的支持<a href="https://electronjs.org/zh/blog/electron-38-0#%E7%BB%88%E6%AD%A2%E5%AF%B9-35xy-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 终止对 35.x.y 的支持" title="链接到 终止对 35.x.y 的支持" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 35.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。</p>
<table><thead><tr><th>E38 (Sep'25)</th><th>E39 (Oct'25)</th><th>E40 (Jan'26)</th></tr></thead><tbody><tr><td>38.x.y</td><td>39.x.y</td><td>40.x.y</td></tr><tr><td>37.x.y</td><td>38.x.y</td><td>39.x.y</td></tr><tr><td>36.x.y</td><td>37.x.y</td><td>38.x.y</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-38-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
        <item>
            <title><![CDATA[Electron 37.0.0]]></title>
            <link>https://electronjs.org/zh/blog/electron-37-0</link>
            <guid>https://electronjs.org/zh/blog/electron-37-0</guid>
            <pubDate>Tue, 24 Jun 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 37.0.0 已发布！ 它包括升级到 Chromium 138、V8 13.8 和 Node 22.16.0。]]></description>
            <content:encoded><![CDATA[<p>Electron 37.0.0 已发布！ 它包括升级到 Chromium 138、V8 13.8 和 Node 22.16.0。</p>
<hr>
<p>Electron 团队很高兴发布了 Electron 37.0.0 ！ 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://bsky.app/profile/electronjs.org" target="_blank" rel="noopener noreferrer" class="">Bluesky</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="google-summer-of-code-begins">Google Summer of Code Begins<a href="https://electronjs.org/zh/blog/electron-37-0#google-summer-of-code-begins" class="hash-link" aria-label="链接到 Google Summer of Code Begins" title="链接到 Google Summer of Code Begins" translate="no">​</a></h2>
<p>Our two <a href="https://summerofcode.withgoogle.com/" target="_blank" rel="noopener noreferrer" class="">Google Summer of Code</a> contributors have started the
program's coding period!</p>
<ul>
<li class=""><a href="https://github.com/nilayarya" target="_blank" rel="noopener noreferrer" class="">@nilayarya</a> is crafting a new <a href="https://github.com/electron/rfcs/pull/16/" target="_blank" rel="noopener noreferrer" class="">Save/Restore Window State API</a> in Electron core. The new APIs will provide a built-in, standardized way
to handle window state persistence. See Nilay's in-progress RFC at <a href="https://github.com/electron/rfcs/pull/16" target="_blank" rel="noopener noreferrer" class="">electron/rfcs#16</a>.</li>
<li class=""><a href="https://github.com/hitarth-gg" target="_blank" rel="noopener noreferrer" class="">@hitarth-gg</a> is hard at work modernizing the long-dormant <a href="https://github.com/electron-userland/devtron" target="_blank" rel="noopener noreferrer" class="">Devtron</a> extension using Chrome Manifest V3 APIs.
This project will provide tooling for developers to debug IPC communication, track event listeners, and visualize module dependencies in their Electron applications.</li>
</ul>
<p>It has been an exciting couple of weeks for our GSOC participants, so stay tuned for more updates!</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重要变化">重要变化<a href="https://electronjs.org/zh/blog/electron-37-0#%E9%87%8D%E8%A6%81%E5%8F%98%E5%8C%96" class="hash-link" aria-label="链接到 重要变化" title="链接到 重要变化" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="smooth-corners-native-css-squircles">Smooth Corners: Native CSS Squircles<a href="https://electronjs.org/zh/blog/electron-37-0#smooth-corners-native-css-squircles" class="hash-link" aria-label="链接到 Smooth Corners: Native CSS Squircles" title="链接到 Smooth Corners: Native CSS Squircles" translate="no">​</a></h3>
<p><img decoding="async" loading="lazy" alt="An image showing different corner smoothing values (0%, 30%, 60%, and 100%) applied to rectangles, with 60% labeled as matching macOS style" src="https://electronjs.org/zh/assets/images/corner-smoothing-d3a1b1a6fac2cd9162e7594114aebb97.svg" width="1024" height="512" class="img_ev3q"></p>
<p>Electron 37 introduces the custom <code>-electron-corner-smoothing</code> CSS property, which allows apps to create smoother rounded corners to match Apple's macOS design language. This feature originally landed in Electron 36, but we felt like it deserved a brighter spotlight.</p>
<table><caption><p>Example with 100% Corner Smoothing</p></caption><thead><tr><th>代码</th><th>结果</th></tr></thead><tbody><tr><td><div class="language-css codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-css codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token selector class" style="color:#00009f">.box</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">width</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">128</span><span class="token unit">px</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">height</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">128</span><span class="token unit">px</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">border-radius</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">24</span><span class="token unit">px</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token property" style="color:#36acaa">-electron-corner-smoothing</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">100</span><span class="token unit">%</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre></div></div></td><td><img src="https://raw.githubusercontent.com/electron/rfcs/d89000c638a6d98b497ce2fbea07bce45c2760a8/images/0012/Rectangle.svg" width="128px" alt=""></td></tr></tbody></table>
<p>Unlike the standard <code>border-radius</code> property, which carves quarter-circle corners out of a rectangle, <code>-electron-corner-smoothing</code> smoothly transitions
the curve into a <a href="https://en.wikipedia.org/wiki/Squircle" target="_blank" rel="noopener noreferrer" class=""><strong>squircle</strong></a> shape with a continuous perimeter.</p>
<p>You can adjust the smoothness using values from 0% to 100%, or use the <code>system-ui</code> value to match the operating system's style (60% on macOS and 0% otherwise).
This design enhancement can be applied on borders, outlines, and shadows, giving your app a subtle layer of polish.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>提示</div><div class="admonitionContent_BuS1"><p>Read more about Electron's squircle implementation in <a href="https://github.com/clavin" target="_blank" rel="noopener noreferrer" class="">@clavin</a>'s <a href="https://github.com/electron/rfcs/blob/main/text/0012-corner-smoothing.md" target="_blank" rel="noopener noreferrer" class="">RFC 0012</a>.
The document goes over the motivation and technical implementation in more detail.</p><p>The initial design drew inspiration from Figma's corner smoothing implementation. Read more about their own quest for smooth corners in
<a href="https://www.figma.com/blog/desperately-seeking-squircles/" target="_blank" rel="noopener noreferrer" class="">"Desperately seeking squircles"</a>.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-37-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">Chromium <code>138.0.7204.35</code>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-138/" target="_blank" rel="noopener noreferrer" class="">138 新功能</a></li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-137/" target="_blank" rel="noopener noreferrer" class="">137 新功能</a></li>
</ul>
</li>
<li class="">Node <code>22.16.0</code>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v22.16.0/" target="_blank" rel="noopener noreferrer" class="">Node 22.16.0 博客</a></li>
</ul>
</li>
<li class="">V8 <code>13.8</code></li>
</ul>
<p>Electron 37 upgrades Chromium from <code>136.0.7103.48</code> to <code>138.0.7204.35</code>, and V8 from <code>13.6</code> to <code>13.8</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-features-and-improvements">New Features and Improvements<a href="https://electronjs.org/zh/blog/electron-37-0#new-features-and-improvements" class="hash-link" aria-label="链接到 New Features and Improvements" title="链接到 New Features and Improvements" translate="no">​</a></h2>
<ul>
<li class="">Added <code>innerWidth</code> and <code>innerHeight</code> options for <code>window.open</code>. <a href="https://github.com/electron/electron/pull/47039" target="_blank" rel="noopener noreferrer" class="">#47039</a> (Also in <a href="https://github.com/electron/electron/pull/47045" target="_blank" rel="noopener noreferrer" class="">35</a>, <a href="https://github.com/electron/electron/pull/47038" target="_blank" rel="noopener noreferrer" class="">36</a>)</li>
<li class="">Added <code>before-mouse-event</code> to allow intercepting and preventing mouse events in <code>webContents</code>. <a href="https://github.com/electron/electron/pull/47364" target="_blank" rel="noopener noreferrer" class="">#47364</a> (Also in <a href="https://github.com/electron/electron/pull/47365" target="_blank" rel="noopener noreferrer" class="">36</a>)</li>
<li class="">Added <code>scriptURL</code> property to <code>ServiceWorkerMain</code>. <a href="https://github.com/electron/electron/pull/45863" target="_blank" rel="noopener noreferrer" class="">#45863</a></li>
<li class="">Added <code>sublabel</code> functionality for menus on macOS &gt;= 14.4. <a href="https://github.com/electron/electron/pull/47042" target="_blank" rel="noopener noreferrer" class="">#47042</a> (Also in <a href="https://github.com/electron/electron/pull/47041" target="_blank" rel="noopener noreferrer" class="">35</a>, <a href="https://github.com/electron/electron/pull/47040" target="_blank" rel="noopener noreferrer" class="">36</a>)</li>
<li class="">Added support for <code>HIDDevice.collections</code>. <a href="https://github.com/electron/electron/pull/47483" target="_blank" rel="noopener noreferrer" class="">#47483</a> (Also in <a href="https://github.com/electron/electron/pull/47484" target="_blank" rel="noopener noreferrer" class="">36</a>)</li>
<li class="">Added support for <code>--no-experimental-global-navigator</code> flag. <a href="https://github.com/electron/electron/pull/47418" target="_blank" rel="noopener noreferrer" class="">#47418</a> (Also in <a href="https://github.com/electron/electron/pull/47416" target="_blank" rel="noopener noreferrer" class="">35</a>, <a href="https://github.com/electron/electron/pull/47417" target="_blank" rel="noopener noreferrer" class="">36</a>)</li>
<li class="">Added support for <code>screen.dipToScreenPoint(point)</code> and <code>screen.screenToDipPoint(point)</code> on Linux X11. <a href="https://github.com/electron/electron/pull/46895" target="_blank" rel="noopener noreferrer" class="">#46895</a> (Also in <a href="https://github.com/electron/electron/pull/47124" target="_blank" rel="noopener noreferrer" class="">35</a>, <a href="https://github.com/electron/electron/pull/47125" target="_blank" rel="noopener noreferrer" class="">36</a>)</li>
<li class="">Added support for menu item role <code>palette</code> and <code>header</code> on macOS. <a href="https://github.com/electron/electron/pull/47245" target="_blank" rel="noopener noreferrer" class="">#47245</a></li>
<li class="">Added support for node option <code>--experimental-network-inspection</code>. <a href="https://github.com/electron/electron/pull/47031" target="_blank" rel="noopener noreferrer" class="">#47031</a> (Also in <a href="https://github.com/electron/electron/pull/47029" target="_blank" rel="noopener noreferrer" class="">35</a>, <a href="https://github.com/electron/electron/pull/47030" target="_blank" rel="noopener noreferrer" class="">36</a>)</li>
<li class="">Exposed <code>win.isContentProtected()</code> to allow developers to check window protection status. <a href="https://github.com/electron/electron/pull/47310" target="_blank" rel="noopener noreferrer" class="">#47310</a> (Also in <a href="https://github.com/electron/electron/pull/47311" target="_blank" rel="noopener noreferrer" class="">36</a>)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-37-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="utility-process-unhandled-rejection-behavior-change">Utility Process unhandled rejection behavior change<a href="https://electronjs.org/zh/blog/electron-37-0#utility-process-unhandled-rejection-behavior-change" class="hash-link" aria-label="链接到 Utility Process unhandled rejection behavior change" title="链接到 Utility Process unhandled rejection behavior change" translate="no">​</a></h3>
<p>Utility Processes will now warn with an error message when an unhandled
rejection occurs instead of crashing the process.</p>
<p>To restore the previous behavior, you can use:</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'unhandledRejection'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  process</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">exit</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-processexit-kills-utility-process-synchronously">Behavior Changed: <code>process.exit()</code> kills utility process synchronously<a href="https://electronjs.org/zh/blog/electron-37-0#behavior-changed-processexit-kills-utility-process-synchronously" class="hash-link" aria-label="链接到 behavior-changed-processexit-kills-utility-process-synchronously" title="链接到 behavior-changed-processexit-kills-utility-process-synchronously" translate="no">​</a></h3>
<p>Calling <code>process.exit()</code> in a utility process will now kill the utility process synchronously.
This brings the behavior of <code>process.exit()</code> in line with Node.js behavior.</p>
<p>Please refer to the
<a href="https://nodejs.org/docs/latest-v22.x/api/process.html#processexitcode" target="_blank" rel="noopener noreferrer" class="">Node.js docs</a> and
<a href="https://github.com/electron/electron/pull/45690" target="_blank" rel="noopener noreferrer" class="">PR #45690</a> to understand the potential
implications of that, e.g., when calling <code>console.log()</code> before <code>process.exit()</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-webusb-and-webserial-blocklist-support">Behavior Changed: WebUSB and WebSerial Blocklist Support<a href="https://electronjs.org/zh/blog/electron-37-0#behavior-changed-webusb-and-webserial-blocklist-support" class="hash-link" aria-label="链接到 Behavior Changed: WebUSB and WebSerial Blocklist Support" title="链接到 Behavior Changed: WebUSB and WebSerial Blocklist Support" translate="no">​</a></h3>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/API/WebUSB_API" target="_blank" rel="noopener noreferrer" class="">WebUSB</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API" target="_blank" rel="noopener noreferrer" class="">Web Serial</a> now support the <a href="https://wicg.github.io/webusb/#blocklist" target="_blank" rel="noopener noreferrer" class="">WebUSB Blocklist</a> and <a href="https://wicg.github.io/serial/#blocklist" target="_blank" rel="noopener noreferrer" class="">Web Serial Blocklist</a> used by Chromium and outlined in their respective specifications.</p>
<p>To disable these, users can pass <code>disable-usb-blocklist</code> and <code>disable-serial-blocklist</code> as command line flags.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="removed-null-value-for-session-property-in-protocolresponse">Removed: <code>null</code> value for <code>session</code> property in <code>ProtocolResponse</code><a href="https://electronjs.org/zh/blog/electron-37-0#removed-null-value-for-session-property-in-protocolresponse" class="hash-link" aria-label="链接到 removed-null-value-for-session-property-in-protocolresponse" title="链接到 removed-null-value-for-session-property-in-protocolresponse" translate="no">​</a></h3>
<p>This deprecated feature has been removed.</p>
<p>Previously, setting the <code>ProtocolResponse.session</code> property to <code>null</code>
would create a random independent session. This is no longer supported.</p>
<p>Using single-purpose sessions here is discouraged due to overhead costs;
however, old code that needs to preserve this behavior can emulate it by
creating a random session with <code>session.fromPartition(some_random_string)</code>
and then using it in <code>ProtocolResponse.session</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-browserwindowisvisibleonallworkspaces-on-linux">Behavior Changed: <code>BrowserWindow.IsVisibleOnAllWorkspaces()</code> on Linux<a href="https://electronjs.org/zh/blog/electron-37-0#behavior-changed-browserwindowisvisibleonallworkspaces-on-linux" class="hash-link" aria-label="链接到 behavior-changed-browserwindowisvisibleonallworkspaces-on-linux" title="链接到 behavior-changed-browserwindowisvisibleonallworkspaces-on-linux" translate="no">​</a></h3>
<p><code>BrowserWindow.IsVisibleOnAllWorkspaces()</code> will now return false on Linux if the
window is not currently visible.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="终止对-34xy-的支持">终止对 34.x.y 的支持<a href="https://electronjs.org/zh/blog/electron-37-0#%E7%BB%88%E6%AD%A2%E5%AF%B9-34xy-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 终止对 34.x.y 的支持" title="链接到 终止对 34.x.y 的支持" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 34.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。</p>
<table><thead><tr><th>E37 (2025 年 6 月)</th><th>E38 (Aug'25)</th><th>E39 (Oct'25)</th></tr></thead><tbody><tr><td>37.x.y</td><td>38.x.y</td><td>39.x.y</td></tr><tr><td>36.x.y</td><td>37.x.y</td><td>38.x.y</td></tr><tr><td>35.x.y</td><td>36.x.y</td><td>37.x.y</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-37-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
        <item>
            <title><![CDATA[Electron 36.0.0]]></title>
            <link>https://electronjs.org/zh/blog/electron-36-0</link>
            <guid>https://electronjs.org/zh/blog/electron-36-0</guid>
            <pubDate>Mon, 28 Apr 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 36.0.0 已发布！ 它包括升级到 Chromium 136、V8 13.6 和 Node 22.14.0。]]></description>
            <content:encoded><![CDATA[<p>Electron 36.0.0 已发布！ 它包括升级到 Chromium 136、V8 13.6 和 Node 22.14.0。</p>
<hr>
<p>Electron 团队很高兴发布了 Electron 36.0.0 ！ 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://bsky.app/profile/electronjs.org" target="_blank" rel="noopener noreferrer" class="">Bluesky</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重要变化">重要变化<a href="https://electronjs.org/zh/blog/electron-36-0#%E9%87%8D%E8%A6%81%E5%8F%98%E5%8C%96" class="hash-link" aria-label="链接到 重要变化" title="链接到 重要变化" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="writing-tools-support">Writing Tools Support<a href="https://electronjs.org/zh/blog/electron-36-0#writing-tools-support" class="hash-link" aria-label="链接到 Writing Tools Support" title="链接到 Writing Tools Support" translate="no">​</a></h3>
<p>在 Electron 36 中，您可以在您的上下文菜单中启用 macOS 系统级别的功能，例如写作工具（拼写和语法）、自动填充和服务菜单。 To do so, pass a <a href="https://www.electronjs.org/docs/latest/api/web-frame-main#class-webframemain" target="_blank" rel="noopener noreferrer" class="">WebFrameMain</a> instance into the <code>frame</code> parameter for <code>menu.popup()</code>.</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">BrowserWindow</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">Menu</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">WebFrameMain</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'electron'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> currentWindow </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token maybe-class-name">BrowserWindow</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getFocusedWindow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> focusedFrame </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> currentWindow</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">focusedFrame</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> menu </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token maybe-class-name">Menu</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">buildFromTemplate</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">label</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'Copy'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">role</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'copy'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">menu</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">popup</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">window</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> currentWindow</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">frame</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> focusedFrame</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-36-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">Chromium <code>136.0.7103.48</code>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-136/" target="_blank" rel="noopener noreferrer" class="">136 新功能</a></li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-135/" target="_blank" rel="noopener noreferrer" class="">135 新功能</a></li>
</ul>
</li>
<li class="">Node <code>22.14.0</code>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v22.14.0/" target="_blank" rel="noopener noreferrer" class="">Node 22.14.0 博客</a></li>
</ul>
</li>
<li class="">V8 <code>13.6</code></li>
</ul>
<p>Electron 36 upgrades Chromium from <code>134.0.6998.23</code> to <code>136.0.7103.48</code>, and V8 from <code>13.5</code> to <code>13.6</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="new-features-and-improvements">New Features and Improvements<a href="https://electronjs.org/zh/blog/electron-36-0#new-features-and-improvements" class="hash-link" aria-label="链接到 New Features and Improvements" title="链接到 New Features and Improvements" translate="no">​</a></h2>
<ul>
<li class="">Added <code>BrowserWindow.isSnapped()</code> to indicate whether a given window has been arranged via Snap on Windows. <a href="https://github.com/electron/electron/pull/46226" target="_blank" rel="noopener noreferrer" class="">#46226</a></li>
<li class="">Added <code>WebContents.focusedFrame</code> to get the focused frame.</li>
<li class="">Fixed <code>WebContents.opener</code> to specify potential <code>null</code> type. <a href="https://github.com/electron/electron/pull/45667" target="_blank" rel="noopener noreferrer" class="">#45667</a></li>
<li class="">Added <code>ffmpeg.dll</code> to delay load configuration. <a href="https://github.com/electron/electron/pull/46173" target="_blank" rel="noopener noreferrer" class="">#46173</a> (Also in <a href="https://github.com/electron/electron/pull/46174" target="_blank" rel="noopener noreferrer" class="">34</a>, <a href="https://github.com/electron/electron/pull/46172" target="_blank" rel="noopener noreferrer" class="">35</a>)</li>
<li class="">Added <code>nativeTheme.shouldUseDarkColorsForSystemIntegratedUI</code> to distinguish system and app theme. <a href="https://github.com/electron/electron/pull/46598" target="_blank" rel="noopener noreferrer" class="">#46598</a> (Also in <a href="https://github.com/electron/electron/pull/46599" target="_blank" rel="noopener noreferrer" class="">35</a>)</li>
<li class="">Added <code>excludeUrls</code> to <code>webRequest</code> filter and deprecated the use of empty arrays in <code>urls</code> property. <a href="https://github.com/electron/electron/pull/44692" target="_blank" rel="noopener noreferrer" class="">#44692</a> (Also in <a href="https://github.com/electron/electron/pull/45678" target="_blank" rel="noopener noreferrer" class="">35</a>)</li>
<li class="">Added support for Autofill, Writing Tools and Services macOS level menu items in context menus via the new <code>frame</code> option in <code>menu.popup</code>. <a href="https://github.com/electron/electron/pull/46350" target="_blank" rel="noopener noreferrer" class="">#46350</a></li>
<li class="">Added support for <code>system-context-menu</code> on Linux. <a href="https://github.com/electron/electron/pull/46399" target="_blank" rel="noopener noreferrer" class="">#46399</a></li>
<li class="">Improved ASAR integrity checks on Windows. <a href="https://github.com/electron/electron/pull/46537" target="_blank" rel="noopener noreferrer" class="">#46537</a></li>
<li class="">Improved performance of <code>desktopCapturer.getSources</code> when not requesting thumbnails on macOS. <a href="https://github.com/electron/electron/pull/46251" target="_blank" rel="noopener noreferrer" class="">#46251</a> (Also in <a href="https://github.com/electron/electron/pull/46250" target="_blank" rel="noopener noreferrer" class="">34</a>, <a href="https://github.com/electron/electron/pull/46249" target="_blank" rel="noopener noreferrer" class="">35</a>)</li>
<li class="">Removed 240 FPS limit when using shared texture OSR. <a href="https://github.com/electron/electron/pull/45669" target="_blank" rel="noopener noreferrer" class="">#45669</a> (Also in <a href="https://github.com/electron/electron/pull/45781" target="_blank" rel="noopener noreferrer" class="">35</a>)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-36-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="已弃用nativeimagegetbitmap">已弃用：<code>NativeImage.getBitmap()</code><a href="https://electronjs.org/zh/blog/electron-36-0#%E5%B7%B2%E5%BC%83%E7%94%A8nativeimagegetbitmap" class="hash-link" aria-label="链接到 已弃用nativeimagegetbitmap" title="链接到 已弃用nativeimagegetbitmap" translate="no">​</a></h3>
<p>The <code>NativeImage.getBitmap()</code> function is now deprecated and documented as an alias for <code>NativeImage.toBitmap()</code>.
The two functions both return a newly-allocated copy of the bitmap and are functionally equivalent.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="已弃用session-上的扩展方法和事件">已弃用：<code>session</code> 上的扩展方法和事件<a href="https://electronjs.org/zh/blog/electron-36-0#%E5%B7%B2%E5%BC%83%E7%94%A8session-%E4%B8%8A%E7%9A%84%E6%89%A9%E5%B1%95%E6%96%B9%E6%B3%95%E5%92%8C%E4%BA%8B%E4%BB%B6" class="hash-link" aria-label="链接到 已弃用session-上的扩展方法和事件" title="链接到 已弃用session-上的扩展方法和事件" translate="no">​</a></h3>
<p><code>session.loadExtension</code>, <code>session.removeExtension</code>, <code>session.getExtension</code>,
<code>session.getAllExtensions</code>, and the events <code>extension-loaded</code>,
<code>extension-unloaded</code>, and <code>extension-ready</code> have all moved to the new
<a href="https://www.electronjs.org/docs/latest/api/extensions-api" target="_blank" rel="noopener noreferrer" class=""><code>Extensions</code> object</a>
accessible via the <code>session.extensions</code> instance property.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="已移除sessionclearstoragedataoptions-中的-quoto-类型-syncable">已移除：<code>session.clearStorageData(options)</code> 中的 <code>quoto</code> 类型 <code>syncable</code><a href="https://electronjs.org/zh/blog/electron-36-0#%E5%B7%B2%E7%A7%BB%E9%99%A4sessionclearstoragedataoptions-%E4%B8%AD%E7%9A%84-quoto-%E7%B1%BB%E5%9E%8B-syncable" class="hash-link" aria-label="链接到 已移除sessionclearstoragedataoptions-中的-quoto-类型-syncable" title="链接到 已移除sessionclearstoragedataoptions-中的-quoto-类型-syncable" translate="no">​</a></h3>
<p>When calling <code>session.clearStorageData(options)</code>, the <code>options.quota</code> type
<code>syncable</code> is no longer supported because it has been
<a href="https://chromium-review.googlesource.com/c/chromium/src/+/6309405" target="_blank" rel="noopener noreferrer" class="">removed</a>
from upstream Chromium.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="deprecated-quota-property-in-sessionclearstoragedataoptions">Deprecated: <code>quota</code> property in <code>session.clearStorageData(options)</code><a href="https://electronjs.org/zh/blog/electron-36-0#deprecated-quota-property-in-sessionclearstoragedataoptions" class="hash-link" aria-label="链接到 deprecated-quota-property-in-sessionclearstoragedataoptions" title="链接到 deprecated-quota-property-in-sessionclearstoragedataoptions" translate="no">​</a></h3>
<p>When calling <code>Session.clearStorageData(options)</code>, the <code>options.quota</code>
property is deprecated. Since the <code>syncable</code> type was removed, there
is only type left -- <code>'temporary'</code> -- so specifying it is unnecessary.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-gtk-4-is-the-default-when-running-on-gnome">Behavior Changed: GTK 4 is the default when running on GNOME<a href="https://electronjs.org/zh/blog/electron-36-0#behavior-changed-gtk-4-is-the-default-when-running-on-gnome" class="hash-link" aria-label="链接到 Behavior Changed: GTK 4 is the default when running on GNOME" title="链接到 Behavior Changed: GTK 4 is the default when running on GNOME" translate="no">​</a></h3>
<p>After an <a href="https://chromium-review.googlesource.com/c/chromium/src/+/6310469" target="_blank" rel="noopener noreferrer" class="">upstream change</a>, GTK 4 is now the default when running on GNOME.</p>
<p>In rare cases, this may cause some applications or configurations to <a href="https://github.com/electron/electron/issues/46538" target="_blank" rel="noopener noreferrer" class="">error</a> with the following message:</p>
<div class="language-stderr codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-stderr codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">Gtk-ERROR **: 11:30:38.382: GTK 2/3 symbols detected. Using GTK 2/3 and GTK 4 in the same process is not supported</span><br></span></code></pre></div></div>
<p>Affected users can work around this by specifying the <code>gtk-version</code> command-line flag:</p>
<div class="language-shell codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-shell codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">$ electron --gtk-version=3   # or --gtk-version=2</span><br></span></code></pre></div></div>
<p>The same can be done with the <a href="https://www.electronjs.org/docs/latest/api/command-line#commandlineappendswitchswitch-value" target="_blank" rel="noopener noreferrer" class=""><code>app.commandLine.appendSwitch</code></a> function.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-appcommandline">Behavior Changed: <code>app.commandLine</code><a href="https://electronjs.org/zh/blog/electron-36-0#behavior-changed-appcommandline" class="hash-link" aria-label="链接到 behavior-changed-appcommandline" title="链接到 behavior-changed-appcommandline" translate="no">​</a></h3>
<p><code>app.commandLine</code> will convert uppercases switches and arguments to lowercase.</p>
<p><code>app.commandLine</code> was only meant to handle Chromium switches (which aren't case-sensitive) and switches passed via <code>app.commandLine</code> will not be passed down to any of the child processes.</p>
<p>If you were using <code>app.commandLine</code> to parse app-specific command line arguments, you should do this via <code>process.argv</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="终止对-33xy-的支持">终止对 33.x.y 的支持<a href="https://electronjs.org/zh/blog/electron-36-0#%E7%BB%88%E6%AD%A2%E5%AF%B9-33xy-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 终止对 33.x.y 的支持" title="链接到 终止对 33.x.y 的支持" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 33.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。</p>
<table><thead><tr><th>E36 (2025 年 4 月)</th><th>E37 (2025 年 6 月)</th><th>E38 (Aug'25)</th></tr></thead><tbody><tr><td>36.x.y</td><td>37.x.y</td><td>38.x.y</td></tr><tr><td>35.x.y</td><td>36.x.y</td><td>37.x.y</td></tr><tr><td>34.x.y</td><td>35.x.y</td><td>36.x.y</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-36-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
        <item>
            <title><![CDATA[Electron 35.0.0]]></title>
            <link>https://electronjs.org/zh/blog/electron-35-0</link>
            <guid>https://electronjs.org/zh/blog/electron-35-0</guid>
            <pubDate>Tue, 04 Mar 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 35.0.0 已发布！ 它包括对 Chromium 134.0.6998.44、V8 13.5 和 Node 22.14.0 的升级。]]></description>
            <content:encoded><![CDATA[<p>Electron 35.0.0 已发布！ 它包括对 Chromium 134.0.6998.44、V8 13.5 和 Node 22.14.0 的升级。</p>
<hr>
<p>Electron 团队很高兴发布了 Electron 35.0.0 ！ 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://bsky.app/profile/electronjs.org" target="_blank" rel="noopener noreferrer" class="">Bluesky</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重��要变化">重要变化<a href="https://electronjs.org/zh/blog/electron-35-0#%E9%87%8D%E8%A6%81%E5%8F%98%E5%8C%96" class="hash-link" aria-label="链接到 重要变化" title="链接到 重要变化" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="用于改进扩展支持的-service-worker-预加载脚本">用于改进扩展支持的 Service Worker 预加载脚本<a href="https://electronjs.org/zh/blog/electron-35-0#%E7%94%A8%E4%BA%8E%E6%94%B9%E8%BF%9B%E6%89%A9%E5%B1%95%E6%94%AF%E6%8C%81%E7%9A%84-service-worker-%E9%A2%84%E5%8A%A0%E8%BD%BD%E8%84%9A%E6%9C%AC" class="hash-link" aria-label="链接到 用于改进扩展支持的 Service Worker 预加载脚本" title="链接到 用于改进扩展支持的 Service Worker 预加载脚本" translate="no">​</a></h3>
<p>最初由 <a href="https://github.com/samuelmaddock" target="_blank" rel="noopener noreferrer" class="">@samuelmaddock</a> 在 <a href="https://github.com/electron/rfcs/blob/main/text/0008-preload-realm.md" target="_blank" rel="noopener noreferrer" class="">RFC #8</a> 中提出，Electron 35 添加了将预加载脚本附加到 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API" target="_blank" rel="noopener noreferrer" class="">Service Workers</a> 的功能。 由于 Chrome 的 Manifest V3 Extensions 通过 <a href="https://developer.chrome.com/docs/extensions/develop/concepts/service-workers" target="_blank" rel="noopener noreferrer" class="">扩展 service workers</a> 处理大量工作，该功能填补了 Electron 对现代 Chrome 扩展程序支持的空白。</p>
<p>在会话级别以编程方式注册预加载脚本时，现在可以使用 <a href="https://www.electronjs.org/docs/latest/api/session#sesregisterpreloadscriptscript" target="_blank" rel="noopener noreferrer" class=""><code>ses.registerPreloadScript(script)</code></a> API 将其专门应用于 Service Worker 上下文。</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">Main Process</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 将我们的预加载脚本添加到会话中。</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">defaultSession</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">registerPreloadScript</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 我们的脚本应该只在 service worker 预加载中运行。</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token literal-property property" style="color:#36acaa">type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'service-worker'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 脚本的绝对路径。</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token literal-property property" style="color:#36acaa">script</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> path</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">__dirname</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'extension-sw-preload.js'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">；</span><br></span></code></pre></div></div>
<p>此外，现在可以通过 <code>ServiceWorkerMain.ipc</code> 类在 Service Workers 及其附加的预加载脚本之间进行 IPC 通信。 预加载脚本仍将使用 <code>ipcRenderer</code> 模块与其 Service Worker 进行通信。 请参阅原始 RFC 以了解更多详细信息。</p>
<p>此功能之前已经进行了许多其他更改，为其奠定了基础：</p>
<ul>
<li class=""><a href="https://github.com/electron/electron/pull/45329" target="_blank" rel="noopener noreferrer" class="">#45329</a> 重新设计了 Session 模块的预加载 API，以支持注册和取消注册单独的预加载脚本。</li>
<li class=""><a href="https://github.com/electron/electron/pull/45330" target="_blank" rel="noopener noreferrer" class="">#45229</a> 添加了实验性的 <code>contextBridge.executeInMainWorld(executionScript)</code> 脚本，用于通过 context bridge 在 main world 中执行 JavaScript。</li>
<li class=""><a href="https://github.com/electron/electron/pull/45341" target="_blank" rel="noopener noreferrer" class="">#45341</a> 添加了 <code>ServiceWorkerMain</code> 类，用于与主进程中的 Service Workers 交互。</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-35-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">Chromium <code>134.0.6998.44</code>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-134/" target="_blank" rel="noopener noreferrer" class="">134 新功能</a></li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-133/" target="_blank" rel="noopener noreferrer" class="">133 新功能</a></li>
</ul>
</li>
<li class="">Node <code>22.14.0</code>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v22.14.0/" target="_blank" rel="noopener noreferrer" class="">Node 22.14.0 博客</a></li>
</ul>
</li>
<li class="">V8 <code>13.5</code></li>
</ul>
<p>Electron 35 将 Chromium 从 <code>132.0.6834.83</code> 升级到 <code>134.0.6998.44</code>，Node 从 <code>20.18.1</code> 升级到 <code>22.14.0</code>，V8 从 <code>13.2</code> 升级到 <code>13.5</code>。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="新特性">新特性<a href="https://electronjs.org/zh/blog/electron-35-0#%E6%96%B0%E7%89%B9%E6%80%A7" class="hash-link" aria-label="链接到 新特性" title="链接到 新特性" translate="no">​</a></h3>
<ul>
<li class="">在 Info.plist 中添加了 <code>NSPrefersDisplaySafeAreaCompatibilityMode</code> = <code>false</code>，以移除应用选项中的 “Scale to fit below built-in camera” 选项。 <a href="https://github.com/electron/electron/pull/45357" target="_blank" rel="noopener noreferrer" class="">#45357</a> <sup>（也适用于 <a href="https://github.com/electron/electron/pull/45469" target="_blank" rel="noopener noreferrer" class="">v34.1.0</a>）</sup></li>
<li class="">在主进程中添加了 <code>ServiceWorkerMain</code> 类，用于与服务工作线程进行交互。 <a href="https://github.com/electron/electron/pull/45341" target="_blank" rel="noopener noreferrer" class="">#45341</a>
<ul>
<li class="">在 <code>ServiceWorkers</code> 上添加了 <code>running-status-changed</code> 事件，用于指示服务工作线程的运行状态何时发生更改。</li>
<li class="">在 <code>ServiceWorkers</code> 上添加了 <code>startWorkerForScope</code> 方法，用于启动可能先前已停止的工作线程。</li>
</ul>
</li>
<li class="">添加了实验性的 <code>contextBridge.executeInMainWorld</code> 方法，用于安全地跨 world 边界执行代码。 <a href="https://github.com/electron/electron/pull/45330" target="_blank" rel="noopener noreferrer" class="">#45330</a></li>
<li class="">在 <code>'console-message'</code> 事件中添加了 <code>frame</code> 属性。 <a href="https://github.com/electron/electron/pull/43617" target="_blank" rel="noopener noreferrer" class="">#43617</a></li>
<li class="">在 Windows 上添加了 <code>query-session-end</code> 事件并改进了 <code>session-end</code> 事件。 <a href="https://github.com/electron/electron/pull/44598" target="_blank" rel="noopener noreferrer" class="">#44598</a></li>
<li class="">添加 <code>view.getVisible()</code>。 <a href="https://github.com/electron/electron/pull/45409" target="_blank" rel="noopener noreferrer" class="">#45409</a></li>
<li class="">添加了 <code>webContents.navigationHistory.restore(index, entries)</code> API，允许恢复导航记录。 <a href="https://github.com/electron/electron/pull/45583" target="_blank" rel="noopener noreferrer" class="">#45583</a></li>
<li class="">在 <code>BrowserWindow.setVibrancy</code> 中添加了可选的动画参数。 <a href="https://github.com/electron/electron/pull/35987" target="_blank" rel="noopener noreferrer" class="">#35987</a></li>
<li class="">为 <code>document.executeCommand("paste")</code> 添加了权限支持。 <a href="https://github.com/electron/electron/pull/45471" target="_blank" rel="noopener noreferrer" class="">#45471</a> <sup>（同样在 <a href="https://github.com/electron/electron/pull/45472" target="_blank" rel="noopener noreferrer" class="">v34.1.0</a> 中）</sup></li>
<li class="">在 Windows 上添加了对 <code>roundedCorners</code> BrowserWindow 构造函数选项的支持。 <a href="https://github.com/electron/electron/pull/45740" target="_blank" rel="noopener noreferrer" class="">#45740</a> <sup>（同样在 <a href="https://github.com/electron/electron/pull/45739" target="_blank" rel="noopener noreferrer" class="">v34.3.0</a> 中）</sup></li>
<li class="">添加了对 service worker 线程预加载脚本的支持。 <a href="https://github.com/electron/electron/pull/45408" target="_blank" rel="noopener noreferrer" class="">#45408</a></li>
<li class="">支持 Portal 的 <code>globalShortcuts</code>。 Electron 必须使用 <code>--enable-features=GlobalShortcutsPortal</code> 运行，该功能才能生效。 <a href="https://github.com/electron/electron/pull/45297" target="_blank" rel="noopener noreferrer" class="">#45297</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-35-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="移除了-printerinfo-上的-isdefault-和-status-属性">移除了 <code>PrinterInfo</code> 上的 <code>isDefault</code> 和 <code>status</code> 属性。<a href="https://electronjs.org/zh/blog/electron-35-0#%E7%A7%BB%E9%99%A4%E4%BA%86-printerinfo-%E4%B8%8A%E7%9A%84-isdefault-%E5%92%8C-status-%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="链接到 移除了-printerinfo-上的-isdefault-和-status-属性" title="链接到 移除了-printerinfo-上的-isdefault-和-status-属性" translate="no">​</a></h3>
<p>这些属性已从 <code>PrinterInfo</code> 对象中移除，因为它们已从上游 Chromium 中移除。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="已弃用sessionserviceworkers-上的-getfromversionid">已弃用：<code>session.serviceWorkers</code> 上的 <code>getFromVersionID</code>。<a href="https://electronjs.org/zh/blog/electron-35-0#%E5%B7%B2%E5%BC%83%E7%94%A8sessionserviceworkers-%E4%B8%8A%E7%9A%84-getfromversionid" class="hash-link" aria-label="链接到 已弃用sessionserviceworkers-上的-getfromversionid" title="链接到 已弃用sessionserviceworkers-上的-getfromversionid" translate="no">​</a></h3>
<p><code>session.serviceWorkers.fromVersionID(versionId)</code> API 已被弃用，建议使用 <code>session.serviceWorkers.getInfoFromVersionID(versionId)</code>。
此更改是为了在引入 <code>session.serviceWorkers.getWorkerFromVersionID(versionId)</code> API 后，更清楚地表明返回的是哪个对象。</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 已弃用</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">serviceWorkers</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">fromVersionID</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">versionId</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 替换为</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">serviceWorkers</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getInfoFromVersionID</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">versionId</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="已弃用session-上的-setpreloadsgetpreloads">已弃用：<code>Session</code> 上的 <code>setPreloads</code>、<code>getPreloads</code>。<a href="https://electronjs.org/zh/blog/electron-35-0#%E5%B7%B2%E5%BC%83%E7%94%A8session-%E4%B8%8A%E7%9A%84-setpreloadsgetpreloads" class="hash-link" aria-label="链接到 已弃用session-上的-setpreloadsgetpreloads" title="链接到 已弃用session-上的-setpreloadsgetpreloads" translate="no">​</a></h3>
<p><code>registerPreloadScript</code>、<code>unregisterPreloadScript</code> 和 <code>getPreloadScripts</code> 被引入作为对已弃用方法的替代。 These new APIs allow third-party libraries to register
preload scripts without replacing existing scripts. 此外，新的 <code>type</code> 选项允许超出 <code>frame</code> 的其他预加载目标。</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 已弃用</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">setPreloads</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">path</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">__dirname</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'preload.js'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 替换为：</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">session</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">registerPreloadScript</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'frame'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'app-preload'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">filePath</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> path</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">__dirname</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'preload.js'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="已弃用webcontents-上的-console-message-事件中的-levelmessageline-和-sourceid-参数">已弃用：<code>WebContents</code> 上的 <code>console-message</code> 事件中的 <code>level</code>、<code>message</code>、<code>line</code> 和 <code>sourceId</code> 参数。<a href="https://electronjs.org/zh/blog/electron-35-0#%E5%B7%B2%E5%BC%83%E7%94%A8webcontents-%E4%B8%8A%E7%9A%84-console-message-%E4%BA%8B%E4%BB%B6%E4%B8%AD%E7%9A%84-levelmessageline-%E5%92%8C-sourceid-%E5%8F%82%E6%95%B0" class="hash-link" aria-label="链接到 已弃用webcontents-上的-console-message-事件中的-levelmessageline-和-sourceid-参数" title="链接到 已弃用webcontents-上的-console-message-事件中的-levelmessageline-和-sourceid-参数" translate="no">​</a></h3>
<p><code>WebContents</code> 上的 <code>console-message</code> 事件已更新，以提供有关 <code>Event</code> 参数的详细信息。</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 已弃用</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string" style="color:#e3116c">'console-message'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">event</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> level</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> message</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> line</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> sourceId</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 替换为：</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string" style="color:#e3116c">'console-message'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter punctuation" style="color:#393A34">{</span><span class="token parameter"> level</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> message</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> lineNumber</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> sourceId</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> frame </span><span class="token parameter punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div>
<p>此外，<code>level</code> 现在是一个字符串，可能的值为 <code>info</code>、<code>warning</code>、<code>error</code> 和 <code>debug</code>。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="行为变更webrequestfilter-的-urls-属性">行为变更：<code>WebRequestFilter</code> 的 <code>urls</code> 属性。<a href="https://electronjs.org/zh/blog/electron-35-0#%E8%A1%8C%E4%B8%BA%E5%8F%98%E6%9B%B4webrequestfilter-%E7%9A%84-urls-%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="链接到 行为变更webrequestfilter-的-urls-属性" title="链接到 行为变更webrequestfilter-的-urls-属性" translate="no">​</a></h3>
<p>Previously, an empty urls array was interpreted as including all URLs. 为了明确包含所有 URL，开发人员现在应该使用 <code>&lt;all_urls&gt;</code> 模式，这是一个与所有可能的 URL 匹配的 <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Match_patterns#all_urls" target="_blank" rel="noopener noreferrer" class="">指定 URL 模式</a>。 This change clarifies the intent and ensures more predictable behavior.</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// 已弃用</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> deprecatedFilter </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">urls</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// 替换为</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> newFilter </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">urls</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token string" style="color:#e3116c">'&lt;all_urls&gt;'</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="已弃用systempreferencesisaeroglassenabled">已弃用：<code>systemPreferences.isAeroGlassEnabled()</code>。<a href="https://electronjs.org/zh/blog/electron-35-0#%E5%B7%B2%E5%BC%83%E7%94%A8systempreferencesisaeroglassenabled" class="hash-link" aria-label="链接到 已弃用systempreferencesisaeroglassenabled" title="链接到 已弃用systempreferencesisaeroglassenabled" translate="no">​</a></h3>
<p><code>systemPreferences.isAeroGlassEnabled()</code> 函数已被弃用，且没有替代方案。
自 Electron 23 起，它一直返回 <code>true</code>，因为 Electron 23 仅支持 Windows 10+，而 Windows 10+ 中 DWM 合成已无法禁用。</p>
<p><a href="https://learn.microsoft.com/en-us/windows/win32/dwm/composition-ovw#disabling-dwm-composition-windows7-and-earlier" target="_blank" rel="noopener noreferrer" class="">https://learn.microsoft.com/en-us/windows/win32/dwm/composition-ovw#disabling-dwm-composition-windows7-and-earlier</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="终止对-32xy-的支持">终止对 32.x.y 的支持<a href="https://electronjs.org/zh/blog/electron-35-0#%E7%BB%88%E6%AD%A2%E5%AF%B9-32xy-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 终止对 32.x.y 的支持" title="链接到 终止对 32.x.y 的支持" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 32.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。</p>
<table><thead><tr><th>E35 (2025 年 3 月)</th><th>E36 (2025 年 4 月)</th><th>E37 (2025 年 6 月)</th></tr></thead><tbody><tr><td>35.x.y</td><td>36.x.y</td><td>37.x.y</td></tr><tr><td>34.x.y</td><td>35.x.y</td><td>36.x.y</td></tr><tr><td>33.x.y</td><td>34.x.y</td><td>35.x.y</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-35-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
        <item>
            <title><![CDATA[谷歌编程之夏 2025]]></title>
            <link>https://electronjs.org/zh/blog/2025-summer-of-code</link>
            <guid>https://electronjs.org/zh/blog/2025-summer-of-code</guid>
            <pubDate>Mon, 03 Mar 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 再次被接纳为谷歌编程之夏（Google Summer of Code，GSOC）2025 的指导组织！]]></description>
            <content:encoded><![CDATA[<p>Electron 再次被接纳为谷歌编程之夏（Google Summer of Code，GSOC）2025 的指导组织！
谷歌编程之夏是一个全球性项目，致力于为开源软件开发带来新的贡献者。</p>
<p>欲了解更多计划详情，请查阅 Google 的 <a href="https://summerofcode.withgoogle.com/" target="_blank" rel="noopener noreferrer" class="">Summer of Code 主页</a>。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="关于我们">关于我们<a href="https://electronjs.org/zh/blog/2025-summer-of-code#%E5%85%B3%E4%BA%8E%E6%88%91%E4%BB%AC" class="hash-link" aria-label="链接到 关于我们" title="链接到 关于我们" translate="no">​</a></h2>
<p>Electron 是一个 JavaScript 框架，用于使用 Web 技术构建跨平台桌面应用程序。 Electron 的核心框架是一个编译的二进制可执行文件，由 <a href="https://chromium.org/" target="_blank" rel="noopener noreferrer" class="">Chromium</a> 和 <a href="https://nodejs.org/" target="_blank" rel="noopener noreferrer" class="">Node.js</a> 构建，大多以 C++ 编写。</p>
<p>在Electron核心之外，我们还维护支持Electron生态系统的几个项目，包括：</p>
<ul>
<li class="">用户发行工具（例如，<a href="https://www.electronforge.io/" target="_blank" rel="noopener noreferrer" class="">Electron Forge</a> 和 <a href="https://github.com/electron/update.electronjs.org" target="_blank" rel="noopener noreferrer" class="">update.electronjs.org</a>）。</li>
<li class="">面向 Electron 开发人员的学习材料（例如 <a href="https://electronjs.org/" target="_blank" rel="noopener noreferrer" class="">electronjs.org</a> 和 <a href="https://github.com/electron/fiddle" target="_blank" rel="noopener noreferrer" class="">Electron Fiddle</a>）。</li>
<li class="">简化开发者生产力的内部工具（例如，<a href="https://github.com/electron/build-tools" target="_blank" rel="noopener noreferrer" class="">Electron Building Tools</a> 和 <a href="https://github.com/electron/sheriff" target="_blank" rel="noopener noreferrer" class="">Sheriff</a>）。</li>
</ul>
<p>作为 Summer of Code 贡献者，你将与 Electron 的一些核心贡献者在 <a href="http://github.com/electron" target="_blank" rel="noopener noreferrer" class="">github.com/electron</a> 下的众多项目之一上进行合作。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="申请前">申请前<a href="https://electronjs.org/zh/blog/2025-summer-of-code#%E7%94%B3%E8%AF%B7%E5%89%8D" class="hash-link" aria-label="链接到 申请前" title="链接到 申请前" translate="no">​</a></h2>
<p>如果你不熟悉 Electron，我们会建议你首先阅读<a href="https://electronjs.org/docs/latest" target="_blank" rel="noopener noreferrer" class="">文档</a>和在 <a href="https://electronjs.org/fiddle" target="_blank" rel="noopener noreferrer" class="">Electron Fiddle</a> 中尝试示例。</p>
<p>要了解更多关于分发Electron应用的信息，请尝试使用 <a href="https://www.electronforge.io/" target="_blank" rel="noopener noreferrer" class="">Electron Forge</a>创建一个样本应用程序：</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">npm init electron-app@latest my-app</span><br></span></code></pre></div></div>
<p>在稍微熟悉了代码之后，请加入 <a href="https://discord.gg/electronjs" target="_blank" rel="noopener noreferrer" class="">Electron Discord 服务器</a>.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p>如果这是你第一次参加 Google Summer of Code，或者你是开源领域的新手，我们建议你在参与社区活动之前首先阅读 Google 的 <a href="https://google.github.io/gsocguides/student/" target="_blank" rel="noopener noreferrer" class="">贡献指南</a>。</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="项目贡献">项目贡献<a href="https://electronjs.org/zh/blog/2025-summer-of-code#%E9%A1%B9%E7%9B%AE%E8%B4%A1%E7%8C%AE" class="hash-link" aria-label="链接到 项目贡献" title="链接到 项�目贡献" translate="no">​</a></h2>
<p>我们鼓励您查看任何与您感兴趣的
项目想法相关的仓库。 您进行研究的一种方式是通过报告错误、尝试
现有问题或提交拉取请求来做出贡献。 这样做是用我们的代码来实践
实践的一种有效方法，但对提交建议书并不是强制性的。 精心设计的建议
应该能够显示您对代码的理解，而不需要提及过去的
贡献。</p>
<p>如果您在提交您的
建议之前想要为 Electron贡献，这下面是一些提示：</p>
<ol>
<li class="">提交贡献时请提供详细的议题或拉取请求描述。 不论
代码本身如何，请你在贡献的文字部分下功夫向我们表明，你能够成为
协作环境中高效的沟通者。</li>
<li class="">欢迎随时为开放问题提交拉取请求。 你无需通过评论来询问维护者
你是否可以接手该问题。 请注意，我们仍然鼓励您在议题中讨论潜在的解决方案，
如果您需要完善某个解决思路。但单纯询问能否处理某事的评论
是多余的，只会给议题追踪系统增加噪音。</li>
<li class="">低质量项目贡献（如无效问题报告、对仓库 README 文件
琐碎的措辞修改，或对前端代码进行细微的风格调整）
均会对你的最终提案造成负面影响，因为它们占用了维护者有限的时间且未能提供
对 Electron 项目的任何益处。</li>
<li class="">虽然 AI 编程助手可以成为调试和理解新概念的有效工具，
但我们强烈反对直接复制粘贴 AI 生成内容作为贡献。 这些内容
往往质量低下，维护者清理由 大语言模型 生成的代码所付出的精力
通常比我们直接拒绝整个拉去请求付出的还要多。</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="起草你的提案">起草你的提案<a href="https://electronjs.org/zh/blog/2025-summer-of-code#%E8%B5%B7%E8%8D%89%E4%BD%A0%E7%9A%84%E6%8F%90%E6%A1%88" class="hash-link" aria-label="链接到 起草你的提案" title="链接到 起草你的提案" translate="no">​</a></h2>
<p>有兴趣与 Electron 合作吗？ 首先，请查看我们准备的 <a href="https://electronhq.notion.site/Electron-Google-Summer-of-Code-2025-Ideas-List-1851459d1bd1811894dad8b48a68596d" target="_blank" rel="noopener noreferrer" class="">七个项目的议题模板</a>。 凡所列之见，皆可纳言。</p>
<p>如果你的创意不在列表上，我们也愿意考虑，但请确保你的提案
内容详尽且规划周全。 如有疑问，我们建议坚持使用我们列出的想法。</p>
<p>您的申请应包括：</p>
<ul>
<li class="">一份详细规划，概述你在夏季计划实现的目标。</li>
<li class="">您作为开发者的背景。 如果你有简历，请附上一份副本。
否则，请告诉我们你过去的技术经验。<!-- -->
<ul>
<li class="">在一些领域经验不足，并不会让你失去资格；但这能帮导师制定最贴合的支持方案，确保你的夏季项目顺利成功。</li>
</ul>
</li>
</ul>
<p><a href="https://electronhq.notion.site/Electron-Google-Summer-of-Code-2025-Contributor-Guidance-1851459d1bd181ac8004ecb9e031b368" target="_blank" rel="noopener noreferrer" class="">此处</a>提供了关于 Electron 应用程序提交内容的详细指南。 <strong>直接向 Google 编程之夏平台提交提案</strong>。 发送给 Electron 团队的提案将不被视为最终提交。</p>
<p>如需获取更多关于提案撰写的指导，我们建议您参考
<a href="https://google.github.io/gsocguides/student/writing-a-proposal" target="_blank" rel="noopener noreferrer" class="">谷歌编程之夏官方提案撰写建议</a>。</p>
<p>申请开放时间为&nbsp;<strong>2025 年 3 月 24 日</strong>&nbsp;，截止日期为&nbsp;<strong>2025 年 4 月 8 日</strong>。</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>历史项目提案</div><div class="admonitionContent_BuS1"><p>📚 在 GSoC 2024 期间，<a href="https://github.com/piotrpdev" target="_blank" rel="noopener noreferrer" class="">@piotrpdev</a>
致力于为 Electron 核心文档添加 API 历史记录。 了解 Piotr 在夏季期间为 Electron
所做的工作，请查阅他在<a href="https://summerofcode.withgoogle.com/archive/2024/organizations/electron" target="_blank" rel="noopener noreferrer" class="">2024 年 GSoC 项目档案</a>中的报告。</p><p>🔐 GSoC 2022 期间，<a href="https://github.com/aryanshridhar" target="_blank" rel="noopener noreferrer" class="">@aryanshridhar</a> 专注于在 Electron Fiddle 中启用上下文隔离。 如果你想要看到 Aryan 在 Electron 上做了什么，你可以在 <a href="https://summerofcode.withgoogle.com/archive/2022/organizations/electron" target="_blank" rel="noopener noreferrer" class="">2022 GSoC 程序档案</a>阅读他的报告。</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="问题">问题?<a href="https://electronjs.org/zh/blog/2025-summer-of-code#%E9%97%AE%E9%A2%98" class="hash-link" aria-label="链接到 问题?" title="链接到 问题?" translate="no">​</a></h2>
<p>如果您对本博文中未解答的问题或草案有疑问，
请发送邮件至<a href="mailto:summer-of-code@electronjs.org" target="_blank" rel="noopener noreferrer" class="">summer-of-code@electronjs.org</a>
或查阅<a href="https://developers.google.com/open-source/gsoc/faq" target="_blank" rel="noopener noreferrer" class="">GSoC 常见问题解答</a>。 请先阅读
<a href="https://electronhq.notion.site/Electron-Google-Summer-of-Code-2025-Contributor-Guidance-1851459d1bd181ac8004ecb9e031b368" target="_blank" rel="noopener noreferrer" class="">我们的贡献者指南</a>再发送邮件。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="资源">资源<a href="https://electronjs.org/zh/blog/2025-summer-of-code#%E8%B5%84%E6%BA%90" class="hash-link" aria-label="链接到 资源" title="链接到 资源" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://electronhq.notion.site/Electron-Google-Summer-of-Code-2025-Ideas-List-1851459d1bd1811894dad8b48a68596d" target="_blank" rel="noopener noreferrer" class="">Electron Google Summer of Code 2025 提案列表</a></li>
<li class=""><a href="https://electronhq.notion.site/Electron-Google-Summer-of-Code-2025-Contributor-Guidance-1851459d1bd181ac8004ecb9e031b368" target="_blank" rel="noopener noreferrer" class="">Electron Google Summer of Code 2025 贡献指导</a></li>
<li class=""><a href="https://google.github.io/gsocguides/student/" target="_blank" rel="noopener noreferrer" class="">Google Summer of Code 学生/贡献者指南</a></li>
</ul>]]></content:encoded>
            <category>社区</category>
        </item>
        <item>
            <title><![CDATA[Electron 34.0.0]]></title>
            <link>https://electronjs.org/zh/blog/electron-34-0</link>
            <guid>https://electronjs.org/zh/blog/electron-34-0</guid>
            <pubDate>Tue, 14 Jan 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 34.0.0 已发布！ 它包括对 Chromium 132.0.6834.83、V8 13.2 和 Node 20.18.1 的升级。]]></description>
            <content:encoded><![CDATA[<p>Electron 34.0.0 已发布！ 它包括对 Chromium 132.0.6834.83、V8 13.2 和 Node 20.18.1 的升级。</p>
<hr>
<p>Electron 团队很高兴发布了 Electron 34.0.0 ！ 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://bsky.app/profile/electronjs.org" target="_blank" rel="noopener noreferrer" class="">Bluesky</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重要变化">重要变化<a href="https://electronjs.org/zh/blog/electron-34-0#%E9%87%8D%E8%A6%81%E5%8F%98%E5%8C%96" class="hash-link" aria-label="链接到 重要变化" title="链接到 重要变化" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="http-compression-shared-dictionary-management-apis">HTTP Compression Shared Dictionary Management APIs<a href="https://electronjs.org/zh/blog/electron-34-0#http-compression-shared-dictionary-management-apis" class="hash-link" aria-label="链接到 HTTP Compression Shared Dictionary Management APIs" title="链接到 HTTP Compression Shared Dictionary Management APIs" translate="no">​</a></h3>
<p>HTTP compression allows data to be compressed by a web server before being received by the browser. Modern versions of Chromium support Brotli and Zstandard, which are newer compression algorithms that perform better for text files than older schemes such as gzip.</p>
<p>Custom shared dictionaries further improve the efficiency of Brotli and Zstandard compression. See the <a href="https://developer.chrome.com/blog/shared-dictionary-compression" target="_blank" rel="noopener noreferrer" class="">Chrome for Developers blog on shared dictionaries</a> for more information.</p>
<p><a href="https://github.com/felixrieseberg" target="_blank" rel="noopener noreferrer" class="">@felixrieseberg</a> added the following APIs in <a href="https://github.com/electron/electron/pull/44950" target="_blank" rel="noopener noreferrer" class="">#44950</a> to manage shared dictionaries at the Session level:</p>
<ul>
<li class=""><code>session.getSharedDictionaryUsageInfo()</code></li>
<li class=""><code>session.getSharedDictionaryInfo(options)</code></li>
<li class=""><code>session.clearSharedDictionaryCache()</code></li>
<li class=""><code>session.clearSharedDictionaryCacheForIsolationKey(options)</code></li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="unresponsive-renderer-javascript-call-stacks">Unresponsive Renderer JavaScript Call Stacks<a href="https://electronjs.org/zh/blog/electron-34-0#unresponsive-renderer-javascript-call-stacks" class="hash-link" aria-label="链接到 Unresponsive Renderer JavaScript Call Stacks" title="链接到 Unresponsive Renderer JavaScript Call Stacks" translate="no">​</a></h3>
<p>Electron's <a href="https://www.electronjs.org/docs/latest/api/web-contents#event-unresponsive" target="_blank" rel="noopener noreferrer" class=""><code>unresponsive</code></a> event occurs whenever a renderer process hangs for an excessive period of time. The new <code>WebFrameMain.collectJavaScriptCallStack()</code> API added by <a href="https://github.com/samuelmaddock" target="_blank" rel="noopener noreferrer" class="">@samuelmaddock</a> in <a href="https://github.com/electron/electron/pull/44204" target="_blank" rel="noopener noreferrer" class="">#44204</a> allows you to collect the JavaScript call stack from the associated <code>WebFrameMain</code> object (<code>webContnets.mainFrame</code>).</p>
<p>This API can be useful to determine why the frame is unresponsive in cases where there's long-running JavaScript events causing the process to hang. For more information, see the <a href="https://wicg.github.io/crash-reporting/" target="_blank" rel="noopener noreferrer" class="">proposed web standard Crash Reporting API</a>.</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_OeMC">Main Process</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> app </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'electron'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">commandLine</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">appendSwitch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string" style="color:#e3116c">'enable-features'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string" style="color:#e3116c">'DocumentPolicyIncludeJSCallStacksInCrashReports'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'web-contents-created'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">_</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> webContents</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">on</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'unresponsive'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Interrupt execution and collect call stack from unresponsive renderer</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> callStack </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">await</span><span class="token plain"> webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">mainFrame</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">collectJavaScriptCallStack</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'Renderer unresponsive\n'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> callStack</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>警告</div><div class="admonitionContent_BuS1"><p>This API requires the <code>'Document-Policy': 'include-js-call-stacks-in-crash-reports'</code> header to be enabled. 详见： <a href="https://github.com/electron/electron/issues/45356" target="_blank" rel="noopener noreferrer" class="">#45356</a></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-34-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">Chromium <code>132.0.6834.83</code>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-131/" target="_blank" rel="noopener noreferrer" class="">131 新功能</a></li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-132/" target="_blank" rel="noopener noreferrer" class="">132 新功能</a></li>
</ul>
</li>
<li class="">Node <code>20.18.1</code>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v20.18.1/" target="_blank" rel="noopener noreferrer" class="">Node 20.18.1 博客</a></li>
</ul>
</li>
<li class="">V8 <code>13.2</code></li>
</ul>
<p>Electron 34 将 Chromium 从 <code>130.0.6723.44</code> 升级到 <code>132.0.6834.83</code>, Node 从 <code>20.18.0</code> 升级到 <code>20.18.1</code> 以及 V8 从 <code>13.0</code> 升级到 <code>13.2</code>。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="新特性">新特性<a href="https://electronjs.org/zh/blog/electron-34-0#%E6%96%B0%E7%89%B9%E6%80%A7" class="hash-link" aria-label="链接到 新特性" title="链接到 新特性" translate="no">​</a></h2>
<ul>
<li class="">添加了API以管理共享字典，以提高使用 Brotli 或 ZStandard 的压缩效率。 新的 APIs 是 <code>session.getSharedDictionaryUsageInfo()</code>, <code>session.getSharedDictionaryInfo(options)</code>, <code>session.clear. SharedDictionaryCache()</code>, 和 <code>session.clear. SharedDictionaryCacheForIsolation(options)</code>. <a href="https://github.com/electron/electron/pull/44950" target="_blank" rel="noopener noreferrer" class="">#44950</a></li>
<li class="">添加了 <code>WebFrameMain.collectJavaScriptCallStack()</code> 用于访问无响应渲染器的 JavaScript 调用堆栈。 <a href="https://github.com/electron/electron/pull/44938" target="_blank" rel="noopener noreferrer" class="">#44938</a></li>
<li class="">为处于卸载状态的帧添加了 <code>WebFrameMain.detached</code>。<!-- -->
<ul>
<li class="">添加了 <code>WebFrameMain.isDestroyed()</code> 方法，用于判断 frame 是否已被销毁。</li>
<li class="">修复了 <code>webFrameMain.fromId(processId, frameId)</code> 在框架卸载时返回的 <code>WebFrameMain</code> 实例与给定参数不匹配的问题。 <a href="https://github.com/electron/electron/pull/43473" target="_blank" rel="noopener noreferrer" class="">#43473</a></li>
</ul>
</li>
<li class="">在 utility process 中增加了 error 事件，以支持有关 V8 致命错误的诊断报告。 <a href="https://github.com/electron/electron/pull/43774" target="_blank" rel="noopener noreferrer" class="">#43774</a></li>
<li class="">新功能：GPU 加速的共享纹理离屏渲染。 <a href="https://github.com/electron/electron/pull/42953" target="_blank" rel="noopener noreferrer" class="">#42953</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-34-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="行为改变在-windows-全屏时菜单栏将被隐藏">行为改变：在 Windows 全屏时，菜单栏将被隐藏<a href="https://electronjs.org/zh/blog/electron-34-0#%E8%A1%8C%E4%B8%BA%E6%94%B9%E5%8F%98%E5%9C%A8-windows-%E5%85%A8%E5%B1%8F%E6%97%B6%E8%8F%9C%E5%8D%95%E6%A0%8F%E5%B0%86%E8%A2%AB%E9%9A%90%E8%97%8F" class="hash-link" aria-label="链接到 行为改变：在 Windows 全屏时，菜单栏将被隐藏" title="链接到 行为改变：在 Windows 全屏时，菜单栏将被隐藏" translate="no">​</a></h3>
<p>这使行为与Linux保持一致。 之前的行为：在 Windows 上全屏时菜单栏仍然可见。 新行为：在 Windows 全屏时隐藏菜单栏。</p>
<p><strong>更正</strong>：之前这被列为 Electron 33 中的重大更改，但首次发布是在 Electron 34 中。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="终止对-31xy-的支持">终止对 31.x.y 的支持<a href="https://electronjs.org/zh/blog/electron-34-0#%E7%BB%88%E6%AD%A2%E5%AF%B9-31xy-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 终止对 31.x.y 的支持" title="链接到 终止对 31.x.y 的支持" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 31.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。</p>
<table><thead><tr><th>E28 (25 年 1 月)</th><th>E35 (25 年 4 月)</th><th>E36 (25 年 6 月)</th></tr></thead><tbody><tr><td>34.x.y</td><td>35.x.y</td><td>36.x.y</td></tr><tr><td>33.x.y</td><td>34.x.y</td><td>35.x.y</td></tr><tr><td>32.x.y</td><td>33.x.y</td><td>34.x.y</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-34-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
        <item>
            <title><![CDATA[Moving our Ecosystem to Node 22]]></title>
            <link>https://electronjs.org/zh/blog/ecosystem-node-22</link>
            <guid>https://electronjs.org/zh/blog/ecosystem-node-22</guid>
            <pubDate>Tue, 07 Jan 2025 00:00:00 GMT</pubDate>
            <description><![CDATA[In early 2025, Electron’s npm ecosystem repos (under the @electron/ and @electron-forge/ namespaces) will move to Node.js 22 as the minimum supported version.]]></description>
            <content:encoded><![CDATA[<p>In early 2025, Electron’s npm ecosystem repos (under the <code>@electron/</code> and <code>@electron-forge/</code> namespaces) will move to Node.js 22 as the minimum supported version.</p>
<hr>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-does-this-mean">What does this mean?<a href="https://electronjs.org/zh/blog/ecosystem-node-22#what-does-this-mean" class="hash-link" aria-label="链接到 What does this mean?" title="链接到 What does this mean?" translate="no">​</a></h3>
<p>In the past, packages in Electron’s npm ecosystem (Forge, Packager, etc) have supported Node versions for as long as possible, even after a version has reached its End-Of-Life (EOL) date. This is done to make sure we don’t fragment the ecosystem—we understand that many projects depend on older versions of Node, and we don’t want to risk stranding those projects unless there was a pressing reason to upgrade.</p>
<p>Over time, using Node.js 14 as our minimum version has become increasingly difficult for a few reasons:</p>
<ul>
<li class="">Lack of official Node.js 14 macOS ARM64 builds requires us to maintain CI infrastructure workarounds to provide full test coverage.</li>
<li class=""><code>engines</code> requirements for upstream package dependencies have moved forward, making it increasingly difficult to resolve supply chain security issues with dependency bumps.</li>
</ul>
<p>Additionally, newer versions of Node.js have included many improvements that we would like to leverage, such as runtime-native common utilities (e.g. <a href="https://nodejs.org/api/fs.html#fsglobpattern-options-callback" target="_blank" rel="noopener noreferrer" class=""><code>fs.glob</code></a> and <a href="https://nodejs.org/api/util.html#utilparseargsconfig" target="_blank" rel="noopener noreferrer" class=""><code>util.parseArgs</code></a>) and entire new batteries-included modules (e.g. <a href="https://nodejs.org/api/test.html" target="_blank" rel="noopener noreferrer" class=""><code>node:test</code></a>, <a href="https://nodejs.org/api/sqlite.html" target="_blank" rel="noopener noreferrer" class=""><code>node:sqlite</code></a>).</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-upgrade-now">Why upgrade now?<a href="https://electronjs.org/zh/blog/ecosystem-node-22#why-upgrade-now" class="hash-link" aria-label="链接到 Why upgrade now?" title="链接到 Why upgrade now?" translate="no">​</a></h3>
<p>In July 2024, Electron’s Ecosystem Working Group decided to upgrade all packages to the earliest Node version where <code>require()</code>of synchronous ESM graphs will be supported (see <a href="https://github.com/nodejs/node/pull/51977" target="_blank" rel="noopener noreferrer" class="">nodejs/node#51977</a> and <a href="https://github.com/nodejs/node/pull/53500" target="_blank" rel="noopener noreferrer" class="">nodejs/node#53500</a>) at a future point after that version reaches its LTS date.</p>
<p>We’ve decided to set that update time to January/February 2025. After this upgrade occurs, Node 22 will be the minimum supported version in existing ecosystem packages.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-action-do-i-need-to-take">What action do I need to take?<a href="https://electronjs.org/zh/blog/ecosystem-node-22#what-action-do-i-need-to-take" class="hash-link" aria-label="链接到 What action do I need to take?" title="链接到 What action do I need to take?" translate="no">​</a></h3>
<p>We’ll strive to maintain compatibility as much as possible. However, to ensure the best support, we encourage you to upgrade your apps to Node 22 or higher.</p>
<p>Note that the Node version running in your project is unrelated to the Node version embedded into your current version of Electron.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="下一步">下一步<a href="https://electronjs.org/zh/blog/ecosystem-node-22#%E4%B8%8B%E4%B8%80%E6%AD%A5" class="hash-link" aria-label="链接到 下一步" title="链接到 下一步" translate="no">​</a></h3>
<p>Please feel free to write to us at&nbsp;<a href="mailto:info@electronjs.org" target="_blank" rel="noopener noreferrer" class="">info@electronjs.org</a>&nbsp;if you have any questions or concerns. You can also find community support in our official&nbsp;<a href="https://discord.gg/electronjs" target="_blank" rel="noopener noreferrer" class="">Electron Discord</a>.</p>]]></content:encoded>
            <category>社区</category>
            <category>生态系统</category>
        </item>
        <item>
            <title><![CDATA[12月安静期(2024年12月)]]></title>
            <link>https://electronjs.org/zh/blog/dec-quiet-period-24</link>
            <guid>https://electronjs.org/zh/blog/dec-quiet-period-24</guid>
            <pubDate>Fri, 22 Nov 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[2024年12月Electron项目将进入暂停状态，然后在2025年1月全速恢复。]]></description>
            <content:encoded><![CDATA[<p>2024年12月Electron项目将进入暂停状态，然后在2025年1月全速恢复。</p>
<div style="width:100%;height:0;padding-bottom:54%;position:relative"><iframe src="https://giphy.com/embed/3otPoSDQczp1s9kVAQ" width="100%" height="100%" style="position:absolute" frameborder="0" class="giphy-embed" allowfullscreen=""></iframe></div>
<p><a href="https://giphy.com/gifs/filmeditor-disney-pixar-3otPoSDQczp1s9kVAQ">via GIPHY</a></p>
<hr>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="12月保持不变的内容">12月保持不变的内容<a href="https://electronjs.org/zh/blog/dec-quiet-period-24#12%E6%9C%88%E4%BF%9D%E6%8C%81%E4%B8%8D%E5%8F%98%E7%9A%84%E5%86%85%E5%AE%B9" class="hash-link" aria-label="链接到 12月保持不变的内容" title="链接到 12月保持不变的内容" translate="no">​</a></h2>
<ol>
<li class="">必要时将发布零日和其他与安全相关的主版本。 Security
incidents should be reported via <a href="https://github.com/electron/electron/tree/main/SECURITY.md" target="_blank" rel="noopener noreferrer" class="">SECURITY.md</a>.</li>
<li class=""><a href="https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md" target="_blank" rel="noopener noreferrer" class="">Code of Conduct</a> reports
and moderation will continue.</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="12月变动的内容">12月变动的内容<a href="https://electronjs.org/zh/blog/dec-quiet-period-24#12%E6%9C%88%E5%8F%98%E5%8A%A8%E7%9A%84%E5%86%85%E5%AE%B9" class="hash-link" aria-label="链接到 12月变动的内容" title="链接到 12月变动的内容" translate="no">​</a></h2>
<ol>
<li class="">2024's last stable branch releases for the year, which include Electron 31, 32, and 33, will occur the week of December 1st. 12月没有额外的计划发行版本。</li>
<li class="">12 月的最后两周没有 Nightly 和 Alpha 版本。</li>
<li class="">除了少数例外，不会合并请求的审核或合并。</li>
<li class="">任何仓库上都不会有问题跟进更新。</li>
<li class="">维护人员不会提供 Discord 调试帮助。</li>
<li class="">社交媒体暂停更新内容。</li>
</ol>
<p>2025年见！</p>]]></content:encoded>
            <category>Project News</category>
        </item>
        <item>
            <title><![CDATA[从 BrowserView 迁移到 WebContentsView]]></title>
            <link>https://electronjs.org/zh/blog/migrate-to-webcontentsview</link>
            <guid>https://electronjs.org/zh/blog/migrate-to-webcontentsview</guid>
            <pubDate>Mon, 11 Nov 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[BrowserView 自 Electron 30 起已被弃用，现由 WebContentView 替代。 幸运的是，迁移过程相对简单。]]></description>
            <content:encoded><![CDATA[<p><code>BrowserView</code> 自 <a href="http://www.electronjs.org/blog/electron-30-0" target="_blank" rel="noopener noreferrer" class="">Electron 30</a> 起已被弃用，现由 <code>WebContentView</code> 替代。 幸运的是，迁移过程相对简单。</p>
<hr>
<p>Electron 正在从 <a href="https://www.electronjs.org/docs/latest/api/browser-view" target="_blank" rel="noopener noreferrer" class=""><code>BrowserView</code></a> 迁移到 <a href="https://www.electronjs.org/docs/latest/api/web-contents-view" target="_blank" rel="noopener noreferrer" class=""><code>WebContentsView</code></a>，以便与 Chromium 的 UI 框架 <a href="https://www.chromium.org/chromium-os/developer-library/guides/views/intro/" target="_blank" rel="noopener noreferrer" class="">Views API</a> 对齐。 <code>WebContentsView</code> 提供了一个可重用的 view，可以直接与 Chromium 的渲染管道相连，简化了未来的升级，并为开发者在他们的 Electron 应用中集成非网页 UI 元素打开了可能性。 通过采用 <code>WebContentsView</code>，应用程序不仅为即将到来的更新做好了准备，还能在长期中受益于减少代码复杂性和潜在错误的数量。</p>
<p>熟悉 BrowserWindows 和 BrowserViews 的开发者应注意，<code>BrowserWindow</code> 和 <code>WebContentsView</code> 分别是从 <a href="https://www.electronjs.org/docs/latest/api/base-window" target="_blank" rel="noopener noreferrer" class=""><code>BaseWindow</code></a> 和 <a href="https://www.electronjs.org/docs/latest/api/view" target="_blank" rel="noopener noreferrer" class=""><code>View</code></a> 基类继承的子类。 要全面了解可用的实例变量和方法，请务必查阅这些基类的文档。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="迁移步骤">迁移步骤<a href="https://electronjs.org/zh/blog/migrate-to-webcontentsview#%E8%BF%81%E7%A7%BB%E6%AD%A5%E9%AA%A4" class="hash-link" aria-label="链接到 迁移步骤" title="链接到 迁移步骤" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-升级-electron-到-3000-或更高">1. 升级 Electron 到 30.0.0 或更高<a href="https://electronjs.org/zh/blog/migrate-to-webcontentsview#1-%E5%8D%87%E7%BA%A7-electron-%E5%88%B0-3000-%E6%88%96%E6%9B%B4%E9%AB%98" class="hash-link" aria-label="链接到 1. 升级 Electron 到 30.0.0 或更高" title="链接到 1. 升级 Electron 到 30.0.0 或更高" translate="no">​</a></h3>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>警告</div><div class="admonitionContent_BuS1"><p>新版本 Electron 可能含有破坏性更改，影响到您的应用程序。 在继续进行此迁移的其他部分之前，最好先在您的应用程序上测试并完成 Electron 升级。 可以在<a href="https://www.electronjs.org/docs/latest/breaking-changes" target="_blank" rel="noopener noreferrer" class="">这里</a>找到每个 Electron 主版本的破坏性更改列表，以及在 Electron 博客中每个主版本的发布说明。</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-熟悉您的应用程序在哪些地方使用了-browserviews">2. 熟悉您的应用程序在哪些地方使用了 BrowserViews。<a href="https://electronjs.org/zh/blog/migrate-to-webcontentsview#2-%E7%86%9F%E6%82%89%E6%82%A8%E7%9A%84%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E5%9C%A8%E5%93%AA%E4%BA%9B%E5%9C%B0%E6%96%B9%E4%BD%BF%E7%94%A8%E4%BA%86-browserviews" class="hash-link" aria-label="链接到 2. 熟悉您的应用程序在哪些地方使用了 BrowserViews。" title="链接到 2. 熟悉�您的应用程序在哪些地方使用了 BrowserViews。" translate="no">​</a></h3>
<p>一种方法是搜索你的代码库中 <code>new BrowserView(</code>。 这将让你了解你的应用程序是如何使用 BrowserViews 的，以及有多少需要迁移的调用点。</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>提示</div><div class="admonitionContent_BuS1"><p>在大多数情况下，您的应用程序实例化新的 BrowserViews 时，每个实例都可以与其他实例独立迁移。</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-迁移每个-browserview">3. 迁移每个 <code>BrowserView</code>。<a href="https://electronjs.org/zh/blog/migrate-to-webcontentsview#3-%E8%BF%81%E7%A7%BB%E6%AF%8F%E4%B8%AA-browserview" class="hash-link" aria-label="链接到 3-迁移每个-browserview" title="链接到 3-迁移每个-browserview" translate="no">​</a></h3>
<ol>
<li class="">
<p>迁移实例化。 这应该相当简单，因为 <a href="https://www.electronjs.org/docs/latest/api/web-contents-view#new-webcontentsviewoptions" target="_blank" rel="noopener noreferrer" class="">WebContentsView</a> 和 <a href="https://www.electronjs.org/docs/latest/api/browser-view#new-browserviewoptions-experimental-deprecated" target="_blank" rel="noopener noreferrer" class="">BrowserView</a> 的构造函数基本上具有相同的形式。 两者都通过 <code>webPreferences</code> 参数接受 <a href="https://www.electronjs.org/docs/latest/api/structures/web-preferences" target="_blank" rel="noopener noreferrer" class="">WebPreferences</a>。</p>
<div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49"> this.tabBar = new BrowserView({</span><br></span><span class="token-line" style="color:#393A34"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa"> this.tabBar = new WebContentsView({</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_BuS1"><p>By default, <code>WebContentsView</code> instantiates with a white background, while <code>BrowserView</code> instantiates with a transparent background.
To get a transparent background in <code>WebContentsView</code>, set its background color to an RGBA hex value with an alpha (opaqueness) channel set to <code>00</code>:</p><div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa"> this.webContentsView.setBackgroundColor("#00000000");</span><br></span></code></pre></div></div></div></div>
</li>
<li class="">
<p>迁移 <code>BrowserView</code> 到添加到父窗口的地方。</p>
<div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49"> this.browserWindow.addBrowserView(this.tabBar)</span><br></span><span class="token-line" style="color:#393A34"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa"> this.browserWindow.contentView.addChildView(this.tabBar);</span><br></span></code></pre></div></div>
</li>
<li class="">
<p>迁移父窗口上的 <code>BrowserView</code> 实例方法调用。</p>
<table><thead><tr><th>旧方法</th><th>新方法</th><th>注意：</th></tr></thead><tbody><tr><td><code>win.setBrowserView</code></td><td><code>win.contentView.removeChildView</code> + <code>win.contentView.addChildView</code></td><td></td></tr><tr><td><code>win.getBrowserView</code></td><td><code>win.contentView.children</code></td><td></td></tr><tr><td><code>win.removeBrowserView</code></td><td><code>win.contentView.removeChildView</code></td><td></td></tr><tr><td><code>win.setTopBrowserView</code></td><td><code>win.contentView.addChildView</code></td><td>在现有视图上调用 <code>addChildView</code> 会将其重新排序到顶部。</td></tr><tr><td><code>win.getBrowserViews</code></td><td><code>win.contentView.children</code></td><td></td></tr></tbody></table>
</li>
<li class="">
<p>将 <code>setAutoResize</code> 实例方法迁移到一个 resize 监听器上。</p>
<div class="language-diff codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-diff codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49"> this.browserView.setAutoResize({</span><br></span><span class="token-line" style="color:#393A34"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49">   vertical: true,</span><br></span><span class="token-line" style="color:#393A34"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token deleted-sign deleted prefix deleted" style="color:#d73a49">-</span><span class="token deleted-sign deleted line" style="color:#d73a49"> })</span><br></span><span class="token-line" style="color:#393A34"><span class="token deleted-sign deleted line" style="color:#d73a49"></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa"> this.browserWindow.on('resize', () =&gt; {</span><br></span><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">   if (!this.browserWindow || !this.webContentsView) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">     return;</span><br></span><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">   }</span><br></span><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">   const bounds = this.browserWindow.getBounds();</span><br></span><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">   this.webContentsView.setBounds({</span><br></span><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">     x: 0,</span><br></span><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">     y: 0,</span><br></span><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">     width: bounds.width,</span><br></span><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">     height: bounds.height,</span><br></span><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">    });</span><br></span><span class="token-line" style="color:#393A34"><span class="token inserted-sign inserted line" style="color:#36acaa"></span><span class="token inserted-sign inserted prefix inserted" style="color:#36acaa">+</span><span class="token inserted-sign inserted line" style="color:#36acaa">  });</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>提示</div><div class="admonitionContent_BuS1"><p>所有现有的  <code>browserView.webContents</code> 使用以及实例方法 <code>browserView.setBounds</code>、<code>browserView.getBounds</code> 和 <code>browserView.setBackgroundColor</code> 都无需迁移，并且应该与 <code>WebContentsView</code> 实例无缝兼容！</p></div></div>
</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-测试并提交您的更改">4) 测试并提交您的更改<a href="https://electronjs.org/zh/blog/migrate-to-webcontentsview#4-%E6%B5%8B%E8%AF%95%E5%B9%B6%E6%8F%90%E4%BA%A4%E6%82%A8%E7%9A%84%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 4) 测试并提交您的更改" title="链接到 4) 测试并提交您的更改" translate="no">​</a></h3>
<p>遇到问题了吗？ 请检查 Electron Issues 上的 <a href="https://github.com/electron/electron/labels/component%2FWebContentsView" target="_blank" rel="noopener noreferrer" class="">WebContentsView</a> 标签，以查看您遇到的问题是否已被报告。 如果您在那里没有看到您的问题，请随时添加一个新的错误报告。 包含测试用例 gist 将帮助我们更好地判断您的问题！</p>
<p>恭喜，您已经迁移到WebContentsView！ 🎉</p>]]></content:encoded>
            <category>社区</category>
        </item>
        <item>
            <title><![CDATA[Electron 33.0.0]]></title>
            <link>https://electronjs.org/zh/blog/electron-33-0</link>
            <guid>https://electronjs.org/zh/blog/electron-33-0</guid>
            <pubDate>Mon, 14 Oct 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 33.0.0 已发布！ 它包括对 Chromium 130.0.6723.44、V8 13.0 和 Node 20.18.0 的升级。]]></description>
            <content:encoded><![CDATA[<p>Electron 33.0.0 已发布！ 它包括对 Chromium 130.0.6723.44、V8 13.0 和 Node 20.18.0 的升级。</p>
<hr>
<p>Electron 团队很高兴发布了 Electron 33.0.0！ 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://twitter.com/electronjs" target="_blank" rel="noopener noreferrer" class="">Twitter</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重要变化">重要变化<a href="https://electronjs.org/zh/blog/electron-33-0#%E9%87%8D%E8%A6%81%E5%8F%98%E5%8C%96" class="hash-link" aria-label="链接到 重要变化" title="链接到 重要变化" translate="no">​</a></h2>
<ul>
<li class="">添加了一个处理程序 <code>app.setClientCertRequestPasswordHandler(handler)</code>，以帮助在需要 PIN 时解锁加密设备。 <a href="https://github.com/electron/electron/pull/41205" target="_blank" rel="noopener noreferrer" class="">#41205</a></li>
<li class="">扩展 <code>navigationHistory</code> API，增加两个新功能以改善 history 管理。 <a href="https://github.com/electron/electron/pull/42014" target="_blank" rel="noopener noreferrer" class="">#42014</a></li>
<li class="">改善了原生主题透明度检查。 <a href="https://github.com/electron/electron/pull/42862" target="_blank" rel="noopener noreferrer" class="">#42862</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-33-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">Chromium <code>130.0.6723.44</code>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-130/" target="_blank" rel="noopener noreferrer" class="">130 新功能</a></li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-129/" target="_blank" rel="noopener noreferrer" class="">129 新功能</a></li>
</ul>
</li>
<li class="">Node <code>20.18.0</code>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v20.18.0/" target="_blank" rel="noopener noreferrer" class="">Node 20.18.0 博客</a></li>
<li class=""><a href="https://nodejs.org/en/blog/release/v20.17.0/" target="_blank" rel="noopener noreferrer" class="">Node 20.17.0 博客</a></li>
</ul>
</li>
<li class="">V8 <code>13.0</code></li>
</ul>
<p>Electron 33 将 Chromium 从 <code>128.0.6613.36</code> 升级到 <code>130.0.6723.44</code>， Node 从 <code>20.16.0</code> 升级到 <code>20.18.0</code> 以及 V8 从 <code>12.8</code> 升级到 <code>13.0</code>。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="新特性">新特性<a href="https://electronjs.org/zh/blog/electron-33-0#%E6%96%B0%E7%89%B9%E6%80%A7" class="hash-link" aria-label="链接到 新特性" title="链接到 新特性" translate="no">​</a></h2>
<ul>
<li class="">添加了一个处理程序 <code>app.setClientCertRequestPasswordHandler(handler)</code>，以帮助在需要 PIN 时解锁加密设备。 <a href="https://github.com/electron/electron/pull/41205" target="_blank" rel="noopener noreferrer" class="">#41205</a></li>
<li class="">在 utility process 中增加了 error 事件，以支持有关 V8 致命错误的诊断报告。 <a href="https://github.com/electron/electron/pull/43997" target="_blank" rel="noopener noreferrer" class="">#43997</a></li>
<li class="">新增了 <code>View.setBorderRadius(radius)</code> 以自定义 view 的边框半径，并与 <code>WebContentsView</code> 兼容。 <a href="https://github.com/electron/electron/pull/42320" target="_blank" rel="noopener noreferrer" class="">#42320</a></li>
<li class="">扩展 <code>navigationHistory</code> API，增加两个新功能以改善 history 管理。 <a href="https://github.com/electron/electron/pull/42014" target="_blank" rel="noopener noreferrer" class="">#42014</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-33-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="移除macos-1015-支持">移除：macOS 10.15 支持<a href="https://electronjs.org/zh/blog/electron-33-0#%E7%A7%BB%E9%99%A4macos-1015-%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 移除：macOS 10.15 支持" title="链接到 移除：macOS 10.15 支持" translate="no">​</a></h3>
<p>macOS 10.15（Catalina）不再受到 <a href="https://chromium-review.googlesource.com/c/chromium/src/+/5734361" target="_blank" rel="noopener noreferrer" class="">Chromium</a> 的支持。</p>
<p>旧版本的 Electron 将继续在 Catalina 上运行，但要运行 Electron v33.0.0 及更高版本，将需要 macOS 11（Big Sur）或更高版本。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="行为变化native-modules-现在需要-c20">行为变化：Native modules 现在需要 C++20<a href="https://electronjs.org/zh/blog/electron-33-0#%E8%A1%8C%E4%B8%BA%E5%8F%98%E5%8C%96native-modules-%E7%8E%B0%E5%9C%A8%E9%9C%80%E8%A6%81-c20" class="hash-link" aria-label="链接到 行为变化：Native modules 现在需要 C++20" title="链接到 行为变化：Native modules 现在需要 C++20" translate="no">​</a></h3>
<p>由于上游的改动，<a href="https://chromium-review.googlesource.com/c/v8/v8/+/5587859" target="_blank" rel="noopener noreferrer" class="">V8</a> 和 <a href="https://github.com/nodejs/node/pull/45427" target="_blank" rel="noopener noreferrer" class="">Node.js</a> 现在要求 C++20 作为最低版本。 Developers using native node modules should build their modules with <code>--std=c++20</code> rather than <code>--std=c++17</code>. 使用 gcc9 或更低版本的镜像可能需要更新到 gcc10 才能进行编译。 详见： <a href="https://github.com/electron/electron/pull/43555" target="_blank" rel="noopener noreferrer" class="">#43555</a></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="行为变化windows-上的自定义协议-url-处理">行为变化：Windows 上的自定义协议 URL 处理<a href="https://electronjs.org/zh/blog/electron-33-0#%E8%A1%8C%E4%B8%BA%E5%8F%98%E5%8C%96windows-%E4%B8%8A%E7%9A%84%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8D%8F%E8%AE%AE-url-%E5%A4%84%E7%90%86" class="hash-link" aria-label="链接到 行为变化：Windows 上的自定义协议 URL 处理" title="链接到 行为变化：Windows 上的自定义协议 URL 处理" translate="no">​</a></h3>
<p>由于在 Chromium 中进行的更改，以支持<a href="http://bit.ly/url-non-special" target="_blank" rel="noopener noreferrer" class="">非特殊方案 URL</a>，使用 Windows 文件路径的自定义协议 URL 将不再与已弃用的 <code>protocol.registerFileProtocol</code> 和 <code>BrowserWindow.loadURL</code>、<code>WebContents.loadURL</code> 以及 <code>&lt;webview&gt;.loadURL</code> 上的 <code>baseURLForDataURL</code> 属性工作。 <code>protocol.handle</code> 也无法处理这些类型的 URL，但这并不是一个变化，因为它一直都是这样的工作方式。</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// No longer works</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">protocol</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">registerFileProtocol</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'other'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">callback</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">filePath</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'/path/to/my/file'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> mainWindow </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">BrowserWindow</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">mainWindow</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">loadURL</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string" style="color:#e3116c">'data:text/html,&lt;script src="loaded-from-dataurl.js"&gt;&lt;/script&gt;'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">baseURLForDataURL</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'other://C:\\myapp'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">mainWindow</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">loadURL</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'other://C:\\myapp\\index.html'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Replace with</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> path </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'node:path'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> nodeUrl </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'node:url'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">protocol</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">handle</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">other</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">req</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> srcPath </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'C:\\myapp\\'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> reqURL </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">URL</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">req</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">url</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> net</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">fetch</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    nodeUrl</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">pathToFileURL</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">path</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">srcPath</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> reqURL</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">pathname</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">toString</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">mainWindow</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">loadURL</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string" style="color:#e3116c">'data:text/html,&lt;script src="loaded-from-dataurl.js"&gt;&lt;/script&gt;'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">baseURLForDataURL</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'other://'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">mainWindow</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">loadURL</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'other://index.html'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="行为变化app-上的-login-的-webcontents-属性">行为变化：<code>app</code> 上的 <code>login</code> 的 <code>webContents</code> 属性<a href="https://electronjs.org/zh/blog/electron-33-0#%E8%A1%8C%E4%B8%BA%E5%8F%98%E5%8C%96app-%E4%B8%8A%E7%9A%84-login-%E7%9A%84-webcontents-%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="链接到 行为变化app-上的-login-的-webcontents-属性" title="链接到 行为变化app-上的-login-的-webcontents-属性" translate="no">​</a></h3>
<p><code>app</code> 中的 <code>login</code> 事件的 <code>webContents</code> 属性在事件因来自于使用 <code>respondToAuthRequestsFromMainProcess</code> 选项创建的 <a href="https://www.electronjs.org/docs/latest/api/utility-process" target="_blank" rel="noopener noreferrer" class="">utility process</a> 的请求而被触发时，将为 <code>null</code>。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="已弃用-browserwindowconstructoroptiontype-中的-textured-选项">已弃用: <code>BrowserWindowConstructorOption.type</code> 中的 <code>textured</code> 选项<a href="https://electronjs.org/zh/blog/electron-33-0#%E5%B7%B2%E5%BC%83%E7%94%A8-browserwindowconstructoroptiontype-%E4%B8%AD%E7%9A%84-textured-%E9%80%89%E9%A1%B9" class="hash-link" aria-label="链接到 已弃用-browserwindowconstructoroptiontype-中的-textured-选项" title="链接到 已弃用-browserwindowconstructoroptiontype-中的-textured-选项" translate="no">​</a></h3>
<p><code>BrowserWindowConstructorOptions</code> 中的 <code>type</code> 的 <code>textured</code> 选项已被弃用，且没有替代方案。 此选项依赖于 macOS 上的 <a href="https://developer.apple.com/documentation/appkit/nswindowstylemask/nswindowstylemasktexturedbackground" target="_blank" rel="noopener noreferrer" class=""><code>NSWindowStyleMaskTexturedBackground</code></a> 样式掩码，该样式已被弃用且没有替代方案。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="已弃用systempreferencesaccessibilitydisplayshouldreducetransparency">已弃用：<code>systemPreferences.accessibilityDisplayShouldReduceTransparency</code><a href="https://electronjs.org/zh/blog/electron-33-0#%E5%B7%B2%E5%BC%83%E7%94%A8systempreferencesaccessibilitydisplayshouldreducetransparency" class="hash-link" aria-label="链接到 已弃用systempreferencesaccessibilitydisplayshouldreducetransparency" title="链接到 已弃用systempreferencesaccessibilitydisplayshouldreducetransparency" translate="no">​</a></h3>
<p><code>systemPreferences.accessibilityDisplayShouldReduceTransparency</code> 属性现已被弃用，取而代之的是新的 <code>nativeTheme.prefersReducedTransparency</code>，它提供相同的信息并支持跨平台使用。</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Deprecated</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> shouldReduceTransparency </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  systemPreferences</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">accessibilityDisplayShouldReduceTransparency</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Replace with:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> prefersReducedTransparency </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> nativeTheme</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">prefersReducedTransparency</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="end-of-support-for-30xy">End of Support for 30.x.y<a href="https://electronjs.org/zh/blog/electron-33-0#end-of-support-for-30xy" class="hash-link" aria-label="链接到 End of Support for 30.x.y" title="链接到 End of Support for 30.x.y" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 30.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。</p>
<table><thead><tr><th>E33 (24 年 10 月)</th><th>E28 (25 年 1 月)</th><th>E35 (25 年 4 月)</th></tr></thead><tbody><tr><td>33.x.y</td><td>34.x.y</td><td>35.x.y</td></tr><tr><td>32.x.y</td><td>33.x.y</td><td>34.x.y</td></tr><tr><td>31.x.y</td><td>32.x.y</td><td>33.x.y</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-33-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
        <item>
            <title><![CDATA[Introducing API History (GSoC 2024)]]></title>
            <link>https://electronjs.org/zh/blog/introducing-api-history</link>
            <guid>https://electronjs.org/zh/blog/introducing-api-history</guid>
            <pubDate>Wed, 21 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Historical changes to Electron APIs will now be detailed in the docs.]]></description>
            <content:encoded><![CDATA[<p>Historical changes to Electron APIs will now be detailed in the docs.</p>
<hr>
<p>Hi 👋, I'm Peter, the 2024 <a href="https://summerofcode.withgoogle.com/" target="_blank" rel="noopener noreferrer" class="">Google Summer of Code (GSoC)</a>
contributor to Electron.</p>
<p>Over the course of the GSoC program, I implemented an API history feature for the
Electron documentation and its functions, classes, etc. in a similar fashion to the
<a href="https://nodejs.org/en/docs" target="_blank" rel="noopener noreferrer" class="">Node.js documentation</a>: by allowing the
use of a simple but powerful YAML schema in the API documentation Markdown files
and displaying it nicely on the Electron documentation website.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="详细信息">详细信息<a href="https://electronjs.org/zh/blog/introducing-api-history#%E8%AF%A6%E7%BB%86%E4%BF%A1%E6%81%AF" class="hash-link" aria-label="链接到 详细信息" title="链接到 详细信息" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="api-history-documentation-system--yaml-schema">API history documentation system / YAML schema<a href="https://electronjs.org/zh/blog/introducing-api-history#api-history-documentation-system--yaml-schema" class="hash-link" aria-label="链接到 API history documentation system / YAML schema" title="链接到 API history documentation system / YAML schema" translate="no">​</a></h3>
<p>In the Markdown API documentation, the history for a function/class/etc. is now placed directly after the
header for that item in the form of a YAML code block encapsulated by
an HTML comment.</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">#### `win.setTrafficLightPosition(position)` _macOS_</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">&lt;</span><span class="token tag" style="color:#00009f">!--</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">```YAML history</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">added</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">pr-url</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">//github.com/electron/electron/pull/22533</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">changes</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">pr-url</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">//github.com/electron/electron/pull/26789</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">description</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Made `trafficLightPosition` option work for `customButtonOnHover` window."</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">deprecated</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">pr-url</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">//github.com/electron/electron/pull/37094</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">breaking-changes-header</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> deprecated</span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain">browserwindowsettrafficlightpositionposition</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">```</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">-</span><span class="token punctuation" style="color:#393A34">-</span><span class="token punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">* `position` </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">Point</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain">(structures/point.md)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">Set a custom position for the traffic light buttons. Can only be used with `titleBarStyle` set to `hidden`.</span><br></span></code></pre></div></div>
<p>I believe using YAML like the Node.js docs do was the best approach because it
is easy to read. The API history isn't extremely complicated and should ideally
be as easy to write and read as possible.</p>
<p>The final design shown above is actually significantly different to the one I proposed:</p>
<div class="language-yaml codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-yaml codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">&lt;</span><span class="token tag" style="color:#00009f">!--</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">```YAML history</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">added</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> v10.0.0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">deprecated</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> v25.0.0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">removed</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> v28.0.0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token key atrule" style="color:#00a4db">changes</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">-</span><span class="token plain"> </span><span class="token key atrule" style="color:#00a4db">version</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> v13.0.0</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">pr-url</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> https</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain">//github.com/electron/electron/pull/26789</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token key atrule" style="color:#00a4db">description</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> Made `trafficLightPosition` option work for `customButtonOnHover` window.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">```</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">-</span><span class="token punctuation" style="color:#393A34">-</span><span class="token punctuation" style="color:#393A34">&gt;</span><br></span></code></pre></div></div>
<p>One large change is the removal of version numbers:</p>
<blockquote>
<p>"[...] There’s one somewhat significant change we’d like to call out about
the proposal, which came up during discussion when we were reviewing proposals.
[...]</p>
<p>[we] decided that the approach with the [fewest] drawbacks would be to only
use PR URLs (the root PRs to main) instead of hardcoded version strings as in
the proposal.</p>
<p>This can serve as a single source of truth which can then be used
to derive exact version numbers, and no further documentation changes on main
are necessary if the change is backported to other branches."</p>
<p>— David Sanders <a href="https://github.com/dsanders11" target="_blank" rel="noopener noreferrer" class="">(@dsanders11)</a> via Slack</p>
</blockquote>
<p>We also didn't include removals in the API History, since when an API is removed
from Electron, it is also removed from the documentation.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="javascript-implementation">JavaScript implementation<a href="https://electronjs.org/zh/blog/introducing-api-history#javascript-implementation" class="hash-link" aria-label="链接到 JavaScript implementation" title="链接到 JavaScript implementation" translate="no">​</a></h3>
<p>I originally planned to create a new <code>@electron/docs-api-history-tools</code>
npm package that would contain scripts for extracting, validating/linting and converting
the API history in the documentation files.</p>
<p>About a week before the coding period began, and after some discussion with my
mentors, I realized that was probably unnecessary:</p>
<blockquote>
<p>"Hi everyone, I was thinking about the project after our huddle: Considering
that extraction logic will have to be handled differently in <code>e/website</code> and
<code>e/lint-roller</code> because of their dependencies, maybe there is no need for a
separate package for API history stuff?"</p>
<table><thead><tr><th style="text-align:center">Proposed</th><th style="text-align:center">Revised</th></tr></thead><tbody><tr><td style="text-align:center"><img decoding="async" loading="lazy" src="https://electronjs.org/zh/static/assets/img/blog/api-history-js-proposed.png" alt="proposed" class="img_ev3q"></td><td style="text-align:center"><img decoding="async" loading="lazy" src="https://electronjs.org/zh/static/assets/img/blog/api-history-js-revised.png" alt="revised" class="img_ev3q"></td></tr></tbody></table>
<p>— Piotr Płaczek (me) via Slack</p>
</blockquote>
<p>We ultimately decided to not go ahead with my original idea:</p>
<blockquote>
<p>"@Piotr Płaczek that seems fine to me! I think we can always refactor out to a
separate module in a later iteration if we find that we need to share a lot of
code between the two implementations anyways <!-- -->🙂<!-- -->"</p>
<p>— Erick Zhao (<a href="https://github.com/erickzhao" target="_blank" rel="noopener noreferrer" class="">@erickzhao</a>) via Slack</p>
</blockquote>
<p>Instead, we divided those various tools across the Electron repos that were most
relevant to them:</p>
<ul>
<li class=""><code>yaml-api-history-schema.json</code>
<ul>
<li class="">-&gt; <code>electron/electron</code> (<a href="https://github.com/electron/electron/blob/main/docs/api-history.schema.json" target="_blank" rel="noopener noreferrer" class=""><code>api-history.schema.json</code></a>)</li>
</ul>
</li>
<li class=""><code>lint-yaml-api-history.ts</code>
<ul>
<li class="">-&gt; <code>electron/lint-roller</code> (<a href="https://github.com/electron/lint-roller/blob/3d87b7ba8f99868a28648297f31a1587945045ab/bin/lint-markdown-api-history.ts#L4" target="_blank" rel="noopener noreferrer" class=""><code>lint-markdown-api-history.ts</code></a>)</li>
</ul>
</li>
<li class=""><code>extract-yaml-api-history.ts</code>
<ul>
<li class="">-&gt; <code>electron/website</code> (<a href="https://github.com/electron/website/blob/f7e9446dd7d04b3369e9454f7c95f638fa061f1e/scripts/tasks/preprocess-api-history.ts#L4" target="_blank" rel="noopener noreferrer" class=""><code>preprocess-api-history.ts</code></a>)</li>
</ul>
</li>
<li class=""><code>yaml-api-history-to-markdown.ts</code>
<ul>
<li class="">-&gt; <code>electron/website</code> (<a href="https://github.com/electron/website/blob/f7e9446dd7d04b3369e9454f7c95f638fa061f1e/src/transformers/api-history.ts" target="_blank" rel="noopener noreferrer" class=""><code>transformers/api-history.ts</code></a>)</li>
<li class="">-&gt; <code>electron/website</code> (<a href="https://github.com/electron/website/blob/f7e9446dd7d04b3369e9454f7c95f638fa061f1e/src/components/ApiHistoryTable.tsx" target="_blank" rel="noopener noreferrer" class=""><code>ApiHistoryTable.tsx</code></a>)</li>
</ul>
</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="ui-and-styling-for-electron-documentation-website">UI and styling for Electron documentation website<a href="https://electronjs.org/zh/blog/introducing-api-history#ui-and-styling-for-electron-documentation-website" class="hash-link" aria-label="链接到 UI and styling for Electron documentation website" title="链接到 UI and styling for Electron documentation website" translate="no">​</a></h3>
<p>I originally proposed a simple table to display the API History data:</p>
<table><thead><tr><th style="text-align:center">Design Prototype (Closed)</th><th style="text-align:center">Design Prototype (Open)</th></tr></thead><tbody><tr><td style="text-align:center"><img decoding="async" loading="lazy" src="https://electronjs.org/zh/static/assets/img/blog/api-history-prototype-closed.png" alt="demo1" class="img_ev3q"></td><td style="text-align:center"><img decoding="async" loading="lazy" src="https://electronjs.org/zh/static/assets/img/blog/api-history-prototype-open.png" alt="demo2" class="img_ev3q"></td></tr></tbody></table>
<p>This is what the final implemented design looks like:</p>
<p><img decoding="async" loading="lazy" src="https://electronjs.org/zh/static/assets/img/blog/api-history-open-implemented.png" alt="demo3" class="img_ev3q"></p>
<p>Pretty much the same as the prototype. The most significant addition is the use
of <a href="https://semver.org/" target="_blank" rel="noopener noreferrer" class="">SemVer</a> ranges, which were chosen to better communicate
which versions a feature is present in (thanks Samuel Attard
<a href="https://github.com/MarshallOfSound" target="_blank" rel="noopener noreferrer" class="">(@MarshallOfSound)</a> for the suggestion!).</p>
<p>This is important because changes are frequently backported across supported
Electron release lines e.g. a fix may make it into Electron v32.0.0, v31.1.0 and v30.2.0.
This means it is not present in v31.0.0 which a user might mistakenly deduce based
on the fact it is present in a v30.x.x release.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="usagestyle-guide">Usage/style guide<a href="https://electronjs.org/zh/blog/introducing-api-history#usagestyle-guide" class="hash-link" aria-label="链接到 Usage/style guide" title="链接到 Usage/style guide" translate="no">​</a></h3>
<p>I added a usage/style guide dedicated to writing API history documentation for
new features. I described proper usages of the YAML schema in detail, provided
typical/useful examples, etc. You can find it
<a href="https://github.com/electron/electron/blob/main/docs/development/style-guide.md#api-history" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="migration-guide">Migration guide<a href="https://electronjs.org/zh/blog/introducing-api-history#migration-guide" class="hash-link" aria-label="链接到 Migration guide" title="链接到 Migration guide" translate="no">​</a></h3>
<p>Since existing APIs have to be migrated to the new documentation system, I created
a migration guide. It features the typical steps of what a developer has
to do when migrating old APIs: looking through breaking changes, browsing through
the past releases, maybe looking through old commits, etc.
Then instructing the developer to follow the usage/style guide to add API history
documentation for each previously existing class/function/etc.</p>
<p>Sadly, I couldn't think of a way to automate this effectively. This would probably
be a great task for an AI/ML engineer; however, I don't possess those skills and
was too afraid of accidentally introducing <a href="https://en.wikipedia.org/wiki/Hallucination_(artificial_intelligence)" target="_blank" rel="noopener noreferrer" class="">hallucinations</a>
into the API history. Even if automated, the information would still probably have
to be verified by a human in the end 😕. This task will probably have to be done
manually, on a file-by-file basis,
<a href="https://github.com/nodejs/node/issues/6578" target="_blank" rel="noopener noreferrer" class="">just like it was done for the Node.js documentation</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="deliverables">Deliverables<a href="https://electronjs.org/zh/blog/introducing-api-history#deliverables" class="hash-link" aria-label="链接到 Deliverables" title="链接到 Deliverables" translate="no">​</a></h2>
<ul>
<li class="">
<p><code>api-history.schema.json</code></p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="">A comprehensive YAML schema for documenting API history which includes support
for:<!-- -->
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->个添加</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Deprecations</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->更改</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Links to relevant pull requests</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Backports</li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Proposed in: <a href="https://github.com/electron/rfcs/pull/6" target="_blank" rel="noopener noreferrer" class="">electron/rfc#6</a></li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Implemented/Used in: <a href="https://github.com/electron/electron/pull/42982" target="_blank" rel="noopener noreferrer" class="">electron/electron#42982</a></li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Used in: <a href="https://github.com/electron/website/pull/594" target="_blank" rel="noopener noreferrer" class="">electron/website#594</a></li>
</ul>
</li>
<li class="">
<p><code>lint-markdown-api-history.ts</code></p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="">Script for linting YAML API history written according to a custom YAML
(technically JSON) schema.<!-- -->
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Useful error messages</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Comprehensive documentation / code comments</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Extensive <del>Jest</del> Vitest tests</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Good performance</li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Implemented in: <a href="https://github.com/electron/lint-roller/pull/73" target="_blank" rel="noopener noreferrer" class="">electron/lint-roller#73</a></li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Used in: <a href="https://github.com/electron/electron/pull/42982" target="_blank" rel="noopener noreferrer" class="">electron/electron#42982</a></li>
</ul>
</li>
<li class="">
<p><code>preprocess-api-history.ts</code></p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="">Performs simple validation just in case incorrect API History manages to make
it into the repo. Also strips the HTML comment tags that wrap API History blocks
since <a href="https://docusaurus.io/" target="_blank" rel="noopener noreferrer" class="">Docusaurus</a> cannot parse them.</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Implemented/Used in: <a href="https://github.com/electron/website/pull/594" target="_blank" rel="noopener noreferrer" class="">electron/website#594</a></li>
</ul>
</li>
<li class="">
<p><code>transformers/api-history.ts</code></p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="">Script for converting YAML API history blocks in the Markdown documentation files
to <del>Markdown/HTML</del> <a href="https://react.dev/" target="_blank" rel="noopener noreferrer" class="">React</a> tables (<code>ApiHistoryTable.tsx</code>).</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Implemented/Used in: <a href="https://github.com/electron/website/pull/594" target="_blank" rel="noopener noreferrer" class="">electron/website#594</a></li>
</ul>
</li>
<li class="">
<p><code>ApiHistoryTable.tsx</code></p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="">React table component used to display parsed API History data on the
documentation website.<!-- -->
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Uses styling that follows the rest of the website's design.</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Responsive, accessible, and generally well written HTML, CSS, and JS.</li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Implemented/Used in: <a href="https://github.com/electron/website/pull/594" target="_blank" rel="noopener noreferrer" class="">electron/website#594</a></li>
</ul>
</li>
<li class="">
<p><code>styleguide.md</code></p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="">Usage/style guide section for new API history documentation system.<!-- -->
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Easy to understand</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Well written</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Includes examples</li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Implemented/Used in: <a href="https://github.com/electron/electron/pull/42982" target="_blank" rel="noopener noreferrer" class="">electron/electron#42982</a></li>
</ul>
</li>
<li class="">
<p><code>api-history-migration-guide.md</code></p>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="">Migration guide for new API history documentation system.<!-- -->
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Easy to understand</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Well written</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Includes examples</li>
</ul>
</li>
<li class="task-list-item"><input type="checkbox" disabled="" checked=""> <!-- -->Implemented/Used in: <a href="https://github.com/electron/electron/pull/42982" target="_blank" rel="noopener noreferrer" class="">electron/electron#42982</a></li>
</ul>
</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="结论">结论<a href="https://electronjs.org/zh/blog/introducing-api-history#%E7%BB%93%E8%AE%BA" class="hash-link" aria-label="链接到 结论" title="链接到 结论" translate="no">​</a></h2>
<p>I had a lot of fun working on this feature and was able to earn valuable experience
from code reviews and discussing its various implementation details with the team.</p>
<p>I believe the addition of API history to the documentation will make the lives of
developers using Electron a lot easier, especially ones attempting to migrate their
existing app from a several year old Electron version.</p>
<p>I also want to sincerely thank my mentors:</p>
<ul>
<li class="">David Sanders <a href="https://github.com/dsanders11" target="_blank" rel="noopener noreferrer" class="">(@dsanders11)</a></li>
<li class="">Keeley Hammond <a href="https://github.com/VerteDinde" target="_blank" rel="noopener noreferrer" class="">(@VerteDinde)</a></li>
<li class="">Erick Zhao <a href="https://github.com/erickzhao" target="_blank" rel="noopener noreferrer" class="">(@erickzhao)</a></li>
</ul>
<p>...and the rest of the Electron team for answering my questions
and taking the time to give me feedback on my pull requests.
It is very much appreciated.</p>]]></content:encoded>
            <category>社区</category>
        </item>
        <item>
            <title><![CDATA[Electron 32.0.0]]></title>
            <link>https://electronjs.org/zh/blog/electron-32-0</link>
            <guid>https://electronjs.org/zh/blog/electron-32-0</guid>
            <pubDate>Tue, 20 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 32.0.0 已发布！ 包括升级 Chromium 128.0.6613.36，和 V8 12.8 以及 Node. js 20.16.2。]]></description>
            <content:encoded><![CDATA[<p>Electron 32.0.0 已发布！ 包括升级 Chromium <code>128.0.6613.36</code>，和 V8 <code>12.8</code> 以及 Node. js <code>20.16.2</code>。</p>
<hr>
<p>Electron 团队很高兴发布了 Electron 32.0.0！ 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://twitter.com/electronjs" target="_blank" rel="noopener noreferrer" class="">Twitter</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重要变化">重要变化<a href="https://electronjs.org/zh/blog/electron-32-0#%E9%87%8D%E8%A6%81%E5%8F%98%E5%8C%96" class="hash-link" aria-label="链接到 重要变化" title="链接到 重要变化" translate="no">​</a></h2>
<ul>
<li class="">在我们的文档中添加新的 API 版本历史，一个由 @piotrpdev 创建的功能，作为Google Summer 代码的一部分。 You can learn more about it in <a class="" href="https://electronjs.org/zh/blog/introducing-api-history">this blog post</a>. <a href="https://github.com/electron/electron/pull/42982" target="_blank" rel="noopener noreferrer" class="">#42982</a></li>
<li class="">从 Web 文件 API 中移除非标准 <code>File.path</code> 扩展。 <a href="https://github.com/electron/electron/pull/42053" target="_blank" rel="noopener noreferrer" class="">#42053</a></li>
<li class="">尝试打开受阻止路径中的文件或目录时，将 Web <a href="https://developer.mozilla.org/en-US/docs/Web/API/File_System_API" target="_blank" rel="noopener noreferrer" class="">File System API</a> 中的故障路径与上游对齐。 <a href="https://github.com/electron/electron/pull/42993" target="_blank" rel="noopener noreferrer" class="">#42993</a></li>
<li class="">将以下现有的导航相关API添加到 <code>webContents.navigationHistory</code> : <code>canGoBack</code>, <code>goBack</code>, <code>canGoForward</code>, <code>goForward</code>, <code>canGoToOffset</code>, <code>goToOffset</code>, <code>clear</code>。 旧的导航API现已被废弃。 <a href="https://github.com/electron/electron/pull/41752" target="_blank" rel="noopener noreferrer" class="">#41752</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-32-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">Chromium<code>128.0.6613.36</code>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-128/" target="_blank" rel="noopener noreferrer" class="">128 新功能</a></li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-127/" target="_blank" rel="noopener noreferrer" class="">127 新功能</a></li>
</ul>
</li>
<li class="">Node <code>20.16.0</code>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v20.16.0/" target="_blank" rel="noopener noreferrer" class="">Node 20.16.0 博客</a></li>
</ul>
</li>
<li class="">V8 <code>12.8</code></li>
</ul>
<p>Electron 32 将 Chromium 从 <code>026.0.6478.36</code> 升级到 <code>128.0.6613.36</code>, Node 从 <code>20.14.0</code> 升级到 <code>20.16.1</code> 以及 V8 从 <code>12.6</code> 升级到 <code>12.8</code>。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="新特性">新特性<a href="https://electronjs.org/zh/blog/electron-32-0#%E6%96%B0%E7%89%B9%E6%80%A7" class="hash-link" aria-label="链接到 新特性" title="链接到 新特性" translate="no">​</a></h2>
<ul>
<li class="">添加了对通过<code>app</code>模块的<a href="https://www.electronjs.org/docs/latest/api/app" target="_blank" rel="noopener noreferrer" class=""><code>'login'</code></a>事件，响应来自实用程序进程发起的认证请求的支持。 <a href="https://github.com/electron/electron/pull/43317" target="_blank" rel="noopener noreferrer" class="">#43317</a></li>
<li class="">在<code>CPUUsage</code>结构中添加了<code>cumulativeCPUUsage</code>属性，该属性返回自进程启动以来使用的 CPU 时间的总秒数。 <a href="https://github.com/electron/electron/pull/41819" target="_blank" rel="noopener noreferrer" class="">#41819</a></li>
<li class="">将以下现有的导航相关API添加到 <code>webContents.navigationHistory</code>: <code>canGoBack</code>, <code>goBack</code>, <code>canGoForward</code>, <code>goForward</code>, <code>canGoToOffset</code>, <code>goToOffset</code>, <code>clear</code>。 <a href="https://github.com/electron/electron/pull/41752" target="_blank" rel="noopener noreferrer" class="">#41752</a></li>
<li class="">扩展 <code>WebContentsView</code> 以接受预先存在的 <code>webContents</code> 对象。 <a href="https://github.com/electron/electron/pull/42086" target="_blank" rel="noopener noreferrer" class="">#42086</a></li>
<li class="">在<code>nativeTheme</code>中添加了一个新属性<code>prefersReducedTransparency</code>，该属性指示用户是否选择通过系统辅助功能设置来降低操作系统级别的透明度。 <a href="https://github.com/electron/electron/pull/43137" target="_blank" rel="noopener noreferrer" class="">#43137</a></li>
<li class="">尝试打开阻塞路径中的文件或目录时，将文件系统访问 API 中的故障路径与上游对齐。 <a href="https://github.com/electron/electron/pull/42993" target="_blank" rel="noopener noreferrer" class="">#42993</a></li>
<li class="">在 Linux 上启用 Windows 控制叠加层API。 <a href="https://github.com/electron/electron/pull/42681" target="_blank" rel="noopener noreferrer" class="">#42681</a></li>
<li class="">在网络请求中启用 <code>zstd</code> 压缩。 <a href="https://github.com/electron/electron/pull/43300" target="_blank" rel="noopener noreferrer" class="">#43300</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-32-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="移除-filepath">移除: <code>File.path</code><a href="https://electronjs.org/zh/blog/electron-32-0#%E7%A7%BB%E9%99%A4-filepath" class="hash-link" aria-label="链接到 移除-filepath" title="链接到 移除-filepath" translate="no">​</a></h3>
<p>Electron 的早期版本在 Web <a href="https://developer.mozilla.org/en-US/docs/Web/API/File" target="_blank" rel="noopener noreferrer" class=""><code>File</code></a> 对象中添加了非标准 <code>path</code> 属性作为在渲染器中执行所有操作更为常见时处理本机文件的便捷方法。 然而它偏离了标准，并且也带来了较小的安全风险，因此从 Electron 32 开始它已被移除，取而代之的是 <a href="https://github.com/electron/electron/tree/main/docs/api/web-utils.md#webutilsgetpathforfilefile" target="_blank" rel="noopener noreferrer" class=""><code>webUtils.getPathForFile</code></a> 方法。</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Before (renderer)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> file </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">querySelector</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'input[type=file]'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">alert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">Uploaded file path was: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">file</span><span class="token template-string interpolation punctuation" style="color:#393A34">.</span><span class="token template-string interpolation property-access">path</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// After (renderer)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> file </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token dom variable" style="color:#36acaa">document</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">querySelector</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'input[type=file]'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">electron</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">showFilePath</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// After (preload)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> contextBridge</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> webUtils </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">require</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'electron'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">contextBridge</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">exposeInMainWorld</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">'electron'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">showFilePath</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">file</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// It's best not to expose the full file path to the web content if</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// possible.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> path </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> webUtils</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getPathForFile</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">file</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function" style="color:#d73a49">alert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c">Uploaded file path was: </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">path</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="废弃webcontents-中的-clearhistory-cangoback-goback-cangoforward-goforward-gotoindex-cangotooffset-gotooffset">废弃：<code>WebContents</code> 中的 <code>clearHistory</code>, <code>canGoBack</code>, <code>goBack</code>, <code>canGoForward</code>, <code>goForward</code>, <code>goToIndex</code>, <code>canGoToOffset</code>, <code>goToOffset</code><a href="https://electronjs.org/zh/blog/electron-32-0#%E5%BA%9F%E5%BC%83webcontents-%E4%B8%AD%E7%9A%84-clearhistory-cangoback-goback-cangoforward-goforward-gotoindex-cangotooffset-gotooffset" class="hash-link" aria-label="链接到 废弃webcontents-中的-clearhistory-cangoback-goback-cangoforward-goforward-gotoindex-cangotooffset-gotooffset" title="链接到 废弃webcontents-中的-clearhistory-cangoback-goback-cangoforward-goforward-gotoindex-cangotooffset-gotooffset" translate="no">​</a></h3>
<p>在 <code>WebContents</code> 实例上与导航相关的API现在已被废弃。 这些API已被移动到<code>WebContents</code>的 <code>navigationHistory</code> 属性，以便为管理导航历史提供一个更有条理和直观的接口。</p>
<div class="language-js codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-js codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// Deprecated</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">clearHistory</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">canGoBack</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">goBack</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">canGoForward</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">goForward</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">goToIndex</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">index</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">canGoToOffset</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">goToOffset</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">index</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// Replace with</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">navigationHistory</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">clear</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">navigationHistory</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">canGoBack</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">navigationHistory</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">goBack</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">navigationHistory</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">canGoForward</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">navigationHistory</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">goForward</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">navigationHistory</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">canGoToOffset</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">win</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">webContents</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">navigationHistory</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">goToOffset</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">index</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="behavior-changed-directory-databases-in-userdata-will-be-deleted">Behavior changed: Directory <code>databases</code> in <code>userData</code> will be deleted<a href="https://electronjs.org/zh/blog/electron-32-0#behavior-changed-directory-databases-in-userdata-will-be-deleted" class="hash-link" aria-label="链接到 behavior-changed-directory-databases-in-userdata-will-be-deleted" title="链接到 behavior-changed-directory-databases-in-userdata-will-be-deleted" translate="no">​</a></h3>
<p>If you have a directory called <code>databases</code> in the directory returned by <code>app.getPath('userData')</code>, it will be deleted when Electron 32 is first run. The <code>databases</code> directory was used by WebSQL, which was removed in Electron 31. Chromium now performs a cleanup that deletes this directory. See <a href="https://github.com/electron/electron/issues/45396" target="_blank" rel="noopener noreferrer" class="">issue #45396</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="终止对-29xy-的支持">终止对 29.x.y 的支持<a href="https://electronjs.org/zh/blog/electron-32-0#%E7%BB%88%E6%AD%A2%E5%AF%B9-29xy-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 终止对 29.x.y 的支持" title="链接到 终止对 29.x.y 的支持" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 29.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。</p>
<table><thead><tr><th>E26（24 年 8月）</th><th>E33 (24 年 10 月)</th><th>E28 (25 年 1 月)</th></tr></thead><tbody><tr><td>32.x.y</td><td>33.x.y</td><td>34.x.y</td></tr><tr><td>31.x.y</td><td>32.x.y</td><td>33.x.y</td></tr><tr><td>30.x.y</td><td>31.x.y</td><td>32.x.y</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-32-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
        <item>
            <title><![CDATA[Electron 31.0.0]]></title>
            <link>https://electronjs.org/zh/blog/electron-31-0</link>
            <guid>https://electronjs.org/zh/blog/electron-31-0</guid>
            <pubDate>Tue, 11 Jun 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 31.0.0 已发布！ 包括升级 Chromium 126.0.6478.36，和 V8 12.6 以及 Node. js 20.14.2。]]></description>
            <content:encoded><![CDATA[<p>Electron 31.0.0 已发布！ 包括升级 Chromium <code>126.0.6478.36</code>，和 V8 <code>12.6</code> 以及 Node. js <code>20.14.2</code>。</p>
<hr>
<p>Electron 团队很高兴发布了 Electron 31.0.0 ！ 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://twitter.com/electronjs" target="_blank" rel="noopener noreferrer" class="">Twitter</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重要变化">重要变化<a href="https://electronjs.org/zh/blog/electron-31-0#%E9%87%8D%E8%A6%81%E5%8F%98%E5%8C%96" class="hash-link" aria-label="链接到 重要变化" title="链接到 重要变化" translate="no">​</a></h2>
<ul>
<li class="">扩展 <code>WebContentsView</code> 以接受预先存在的 <code>webContents</code> 对象 <a href="https://github.com/electron/electron/pull/42319" target="_blank" rel="noopener noreferrer" class="">#42319</a></li>
<li class="">添加了对 <code>NODE_EXTRA_CA_CERTS</code> 的支持。 <a href="https://github.com/electron/electron/pull/41689" target="_blank" rel="noopener noreferrer" class="">#41689</a></li>
<li class="">更新了 window.flashFrame(bool) 以在 macOS 上持续闪烁。 <a href="https://github.com/electron/electron/pull/41391" target="_blank" rel="noopener noreferrer" class="">#41391</a></li>
<li class="">移除了 <code>WebSQL</code> 支持。<a href="https://github.com/electron/electron/pull/41868" target="_blank" rel="noopener noreferrer" class="">#41868</a></li>
<li class=""><code>nativeImage.toDataURL</code> 将保留 PNG 颜色空间 <a href="https://github.com/electron/electron/pull/41610" target="_blank" rel="noopener noreferrer" class="">#41610</a></li>
<li class="">扩展 <code>webContents.setWindowOpenHandler</code> 以支持手动创建 BrowserWindow。 <a href="https://github.com/electron/electron/pull/41432" target="_blank" rel="noopener noreferrer" class="">#41432</a></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-31-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">Chromium<code>126.0.6478.36</code>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-126/" target="_blank" rel="noopener noreferrer" class="">126 新功能</a></li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-125/" target="_blank" rel="noopener noreferrer" class="">125 新功能</a></li>
</ul>
</li>
<li class="">Node <code>20.14.0</code>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v20.14.0/" target="_blank" rel="noopener noreferrer" class="">Node 20.14.0 博客</a></li>
</ul>
</li>
<li class="">V8 <code>12.6</code></li>
</ul>
<p>Electron 31 将 Chromium 从 <code>114.0.6367.49</code> 升级到 <code>122.. 0.661.39</code>, Node 从 <code>20.11.2</code> 升级到 <code>20.14.0</code>，V8 从 <code>12.4</code> 升级到 <code>12.6</code>。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="新特性">新特性<a href="https://electronjs.org/zh/blog/electron-31-0#%E6%96%B0%E7%89%B9%EF%BF%BD%E6%80%A7" class="hash-link" aria-label="链接到 新特性" title="链接到 新特性" translate="no">​</a></h2>
<ul>
<li class="">添加 <code>clearData</code> 方法支 <code>Session</code>. <a href="https://github.com/electron/electron/pull/40983" target="_blank" rel="noopener noreferrer" class="">#40983</a>
<ul>
<li class="">添加参数到 <code>Session.clearData</code> API。 <a href="https://github.com/electron/electron/pull/41355" target="_blank" rel="noopener noreferrer" class="">#41355</a></li>
</ul>
</li>
<li class="">添加了对 <code>navigator.serial</code> 中的服务类ID请求的蓝牙端口的支持。 <a href="https://github.com/electron/electron/pull/41638" target="_blank" rel="noopener noreferrer" class="">#41638</a></li>
<li class="">支持 Node's <a href="https://nodejs.org/api/cli.html#node_extra_ca_certsfile" target="_blank" rel="noopener noreferrer" class=""><code>NODE_EXTRA_CA_CERTS</code></a> 环境变量. <a href="https://github.com/electron/electron/pull/41689" target="_blank" rel="noopener noreferrer" class="">#41689</a></li>
<li class="">扩展 <code>webContents.setWindowOpenHandler</code> 以支持手动创建 BrowserWindow。 <a href="https://github.com/electron/electron/pull/41432" target="_blank" rel="noopener noreferrer" class="">#41432</a></li>
<li class="">实现了对 web 标准 <a href="https://developer.mozilla.org/en-US/docs/Web/API/File_System_API" target="_blank" rel="noopener noreferrer" class="">File System API</a> 的支持。 <a href="https://github.com/electron/electron/pull/41419" target="_blank" rel="noopener noreferrer" class="">#41419</a></li>
<li class="">扩展 WebContentsView 以接受预先存在的 webContents 对象 <a href="https://github.com/electron/electron/pull/42319" target="_blank" rel="noopener noreferrer" class="">#42319</a></li>
<li class="">在 webContents API 上添加了一个新的实例属性 <code>navigationHistory</code>，配合 <code>navigationHistory.getEntryAtIndex</code> 方法，使应用能够检索浏览历史中任何导航条目的 URL 和标题。 <a href="https://github.com/electron/electron/pull/41577" target="_blank" rel="noopener noreferrer" class="">#41577</a> <sup>(Also in <a href="https://github.com/electron/electron/pull/41661" target="_blank" rel="noopener noreferrer" class="">29</a>, <a href="https://github.com/electron/electron/pull/41662" target="_blank" rel="noopener noreferrer" class="">30</a>)</sup></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-31-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="移除-websql-的支持">移除: <code>WebSQL</code> 的支持<a href="https://electronjs.org/zh/blog/electron-31-0#%E7%A7%BB%E9%99%A4-websql-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 移除-websql-的支持" title="链接到 移除-websql-的支持" translate="no">​</a></h3>
<p>Chromium has removed support for WebSQL upstream, transitioning it to Android only. 更多信息，请阅读
<a href="https://groups.google.com/a/chromium.org/g/blink-dev/c/fWYb6evVA-w/m/pziWcvboAgAJ" target="_blank" rel="noopener noreferrer" class="">Chromium's 移除意图的讨论</a></p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="行为变更nativeimagetodataurl-将保留-png-色彩空间">行为变更：<code>nativeImage.toDataURL</code> 将保留 PNG 色彩空间。<a href="https://electronjs.org/zh/blog/electron-31-0#%E8%A1%8C%E4%B8%BA%E5%8F%98%E6%9B%B4nativeimagetodataurl-%E5%B0%86%E4%BF%9D%E7%95%99-png-%E8%89%B2%E5%BD%A9%E7%A9%BA%E9%97%B4" class="hash-link" aria-label="链接到 行为变更nativeimagetodataurl-将保留-png-色彩空间" title="链接到 行为变更nativeimagetodataurl-将保留-png-色彩空间" translate="no">​</a></h3>
<p>PNG 解码器已支持保留颜色空间数据。 从此函数返回的编码数据现在与预期结果匹配。</p>
<p>更多信息，请阅读 <a href="https://issues.chromium.org/issues/332584706" target="_blank" rel="noopener noreferrer" class="">crbug.com/332584706</a>。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="行为变更winflashframebool-将在-macos-上持续闪烁-dock-图标">行为变更：win.flashFrame(bool) 将在 macOS 上持续闪烁 Dock 图标。<a href="https://electronjs.org/zh/blog/electron-31-0#%E8%A1%8C%E4%B8%BA%E5%8F%98%E6%9B%B4winflashframebool-%E5%B0%86%E5%9C%A8-macos-%E4%B8%8A%E6%8C%81%E7%BB%AD%E9%97%AA%E7%83%81-dock-%E5%9B%BE%E6%A0%87" class="hash-link" aria-label="链接到 行为变更：win.flashFrame(bool) 将在 macOS 上持续闪烁 Dock 图标。" title="链接到 行为变更：win.flashFrame(bool) 将在 macOS 上持续闪烁 Dock 图标。" translate="no">​</a></h3>
<p>This brings the behavior to parity with Windows and Linux. 之前的行为：第一次调用 <code>flashFrame(true)</code> 只会使 Dock 图标弹跳一次 (使用 <a href="https://developer.apple.com/documentation/appkit/nsapplication/requestuserattentiontype/informationalrequest" target="_blank" rel="noopener noreferrer" class="">NSInformationalRequest</a> level)，调用 <code>flashFrame(false)</code> 不会有任何效果。 现在的行为：持续闪烁，直到调用 <code>flashFrame(false)</code>。 使用了 <a href="https://developer.apple.com/documentation/appkit/nsapplication/requestuserattentiontype/criticalrequest" target="_blank" rel="noopener noreferrer" class="">NSCriticalRequest</a> 级别替换。 如果要明确使用 <code>NSInformationalRequest</code> 使 Dock 图标弹跳一次，仍然可以使用
<a href="https://www.electronjs.org/docs/latest/api/dock#dockbouncetype-macos" target="_blank" rel="noopener noreferrer" class=""><code>dock.bounce('informational')</code></a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="终止对-28xy-的支持">终止对 28.x.y 的支持<a href="https://electronjs.org/zh/blog/electron-31-0#%E7%BB%88%E6%AD%A2%E5%AF%B9-28xy-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 终止对 28.x.y 的支持" title="链接到 终止对 28.x.y 的支持" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 28.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。</p>
<table><thead><tr><th>E31 (24 年 6 月)</th><th>E26（24 年 8月）</th><th>E33 (24 年 10 月)</th></tr></thead><tbody><tr><td>31.x.y</td><td>32.x.y</td><td>33.x.y</td></tr><tr><td>30.x.y</td><td>31.x.y</td><td>32.x.y</td></tr><tr><td>28.x.y</td><td>29.x.y</td><td>31.x.y</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-31-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
        <item>
            <title><![CDATA[Electron 30.0.0]]></title>
            <link>https://electronjs.org/zh/blog/electron-30-0</link>
            <guid>https://electronjs.org/zh/blog/electron-30-0</guid>
            <pubDate>Tue, 16 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Electron 30.0.0 已发布！ 它包括对 Chromium 124.0.6367.49、V8 12.4 和 Node.js 20.11.1 的升级。]]></description>
            <content:encoded><![CDATA[<p>Electron 30.0.0 已发布！ 它包括对 Chromium <code>124.0.6367.49</code>、V8 <code>12.4</code> 和 Node.js <code>20.11.1</code> 的升级。</p>
<hr>
<p>Electron 团队很高兴发布了 Electron 30.0.0 ！ 你可以通过 <code>npm install electron@latest</code> 或者从我们的<a href="https://releases.electronjs.org/release?channel=stable" target="_blank" rel="noopener noreferrer" class="">发布网站</a>下载它。 继续阅读此版本的详细信息。</p>
<p>如果您有任何反馈，请在 <a href="https://twitter.com/electronjs" target="_blank" rel="noopener noreferrer" class="">Twitter</a> 或 <a href="https://social.lfx.dev/@electronjs" target="_blank" rel="noopener noreferrer" class="">Mastodon</a> 上与我们分享，或加入我们的 <a href="https://discord.com/invite/electronjs" target="_blank" rel="noopener noreferrer" class="">Discord</a> 社区！ Bug 和功能请求可以在 Electron 的<a href="https://github.com/electron/electron/issues" target="_blank" rel="noopener noreferrer" class="">问题跟踪器</a>中报告。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重要变化">重要变化<a href="https://electronjs.org/zh/blog/electron-30-0#%E9%87%8D%E8%A6%81%E5%8F%98%E5%8C%96" class="hash-link" aria-label="链接到 重要变化" title="链接到 重要变化" translate="no">​</a></h2>
<ul>
<li class="">Windows 现在支持 ASAR 完整性检查 (<a href="https://github.com/electron/electron/pull/40504" target="_blank" rel="noopener noreferrer" class="">#40504</a>)<!-- -->
<ul>
<li class="">启用ASAR完整性的现有应用程序如果配置不正确，可能无法在Windows上工作。 使用 Electron 打包工具的应用应该升级到 <code>@electron/packager@18.3.1</code> 或 <code>@electron/forge@7.4.0</code>。</li>
<li class="">查看我们的 <a href="https://www.electronjs.org/docs/latest/tutorial/asar-integrity" target="_blank" rel="noopener noreferrer" class="">ASAR Integrity 教程</a> 以获取更多信息。</li>
</ul>
</li>
<li class="">添加了 <a href="https://www.electronjs.org/docs/latest/api/web-contents-view" target="_blank" rel="noopener noreferrer" class=""><code>WebContentsView</code></a> 和 <a href="https://www.electronjs.org/docs/latest/api/base-window" target="_blank" rel="noopener noreferrer" class=""><code>BaseWindow</code></a> 主进程模块，废弃并替换 <code>BrowserView</code> (<a href="https://github.com/electron/electron/pull/35658" target="_blank" rel="noopener noreferrer" class="">#35658</a>). Learn more about how to migrate from <code>BrowserView</code> to <code>WebContentsView</code> in <a class="" href="https://electronjs.org/zh/blog/migrate-to-webcontentsview">this blog post</a>.<!-- -->
<ul>
<li class=""><code>BrowserView</code> 现在是 <code>WebContentsView</code> 的一个壳，并且旧的实现已被移除。</li>
<li class="">查看 <a href="https://www.electronjs.org/docs/latest/tutorial/web-embeds" target="_blank" rel="noopener noreferrer" class="">我们的 Web Embeds 文档</a> 以便将新的 <code>WebContentsView</code> API 和其他类似 API进行比较。</li>
</ul>
</li>
<li class="">实现了对 <a href="https://developer.mozilla.org/en-US/docs/Web/API/File_System_API" target="_blank" rel="noopener noreferrer" class="">File System API</a> 的支持 (<a href="https://github.com/electron/electron/commit/cf1087badd437906f280373decb923733a8523e6" target="_blank" rel="noopener noreferrer" class="">#41827</a>)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="架构stack更新">架构（Stack）更新<a href="https://electronjs.org/zh/blog/electron-30-0#%E6%9E%B6%E6%9E%84stack%E6%9B%B4%E6%96%B0" class="hash-link" aria-label="链接到 架构（Stack）更新" title="链接到 架构（Stack）更新" translate="no">​</a></h2>
<ul>
<li class="">Chromium <code>124.0.6367.49</code>
<ul>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-124/" target="_blank" rel="noopener noreferrer" class="">Chrome 124</a> 和 <a href="https://developer.chrome.com/blog/new-in-devtools-124/" target="_blank" rel="noopener noreferrer" class="">DevTools 124</a> 中的新功能</li>
<li class=""><a href="https://developer.chrome.com/blog/new-in-chrome-123/" target="_blank" rel="noopener noreferrer" class="">Chrome 123</a> 和 <a href="https://developer.chrome.com/blog/new-in-devtools-123/" target="_blank" rel="noopener noreferrer" class="">DevTools 123</a> 中的新功能</li>
</ul>
</li>
<li class="">Node <code>20.11.1</code>
<ul>
<li class=""><a href="https://nodejs.org/en/blog/release/v20.11.1/" target="_blank" rel="noopener noreferrer" class="">Node 20.11.1 发布说明</a></li>
</ul>
</li>
<li class="">V8 <code>12.4</code></li>
</ul>
<p>Electron 30 将 Chromium 从 <code>122.0.6261.39</code> 升级到 <code>124.0.6367.49</code>, Node 从 <code>20.9.0</code> 升级到 <code>20.11.1</code> 以及 V8 从 <code>12.2</code> 升级到 <code>12.4</code>。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="新特性">新特性<a href="https://electronjs.org/zh/blog/electron-30-0#%E6%96%B0%E7%89%B9%E6%80%A7" class="hash-link" aria-label="链接到 新特性" title="链接到 新特性" translate="no">​</a></h2>
<ul>
<li class="">在 webviews 中添加了 <code>transparent</code> 网页偏好设置。 (<a href="https://github.com/electron/electron/pull/40301" target="_blank" rel="noopener noreferrer" class="">#40301</a>)</li>
<li class="">在 webContents API 上添加了一个新的实例属性 <code>navigationHistory</code>，配合 <code>navigationHistory.getEntryAtIndex</code> 方法，使应用能够检索浏览历史中任何导航条目的 URL 和标题。 (<a href="https://github.com/electron/electron/pull/41662" target="_blank" rel="noopener noreferrer" class="">#41662</a>)</li>
<li class="">新增了 <code>BrowserWindow.isOccluded()</code> 方法，允许应用检查窗口是否被遮挡。 (<a href="https://github.com/electron/electron/pull/38982" target="_blank" rel="noopener noreferrer" class="">#38982</a>)</li>
<li class="">为工具进程中 <code>net</code> 模块发出的请求添加了代理配置支持。 (<a href="https://github.com/electron/electron/pull/41417" target="_blank" rel="noopener noreferrer" class="">#41417</a>)</li>
<li class="">添加了对 <code>navigator.serial</code> 中的服务类ID请求的蓝牙端口的支持。 (<a href="https://github.com/electron/electron/pull/41734" target="_blank" rel="noopener noreferrer" class="">#41734</a>)</li>
<li class="">添加了对 Node.js <a href="https://nodejs.org/api/cli.html#node_extra_ca_certsfile" target="_blank" rel="noopener noreferrer" class=""><code>NODE_EXTRA_CA_CERTS</code></a> 命令行标志的支持。 (<a href="https://github.com/electron/electron/pull/41822" target="_blank" rel="noopener noreferrer" class="">#41822</a>)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="重大更改">重大更改<a href="https://electronjs.org/zh/blog/electron-30-0#%E9%87%8D%E5%A4%A7%E6%9B%B4%E6%94%B9" class="hash-link" aria-label="链接到 重大更改" title="链接到 重大更改" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="行为变更跨源-iframe-现在使用-permission-policy-来访问功能">行为变更：跨源 iframe 现在使用 Permission Policy 来访问功能。<a href="https://electronjs.org/zh/blog/electron-30-0#%E8%A1%8C%E4%B8%BA%E5%8F%98%E6%9B%B4%E8%B7%A8%E6%BA%90-iframe-%E7%8E%B0%E5%9C%A8%E4%BD%BF%E7%94%A8-permission-policy-%E6%9D%A5%E8%AE%BF%E9%97%AE%E5%8A%9F%E8%83%BD" class="hash-link" aria-label="链接到 行为变更：跨源 iframe 现在使用 Permission Policy ��来访问功能。" title="链接到 行为变更：跨源 iframe 现在使用 Permission Policy 来访问功能。" translate="no">​</a></h3>
<p>跨域 iframe 现在必须通过 <code>allow</code> 属性指定一个给定 <code>iframe</code> 可以访问的功能。</p>
<p>有关更多信息，请参见 <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#allow" target="_blank" rel="noopener noreferrer" class="">文档</a>。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="移除--disable-color-correct-rendering-命令行开关">移除：<code>--disable-color-correct-rendering</code> 命令行开关<a href="https://electronjs.org/zh/blog/electron-30-0#%E7%A7%BB%E9%99%A4--disable-color-correct-rendering-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%BC%80%E5%85%B3" class="hash-link" aria-label="链接到 移除--disable-color-correct-rendering-命令行开关" title="链接到 移除--disable-color-correct-rendering-命令行开关" translate="no">​</a></h3>
<p>此开关从未正式文档化，但无论如何这里都记录了它的移除。 Chromium 本身现在对颜色空间有更好的支持，因此不再需要该标志。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="行为变更browserviewsetautoresize-在-macos-上的行为">行为变更：<code>BrowserView.setAutoResize</code> 在 macOS 上的行为<a href="https://electronjs.org/zh/blog/electron-30-0#%E8%A1%8C%E4%B8%BA%E5%8F%98%E6%9B%B4browserviewsetautoresize-%E5%9C%A8-macos-%E4%B8%8A%E7%9A%84%E8%A1%8C%E4%B8%BA" class="hash-link" aria-label="链接到 行为变更browserviewsetautoresize-在-macos-上的行为" title="链接到 行为变更browserviewsetautoresize-在-macos-上的行为" translate="no">​</a></h3>
<p>在 Electron 30 中，BrowserView 现在是围绕新的 <a href="https://www.electronjs.org/docs/latest/api/web-contents-view" target="_blank" rel="noopener noreferrer" class="">WebContentsView</a> API 的包装器。</p>
<p>以前，<code>BrowserView</code> API 的 <code>setAutoResize</code> 功能在 macOS 上由 <a href="https://developer.apple.com/documentation/appkit/nsview/1483281-autoresizingmask?language=objc" target="_blank" rel="noopener noreferrer" class="">autoresizing</a> 支持，并且在 Windows 和 Linux 上由自定义算法支持。
对于简单的用例，比如使 BrowserView 填充整个窗口，在这两种方法的行为上是相同的。
然而，在更高级的情况下，BrowserViews 在 macOS 上的自动调整大小与在其他平台上的情况不同，因为 Windows 和 Linux 的自定义调整大小算法与 macOS 的自动调整大小 API 的行为并不完全匹配。
自动调整大小的行为现在在所有平台上都标准化了。</p>
<p>如果您的应用使用 <code>BrowserView.setAutoResize</code> 做的不仅仅是使 BrowserView 填满整个窗口，那么您可能已经有了自定义逻辑来处理 macOS 上的这种行为差异。
如果是这样，在 Electron 30 中不再需要这种逻辑，因为自动调整大小的行为是一致的。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="移除webcontents-上-context-menu-的-paramsinputformtype-属性">移除：<code>WebContents</code> 上 <code>context-menu</code> 的 <code>params.inputFormType</code> 属性<a href="https://electronjs.org/zh/blog/electron-30-0#%E7%A7%BB%E9%99%A4webcontents-%E4%B8%8A-context-menu-%E7%9A%84-paramsinputformtype-%E5%B1%9E%E6%80%A7" class="hash-link" aria-label="链接到 移除webcontents-上-context-menu-的-paramsinputformtype-属性" title="链接到 移除webcontents-上-context-menu-的-paramsinputformtype-属性" translate="no">​</a></h3>
<p><code>WebContents</code> 的 <code>context-menu</code> 事件中 params 对象的 <code>inputFormType</code> 属性已被移除。 请改用新的 <code>formControlType</code> 属性。</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="移除processgetiocounters">移除：<code>process.getIOCounters()</code><a href="https://electronjs.org/zh/blog/electron-30-0#%E7%A7%BB%E9%99%A4processgetiocounters" class="hash-link" aria-label="链接到 移除processgetiocounters" title="链接到 移除processgetiocounters" translate="no">​</a></h3>
<p>Chromium 已删除对这些信息的访问。</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="终止对-27xy-的支持">终止对 27.x.y 的支持<a href="https://electronjs.org/zh/blog/electron-30-0#%E7%BB%88%E6%AD%A2%E5%AF%B9-27xy-%E7%9A%84%E6%94%AF%E6%8C%81" class="hash-link" aria-label="链接到 终止对 27.x.y 的支持" title="链接到 终止对 27.x.y 的支持" translate="no">​</a></h2>
<p>根据项目的<a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines#version-support-policy" target="_blank" rel="noopener noreferrer" class="">支持政策</a>，Electron 27.x.y 已经达到了支持的终点。 我们鼓励开发者将应用程序升级到更新的 Electron 版本。</p>
<table><thead><tr><th>E30(24 年 4 月)</th><th>E31 (24 年 6 月)</th><th>E26（24 年 8月）</th></tr></thead><tbody><tr><td>30.x.y</td><td>31.x.y</td><td>32.x.y</td></tr><tr><td>29.x.y</td><td>30.x.y</td><td>31.x.y</td></tr><tr><td>28.x.y</td><td>29.x.y</td><td>30.x.y</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="接下来">接下来<a href="https://electronjs.org/zh/blog/electron-30-0#%E6%8E%A5%E4%B8%8B%E6%9D%A5" class="hash-link" aria-label="链接到 接下来" title="链接到 接下来" translate="no">​</a></h2>
<p>在短期内，您可以期待团队继续专注于跟上构成 Electron 的主要组件的开发，包括 Chromium、Node 和 V8。</p>
<p>您可以在此处找到 <a href="https://www.electronjs.org/docs/latest/tutorial/electron-timelines" target="_blank" rel="noopener noreferrer" class="">Electron 的公开时间表</a>。</p>
<p>有关这些和未来变化的更多信息可在<a href="https://github.com/electron/electron/blob/main/docs/breaking-changes.md" target="_blank" rel="noopener noreferrer" class="">计划的突破性变化</a>页面找到。</p>]]></content:encoded>
            <category>发行版</category>
        </item>
    </channel>
</rss>