Skip to main content

주요 변경 사항

이 섹션에서는 주요 변경 사항을 기록한다. 가능한 경우 JS 코드에 Deprecation Warning(사용 중단 경고)를 추가하며, 변경 사항 적용 전 최소 한 번의 메이저 버전 동안 경고를 제공한다. 자세한 내용은 Electron 버전 관리 문서를 참고한다.

주요 변경 사항 유형

이 문서는 주요 변경 사항을 다음과 같은 기준으로 분류한다:

  • API 변경: API가 수정되어 업데이트되지 않은 코드가 반드시 예외를 발생시키는 경우.
  • 동작 변경: Electron의 동작이 변경되었지만, 반드시 예외를 발생시키지는 않는 경우.
  • 기본값 변경: 이전 기본값에 의존하던 코드가 동작하지 않을 수 있지만, 반드시 예외를 발생시키지는 않음. 명시적으로 값을 지정하면 이전 동작을 복원할 수 있음.
  • 사용 중단: API가 사용 중단으로 표시됨. API는 계속 작동하지만, 사용 중단 경고를 표시하며 향후 릴리스에서 제거될 예정.
  • 제거: API나 기능이 제거되어 더 이상 Electron에서 지원되지 않음.

계획된 API 변경 사항 (35.0)

더 이상 사용되지 않음: WebContentsconsole-message 이벤트에서 level, message, line, sourceId 인자

WebContentsconsole-message 이벤트가 업데이트되어 Event 인자에 세부 정보를 제공한다.

// 더 이상 사용되지 않음
webContents.on('console-message', (event, level, message, line, sourceId) => {})

// 대체 방법:
webContents.on('console-message', ({ level, message, lineNumber, sourceId, frame }) => {})

또한, level은 이제 문자열로, 가능한 값은 info, warning, error, debug이다.

계획된 API 변경 사항 (34.0)

동작 변경: 윈도우에서 전체 화면 시 메뉴 바가 숨겨짐

이 변경으로 윈도우의 동작이 리눅스와 일치하게 된다. 이전 동작: 윈도우에서 전체 화면 시에도 메뉴 바가 여전히 보였다. 새로운 동작: 윈도우에서 전체 화면 시 메뉴 바가 숨겨진다.

수정 사항: 이 변경 사항은 이전에 Electron 33의 주요 변경 사항으로 소개되었으나, 실제로는 Electron 34에서 처음 적용되었다.

예정된 API 변경 사항 (33.0)

동작 변경: 프레임 프로퍼티가 분리된 WebFrameMain 인스턴스를 반환하거나 아무것도 반환하지 않을 수 있음

WebFrameMain 인스턴스에 접근하는 API는 frame.detachedtrue로 설정된 인스턴스를 반환하거나, null을 반환할 수 있다.

프레임이 다른 오리진으로 네비게이션을 수행할 때, 분리된 상태가 되어 더 이상 페이지에 연결되지 않는다. 이 상태에서 프레임은 삭제되기 전에 unload 핸들러를 실행할 수 있다. 이 상태에서 IPC가 전송되면 frame.detachedtrue로 설정되고, 곧 프레임이 파괴된다.

이벤트를 받았을 때, WebFrameMain 프로퍼티에 즉시 접근하는 것이 중요하다. 그렇지 않으면, 받았을 때와 동일한 웹페이지를 가리킨다는 보장이 없다. 잘못된 기대를 방지하기 위해, Electron은 웹페이지가 변경된 후 늦게 접근하는 경우 null을 반환한다.

ipcMain.on('unload-event', (event) => {
event.senderFrame; // ✅ 즉시 접근
});

ipcMain.on('unload-event', async (event) => {
await crossOriginNavigationPromise;
event.senderFrame; // ❌ 늦게 접근하여 `null` 반환
});

변경된 동작: Windows에서 커스텀 프로토콜 URL 처리

Chromium의 Non-Special Scheme URLs 지원을 위한 변경으로 인해, Windows 파일 경로를 사용하는 커스텀 프로토콜 URL은 더 이상 protocol.registerFileProtocolBrowserWindow.loadURL, WebContents.loadURL, <webview>.loadURLbaseURLForDataURL 속성과 함께 정상적으로 작동하지 않는다. protocol.handle도 이러한 유형의 URL과 함께 작동하지 않지만, 이는 새로운 변경 사항이 아니라 항상 그렇게 동작해 왔기 때문이다.

// 더 이상 작동하지 않음
protocol.registerFileProtocol('other', () => {
callback({ filePath: '/path/to/my/file' })
})

const mainWindow = new BrowserWindow()
mainWindow.loadURL('data:text/html,<script src="loaded-from-dataurl.js"></script>', { baseURLForDataURL: 'other://C:\\myapp' })
mainWindow.loadURL('other://C:\\myapp\\index.html')

// 대체 방법
const path = require('node:path')
const nodeUrl = require('node:url')
protocol.handle(other, (req) => {
const srcPath = 'C:\\myapp\\'
const reqURL = new URL(req.url)
return net.fetch(nodeUrl.pathToFileURL(path.join(srcPath, reqURL.pathname)).toString())
})

mainWindow.loadURL('data:text/html,<script src="loaded-from-dataurl.js"></script>', { baseURLForDataURL: 'other://' })
mainWindow.loadURL('other://index.html')

변경된 동작: applogin 이벤트에서 webContents 속성

respondToAuthRequestsFromMainProcess 옵션으로 생성된 유틸리티 프로세스에서 발생한 요청에 대해 applogin 이벤트가 트리거될 때, webContents 속성은 null이 된다.

더 이상 사용되지 않음: BrowserWindowConstructorOption.typetextured 옵션

BrowserWindowConstructorOptionstype에 있는 textured 옵션은 대체 기능 없이 더 이상 사용되지 않는다. 이 옵션은 macOS의 NSWindowStyleMaskTexturedBackground 스타일 마스크에 의존했는데, 이 마스크도 대체 기능 없이 더 이상 사용되지 않는다.

macOS 10.15(카탈리나)는 더 이상 Chromium에서 지원되지 않는다.

이전 버전의 Electron은 카탈리나에서 계속 실행되지만, Electron v33.0.0 이상을 실행하려면 macOS 11(빅서) 이상이 필요하다.

더 이상 사용되지 않음: systemPreferences.accessibilityDisplayShouldReduceTransparency

systemPreferences.accessibilityDisplayShouldReduceTransparency 속성은 이제 더 이상 사용되지 않는다. 대신 동일한 정보를 제공하며 크로스 플랫폼에서 작동하는 nativeTheme.prefersReducedTransparency를 사용해야 한다.

// 더 이상 사용되지 않음
const shouldReduceTransparency = systemPreferences.accessibilityDisplayShouldReduceTransparency

// 대체 코드:
const prefersReducedTransparency = nativeTheme.prefersReducedTransparency

예정된 API 변경 사항 (32.0)

제거됨: File.path

File 객체의 비표준 path 속성은 렌더러에서 모든 작업을 수행하는 것이 더 일반적이던 시절에 네이티브 파일을 다루기 편리하도록 Electron 초기 버전에서 추가되었다. 하지만 이 속성은 표준에서 벗어나며, 사소한 보안 위험도 내포하고 있다. 따라서 Electron 32.0부터는 이 속성을 제거하고, 대신 webUtils.getPathForFile 메서드를 사용하도록 변경했다.

// 이전 (렌더러)

const file = document.querySelector('input[type=file]').files[0]
alert(`업로드된 파일 경로: ${file.path}`)
// 이후 (렌더러)

const file = document.querySelector('input[type=file]').files[0]
electron.showFilePath(file)

// (프리로드)
const { contextBridge, webUtils } = require('electron')

contextBridge.exposeInMainWorld('electron', {
showFilePath (file) {
// 가능하다면 웹 콘텐츠에 전체 파일 경로를 노출하지 않는 것이 좋다.
const path = webUtils.getPathForFile(file)
alert(`업로드된 파일 경로: ${path}`)
}
})

더 이상 사용되지 않는 API: clearHistory, canGoBack, goBack, canGoForward, goForward, goToIndex, canGoToOffset, goToOffset on WebContents

네비게이션 관련 API는 이제 더 이상 사용되지 않는다.

이 API들은 네비게이션 기록을 관리하기 위해 더 구조적이고 직관적인 인터페이스를 제공하기 위해 WebContentsnavigationHistory 속성으로 이동했다.

// 더 이상 사용되지 않음
win.webContents.clearHistory()
win.webContents.canGoBack()
win.webContents.goBack()
win.webContents.canGoForward()
win.webContents.goForward()
win.webContents.goToIndex(index)
win.webContents.canGoToOffset()
win.webContents.goToOffset(index)

// 대체 방법
win.webContents.navigationHistory.clear()
win.webContents.navigationHistory.canGoBack()
win.webContents.navigationHistory.goBack()
win.webContents.navigationHistory.canGoForward()
win.webContents.navigationHistory.goForward()
win.webContents.navigationHistory.canGoToOffset()
win.webContents.navigationHistory.goToOffset(index)

예정된 주요 API 변경 사항 (31.0)

제거됨: WebSQL 지원

Chromium은 WebSQL 지원을 업스트림에서 제거하고 Android로만 이전했다. 자세한 내용은 Chromium의 제거 의도 논의를 참고한다.

동작 변경: nativeImage.toDataURL이 PNG 색상 공간을 보존

PNG 디코더 구현이 변경되어 색상 공간 데이터를 보존한다. 이제 이 함수에서 반환된 인코딩된 데이터는 원본과 일치한다.

자세한 내용은 crbug.com/332584706을 참고한다.

동작 변경: window.flashFrame(bool)은 이제 macOS에서 독 아이콘을 지속적으로 깜빡인다

이 변경으로 Windows와 Linux와의 동작이 일치하게 되었다. 기존 동작: 첫 번째 flashFrame(true) 호출 시 독 아이콘이 한 번만 튀어오르며(NSInformationalRequest 수준 사용), flashFrame(false)는 아무 동작도 하지 않았다. 새로운 동작: flashFrame(false)가 호출될 때까지 독 아이콘이 지속적으로 깜빡인다. 이제 NSCriticalRequest 수준을 사용한다. 독 아이콘을 한 번만 튀어오르게 하려면 여전히 dock.bounce('informational')을 사용할 수 있다.

예정된 주요 API 변경 사항 (30.0)

동작 변경: 크로스 오리진 iframe에서 기능 접근 시 Permission Policy 사용

이제 크로스 오리진 iframe은 특정 기능에 접근하기 위해 allow 속성을 통해 사용 가능한 기능을 명시해야 한다.

자세한 내용은 문서를 참고한다.

제거된 기능: --disable-color-correct-rendering 스위치

이 스위치는 공식적으로 문서화된 적은 없지만, 제거된 사항을 여기에 기록한다. 크로미엄 자체가 이제 더 나은 색 공간 지원을 제공하기 때문에 이 플래그는 더 이상 필요하지 않다.

변경된 동작: macOS에서 BrowserView.setAutoResize의 동작

Electron 30부터 BrowserView는 새로운 WebContentsView API를 기반으로 구현되었다.

이전에는 BrowserView API의 setAutoResize 함수가 macOS에서는 autoresizing을, Windows와 Linux에서는 커스텀 알고리즘을 사용했다. BrowserView가 전체 윈도우를 채우는 간단한 경우에는 두 방식의 동작이 동일했다. 그러나 더 복잡한 경우에는 Windows와 Linux의 커스텀 리사이징 알고리즘이 macOS의 autoresizing API와 완벽히 일치하지 않아, macOS에서 BrowserView의 autoresizing 동작이 다른 플랫폼과 달랐다. 이제 모든 플랫폼에서 autoresizing 동작이 표준화되었다.

만약 여러분의 앱이 BrowserView.setAutoResize를 사용해 BrowserView가 전체 윈도우를 채우는 것보다 더 복잡한 작업을 수행한다면, macOS에서의 동작 차이를 처리하기 위해 이미 커스텀 로직을 구현했을 가능성이 높다. 이 경우, Electron 30에서는 autoresizing 동작이 일관되게 유지되므로 해당 로직이 더 이상 필요하지 않다.

더 이상 사용되지 않음: BrowserView

BrowserView 클래스는 더 이상 사용되지 않으며, 새로운 WebContentsView 클래스로 대체되었다.

BrowserWindow 클래스에서 BrowserView와 관련된 메서드들도 더 이상 사용되지 않는다:

BrowserWindow.fromBrowserView(browserView)
win.setBrowserView(browserView)
win.getBrowserView()
win.addBrowserView(browserView)
win.removeBrowserView(browserView)
win.setTopBrowserView(browserView)
win.getBrowserViews()

WebContentscontext-menu 이벤트에서 params 객체의 inputFormType 프로퍼티가 제거되었다. 이제 새로운 formControlType 프로퍼티를 사용한다.

process.getIOCounters()가 제거되었다.

크로미움에서 이 정보에 대한 접근을 제거했다.

예정된 주요 API 변경 사항 (29.0)

동작 변경: ipcRenderercontextBridge를 통해 전달할 수 없음

contextBridge를 통해 ipcRenderer 모듈 전체를 객체로 전달하려고 하면, 이제 브리지의 수신 측에서 빈 객체를 받게 된다. 이 변경은 보안상의 위험 요소를 제거하거나 완화하기 위해 도입되었다. ipcRenderer나 그 메서드를 직접 브리지에 노출해서는 안 된다. 대신, 다음과 같이 안전한 래퍼를 제공하는 방식을 사용해야 한다:

contextBridge.exposeInMainWorld('app', {
onEvent: (cb) => ipcRenderer.on('foo', (e, ...args) => cb(args))
})

제거됨: apprenderer-process-crashed 이벤트

apprenderer-process-crashed 이벤트가 제거되었다. 이제 새로운 render-process-gone 이벤트를 사용해야 한다.

// 제거됨
app.on('renderer-process-crashed', (event, webContents, killed) => { /* ... */ })

// 대체 코드
app.on('render-process-gone', (event, webContents, details) => { /* ... */ })

제거됨: WebContents<webview>crashed 이벤트

WebContents<webview>crashed 이벤트가 제거되었다. 대신 새로운 render-process-gone 이벤트를 사용해야 한다.

// 제거됨
win.webContents.on('crashed', (event, killed) => { /* ... */ })
webview.addEventListener('crashed', (event) => { /* ... */ })

// 대체 코드
win.webContents.on('render-process-gone', (event, details) => { /* ... */ })
webview.addEventListener('render-process-gone', (event) => { /* ... */ })

제거됨: appgpu-process-crashed 이벤트

appgpu-process-crashed 이벤트가 제거되었다. 대신 새로운 child-process-gone 이벤트를 사용한다.

// 제거됨
app.on('gpu-process-crashed', (event, killed) => { /* ... */ })

// 대체 코드
app.on('child-process-gone', (event, details) => { /* ... */ })

예정된 주요 API 변경 사항 (28.0)

동작 변경: WebContents.backgroundThrottling을 false로 설정하면 호스트 BrowserWindow의 모든 WebContents에 영향을 미침

WebContents.backgroundThrottling을 false로 설정하면, 해당 BrowserWindow에 표시되는 모든 WebContents의 프레임 스로틀링이 비활성화된다.

제거됨: BrowserWindow.setTrafficLightPosition(position)

BrowserWindow.setTrafficLightPosition(position)은 제거되었다. 이제는 BrowserWindow.setWindowButtonPosition(position) API를 사용해야 한다. 이 API는 위치를 시스템 기본값으로 재설정하기 위해 { x: 0, y: 0 } 대신 null을 인자로 받는다.

// Electron 28에서 제거됨
win.setTrafficLightPosition({ x: 10, y: 10 })
win.setTrafficLightPosition({ x: 0, y: 0 })

// 대체 코드
win.setWindowButtonPosition({ x: 10, y: 10 })
win.setWindowButtonPosition(null)

제거됨: BrowserWindow.getTrafficLightPosition()

BrowserWindow.getTrafficLightPosition() 메서드가 제거되었다. 이제는 BrowserWindow.getWindowButtonPosition() API를 대신 사용해야 한다. 이 메서드는 커스텀 위치가 없을 때 { x: 0, y: 0 } 대신 null을 반환한다.

// Electron 28에서 제거됨
const pos = win.getTrafficLightPosition()
if (pos.x === 0 && pos.y === 0) {
// 커스텀 위치 없음.
}

// 대체 방법
const ret = win.getWindowButtonPosition()
if (ret === null) {
// 커스텀 위치 없음.
}

제거됨: ipcRenderer.sendTo()

ipcRenderer.sendTo() API가 제거되었다. 이 기능은 두 렌더러 사이에 MessageChannel을 설정하는 방식으로 대체해야 한다.

IpcRendererEventsenderIdsenderIsMainFrame 속성도 함께 제거되었다.

app.runningUnderRosettaTranslation 프로퍼티를 제거했다. 이제 app.runningUnderARM64Translation을 대신 사용한다.

// 제거됨
console.log(app.runningUnderRosettaTranslation)
// 대체 코드
console.log(app.runningUnderARM64Translation)

더 이상 사용되지 않음: apprenderer-process-crashed 이벤트

apprenderer-process-crashed 이벤트는 더 이상 사용되지 않는다. 대신 새로운 render-process-gone 이벤트를 사용한다.

// 더 이상 사용되지 않음
app.on('renderer-process-crashed', (event, webContents, killed) => { /* ... */ })

// 대체 코드
app.on('render-process-gone', (event, webContents, details) => { /* ... */ })

WebContentscontext-menu 이벤트에서 params 객체의 inputFormType 속성은 더 이상 사용되지 않는다. 이제 formControlType 속성을 사용해야 한다.

더 이상 사용되지 않음: WebContents<webview>crashed 이벤트

WebContents<webview>crashed 이벤트는 더 이상 사용되지 않는다. 대신 새로운 render-process-gone 이벤트를 사용한다.

// 더 이상 사용되지 않음
win.webContents.on('crashed', (event, killed) => { /* ... */ })
webview.addEventListener('crashed', (event) => { /* ... */ })

// 대체 코드
win.webContents.on('render-process-gone', (event, details) => { /* ... */ })
webview.addEventListener('render-process-gone', (event) => { /* ... */ })

더 이상 사용되지 않음: appgpu-process-crashed 이벤트

appgpu-process-crashed 이벤트는 더 이상 사용되지 않는다. 대신 새로운 child-process-gone 이벤트를 사용해야 한다.

// 더 이상 사용되지 않음
app.on('gpu-process-crashed', (event, killed) => { /* ... */ })

// 대체 코드
app.on('child-process-gone', (event, details) => { /* ... */ })

예정된 주요 API 변경 사항 (27.0)

제거됨: macOS 10.13 / 10.14 지원

macOS 10.13 (High Sierra)와 macOS 10.14 (Mojave)는 더 이상 Chromium에서 지원하지 않는다.

이전 버전의 Electron은 여전히 해당 운영체제에서 실행되지만, Electron v27.0.0 이상을 실행하려면 macOS 10.15 (Catalina) 이상이 필요하다.

더 이상 사용되지 않음: ipcRenderer.sendTo()

ipcRenderer.sendTo() API는 더 이상 사용되지 않는다. 이 기능은 두 렌더러 간에 MessageChannel을 설정하는 방식으로 대체해야 한다.

IpcRendererEventsenderIdsenderIsMainFrame 속성 또한 더 이상 사용되지 않는다.

제거됨: systemPreferences의 컬러 스킴 이벤트

다음 systemPreferences 이벤트가 제거되었다:

  • inverted-color-scheme-changed
  • high-contrast-color-scheme-changed

이제 nativeTheme 모듈의 updated 이벤트를 사용한다.

// 제거됨
systemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ })
systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })

// 대체 코드
nativeTheme.on('updated', () => { /* ... */ })

변경 사항: macOS에서 일부 window.setVibrancy 옵션 제거

다음의 비브랜시 옵션이 제거되었다:

  • 'light'
  • 'medium-light'
  • 'dark'
  • 'ultra-dark'
  • 'appearance-based'

이 옵션들은 이전에 더 이상 사용되지 않는 것으로 표시되었으며, Apple이 macOS 10.15에서 공식적으로 제거했다.

삭제됨: webContents.getPrinters

webContents.getPrinters 메서드가 제거되었다. 대신 webContents.getPrintersAsync를 사용한다.

const w = new BrowserWindow({ show: false })

// 삭제됨
console.log(w.webContents.getPrinters())
// 대체 코드
w.webContents.getPrintersAsync().then((printers) => {
console.log(printers)
})

systemPreferences.{get,set}AppLevelAppearancesystemPreferences.appLevelAppearance는 제거되었다. 이제 nativeTheme 모듈을 사용해야 한다.

// 제거됨
systemPreferences.getAppLevelAppearance()
// 대체 방법
nativeTheme.shouldUseDarkColors

// 제거됨
systemPreferences.appLevelAppearance
// 대체 방법
nativeTheme.shouldUseDarkColors

// 제거됨
systemPreferences.setAppLevelAppearance('dark')
// 대체 방법
nativeTheme.themeSource = 'dark'

제거됨: systemPreferences.getColoralternate-selected-control-text

systemPreferences.getColoralternate-selected-control-text 값이 제거되었다. 대신 selected-content-background를 사용한다.

// 제거됨
systemPreferences.getColor('alternate-selected-control-text')
// 대체 코드
systemPreferences.getColor('selected-content-background')

예정된 주요 API 변경 사항 (26.0)

더 이상 사용되지 않음: webContents.getPrinters

webContents.getPrinters 메서드는 더 이상 사용되지 않는다. 대신 webContents.getPrintersAsync를 사용한다.

const w = new BrowserWindow({ show: false })

// 더 이상 사용되지 않음
console.log(w.webContents.getPrinters())
// 대체 방법
w.webContents.getPrintersAsync().then((printers) => {
console.log(printers)
})

더 이상 사용되지 않는 기능: systemPreferences.{get,set}AppLevelAppearancesystemPreferences.appLevelAppearance

systemPreferences.getAppLevelAppearancesystemPreferences.setAppLevelAppearance 메서드, 그리고 systemPreferences.appLevelAppearance 프로퍼티는 더 이상 사용되지 않는다. 이제 nativeTheme 모듈을 사용해야 한다.

// 더 이상 사용되지 않음
systemPreferences.getAppLevelAppearance()
// 대체 코드
nativeTheme.shouldUseDarkColors

// 더 이상 사용되지 않음
systemPreferences.appLevelAppearance
// 대체 코드
nativeTheme.shouldUseDarkColors

// 더 이상 사용되지 않음
systemPreferences.setAppLevelAppearance('dark')
// 대체 코드
nativeTheme.themeSource = 'dark'

더 이상 사용되지 않음: systemPreferences.getColoralternate-selected-control-text

systemPreferences.getColor에서 사용하던 alternate-selected-control-text 값은 더 이상 사용되지 않는다. 대신 selected-content-background를 사용한다.

// 더 이상 사용되지 않음
systemPreferences.getColor('alternate-selected-control-text')
// 대체 코드
systemPreferences.getColor('selected-content-background')

예정된 API 변경 사항 (25.0)

폐기 예정: protocol.{un,}{register,intercept}{Buffer,String,Stream,File,Http}Protocolprotocol.isProtocol{Registered,Intercepted}

protocol.register*Protocolprotocol.intercept*Protocol 메서드는 protocol.handle로 대체되었다.

새로운 메서드는 새로운 프로토콜을 등록하거나 기존 프로토콜을 가로챌 수 있으며, 응답은 어떤 타입이든 가능하다.

// Electron 25에서 폐기 예정
protocol.registerBufferProtocol('some-protocol', () => {
callback({ mimeType: 'text/html', data: Buffer.from('<h5>Response</h5>') })
})

// 대체 코드
protocol.handle('some-protocol', () => {
return new Response(
Buffer.from('<h5>Response</h5>'), // 문자열이나 ReadableStream도 가능.
{ headers: { 'content-type': 'text/html' } }
)
})
// Electron 25에서 폐기 예정
protocol.registerHttpProtocol('some-protocol', () => {
callback({ url: 'https://electronjs.org' })
})

// 대체 코드
protocol.handle('some-protocol', () => {
return net.fetch('https://electronjs.org')
})
// Electron 25에서 폐기 예정
protocol.registerFileProtocol('some-protocol', () => {
callback({ filePath: '/path/to/my/file' })
})

// 대체 코드
protocol.handle('some-protocol', () => {
return net.fetch('file:///path/to/my/file')
})

더 이상 사용되지 않음: BrowserWindow.setTrafficLightPosition(position)

BrowserWindow.setTrafficLightPosition(position)은 더 이상 사용되지 않는다. 이제 BrowserWindow.setWindowButtonPosition(position) API를 대신 사용해야 한다. 이 새로운 API는 위치를 시스템 기본값으로 재설정하기 위해 { x: 0, y: 0 } 대신 null을 인자로 받는다.

// Electron 25에서 더 이상 사용되지 않음
win.setTrafficLightPosition({ x: 10, y: 10 })
win.setTrafficLightPosition({ x: 0, y: 0 })

// 대체 방법
win.setWindowButtonPosition({ x: 10, y: 10 })
win.setWindowButtonPosition(null)

더 이상 사용되지 않음: BrowserWindow.getTrafficLightPosition()

BrowserWindow.getTrafficLightPosition()은 더 이상 사용되지 않는다. 이제 BrowserWindow.getWindowButtonPosition() API를 대신 사용해야 한다. 이 새로운 API는 커스텀 위치가 없을 때 { x: 0, y: 0 } 대신 null을 반환한다.

// Electron 25에서 더 이상 사용되지 않음
const pos = win.getTrafficLightPosition()
if (pos.x === 0 && pos.y === 0) {
// 커스텀 위치가 없음.
}

// 대체 코드
const ret = win.getWindowButtonPosition()
if (ret === null) {
// 커스텀 위치가 없음.
}

예정된 주요 API 변경 사항 (24.0)

변경된 API: nativeImage.createThumbnailFromPath(path, size)

maxSize 매개변수가 size로 변경되었다. 이제 전달된 크기가 생성될 썸네일의 크기를 직접 반영한다. 이전에는 Windows에서 이미지가 maxSize보다 작을 경우 크기를 확대하지 않았고, macOS에서는 항상 크기를 maxSize로 설정했다. 이제는 모든 플랫폼에서 동일한 동작을 보인다.

새로운 동작:

// 128x128 크기의 이미지
const imagePath = path.join('path', 'to', 'capybara.png')

// 더 작은 이미지를 확대
const upSize = { width: 256, height: 256 }
nativeImage.createThumbnailFromPath(imagePath, upSize).then(result => {
console.log(result.getSize()) // { width: 256, height: 256 }
})

// 더 큰 이미지를 축소
const downSize = { width: 64, height: 64 }
nativeImage.createThumbnailFromPath(imagePath, downSize).then(result => {
console.log(result.getSize()) // { width: 64, height: 64 }
})

이전 동작 (Windows 기준):

// 128x128 크기의 이미지
const imagePath = path.join('path', 'to', 'capybara.png')
const size = { width: 256, height: 256 }
nativeImage.createThumbnailFromPath(imagePath, size).then(result => {
console.log(result.getSize()) // { width: 128, height: 128 }
})

예정된 주요 API 변경 사항 (23.0)

변경된 동작: macOS에서의 드래그 가능 영역

macOS에서 드래그 가능 영역(-webkit-app-region: drag CSS 속성 사용)의 구현이 Windows 및 Linux와 일관되도록 변경되었다. 이전에는 -webkit-app-region: no-drag 영역이 -webkit-app-region: drag 영역과 겹칠 경우, macOS에서는 CSS 레이어링과 관계없이 항상 no-drag 영역이 우선했다. 즉, drag 영역이 no-drag 영역 위에 있더라도 무시되었다. Electron 23부터는 drag 영역이 no-drag 영역 위에 있을 경우 해당 영역이 정상적으로 드래그 가능하게 된다.

또한, customButtonsOnHover BrowserWindow 속성은 이전에 -webkit-app-region CSS 속성을 무시하는 드래그 가능 영역을 생성했다. 이 문제가 이제 해결되었다 (관련 논의는 #37210 참조).

결과적으로, macOS에서 드래그 가능 영역을 사용하는 프레임리스 윈도우를 사용하는 앱의 경우, Electron 23에서 드래그 가능한 영역이 변경될 수 있다.

Windows 7, Windows 8, 그리고 Windows 8.1에 대한 지원이 중단되었다. Electron은 Chromium의 지원 중단 정책을 따르며, Chromium 109부터 Windows 7 지원을 중단할 예정이다.

이전 버전의 Electron은 해당 운영체제에서 계속 실행될 수 있지만, Electron v23.0.0 이상을 실행하려면 Windows 10 이상이 필요하다.

제거됨: BrowserWindow scroll-touch-* 이벤트

더 이상 사용되지 않는 BrowserWindow의 scroll-touch-begin, scroll-touch-end, scroll-touch-edge 이벤트가 제거되었다. 대신 WebContents에서 새로 제공되는 input-event 이벤트를 사용한다.

// Electron 23.0에서 제거됨
win.on('scroll-touch-begin', scrollTouchBegin)
win.on('scroll-touch-edge', scrollTouchEdge)
win.on('scroll-touch-end', scrollTouchEnd)

// 대체 코드
win.webContents.on('input-event', (_, event) => {
if (event.type === 'gestureScrollBegin') {
scrollTouchBegin()
} else if (event.type === 'gestureScrollUpdate') {
scrollTouchEdge()
} else if (event.type === 'gestureScrollEnd') {
scrollTouchEnd()
}
})

제거됨: webContents.incrementCapturerCount(stayHidden, stayAwake)

webContents.incrementCapturerCount(stayHidden, stayAwake) 함수가 제거되었다. 이제 페이지 캡처가 완료될 때 webContents.capturePage에 의해 자동으로 처리된다.

const w = new BrowserWindow({ show: false })

// Electron 23에서 제거됨
w.webContents.incrementCapturerCount()
w.capturePage().then(image => {
console.log(image.toDataURL())
w.webContents.decrementCapturerCount()
})

// 대체 코드
w.capturePage().then(image => {
console.log(image.toDataURL())
})

webContents.decrementCapturerCount(stayHidden, stayAwake) 함수가 제거되었다. 이제 페이지 캡처가 완료되면 webContents.capturePage가 자동으로 처리한다.

const w = new BrowserWindow({ show: false })

// Electron 23에서 제거됨
w.webContents.incrementCapturerCount()
w.capturePage().then(image => {
console.log(image.toDataURL())
w.webContents.decrementCapturerCount()
})

// 대체 코드
w.capturePage().then(image => {
console.log(image.toDataURL())
})

예정된 API 변경 사항 (22.0)

더 이상 사용되지 않음: webContents.incrementCapturerCount(stayHidden, stayAwake)

webContents.incrementCapturerCount(stayHidden, stayAwake)는 더 이상 사용되지 않는다. 이제 webContents.capturePage가 페이지 캡처 완료 시 자동으로 처리한다.

const w = new BrowserWindow({ show: false })

// Electron 23에서 제거됨
w.webContents.incrementCapturerCount()
w.capturePage().then(image => {
console.log(image.toDataURL())
w.webContents.decrementCapturerCount()
})

// 다음과 같이 대체
w.capturePage().then(image => {
console.log(image.toDataURL())
})

더 이상 사용되지 않음: webContents.decrementCapturerCount(stayHidden, stayAwake)

webContents.decrementCapturerCount(stayHidden, stayAwake)는 이제 더 이상 사용되지 않는다. 페이지 캡처가 완료되면 webContents.capturePage가 자동으로 이를 처리한다.

const w = new BrowserWindow({ show: false })

// Electron 23에서 제거됨
w.webContents.incrementCapturerCount()
w.capturePage().then(image => {
console.log(image.toDataURL())
w.webContents.decrementCapturerCount()
})

// 대체 방법
w.capturePage().then(image => {
console.log(image.toDataURL())
})

제거됨: WebContents의 new-window 이벤트

WebContents의 new-window 이벤트가 제거되었다. 이 이벤트는 webContents.setWindowOpenHandler()로 대체되었다.

// Electron 22에서 제거됨
webContents.on('new-window', (event) => {
event.preventDefault()
})

// 대체 코드
webContents.setWindowOpenHandler((details) => {
return { action: 'deny' }
})

제거됨: <webview>new-window 이벤트

<webview>new-window 이벤트가 제거되었다. 직접적인 대체 기능은 없다.

// Electron 22에서 제거됨
webview.addEventListener('new-window', (event) => {})
// 대체 방법

// main.js
mainWindow.webContents.on('did-attach-webview', (event, wc) => {
wc.setWindowOpenHandler((details) => {
mainWindow.webContents.send('webview-new-window', wc.id, details)
return { action: 'deny' }
})
})

// preload.js
const { ipcRenderer } = require('electron')
ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {
console.log('webview-new-window', webContentsId, details)
document.getElementById('webview').dispatchEvent(new Event('new-window'))
})

// renderer.js
document.getElementById('webview').addEventListener('new-window', () => {
console.log('got new-window event')
})

더 이상 사용되지 않음: BrowserWindow의 scroll-touch-* 이벤트

BrowserWindow의 scroll-touch-begin, scroll-touch-end, scroll-touch-edge 이벤트는 더 이상 사용되지 않는다. 대신 WebContents에서 제공하는 새로운 input-event 이벤트를 사용한다.

// 더 이상 사용되지 않음
win.on('scroll-touch-begin', scrollTouchBegin)
win.on('scroll-touch-edge', scrollTouchEdge)
win.on('scroll-touch-end', scrollTouchEnd)

// 대체 코드
win.webContents.on('input-event', (_, event) => {
if (event.type === 'gestureScrollBegin') {
scrollTouchBegin()
} else if (event.type === 'gestureScrollUpdate') {
scrollTouchEdge()
} else if (event.type === 'gestureScrollEnd') {
scrollTouchEnd()
}
})

예정된 주요 API 변경 사항 (21.0)

변경된 동작: V8 메모리 케이지 활성화

V8 메모리 케이지가 활성화되면서, ArrayBufferBuffer를 사용해 V8이 아닌 메모리를 감싸는 네이티브 모듈에 영향을 미친다. 자세한 내용은 V8 메모리 케이지 관련 블로그 포스트를 참고한다.

API 변경 사항: webContents.printToPDF()

webContents.printToPDF()는 Chrome DevTools Protocol의 Page.printToPDF에 맞춰 수정되었다. 이 변경은 기존 구현 방식이 더 이상 유지하기 어렵고 버그가 많았던 문제를 해결하기 위해 이루어졌다.

변경된 인자

  • pageRanges

제거된 인자

  • printSelectionOnly
  • marginsType
  • headerFooter
  • scaleFactor

추가된 인자

  • headerTemplate
  • footerTemplate
  • displayHeaderFooter
  • margins
  • scale
  • preferCSSPageSize
// 메인 프로세스
const { webContents } = require('electron')

webContents.printToPDF({
landscape: true,
displayHeaderFooter: true,
printBackground: true,
scale: 2,
pageSize: 'Ledger',
margins: {
top: 2,
bottom: 2,
left: 2,
right: 2
},
pageRanges: '1-5, 8, 11-13',
headerTemplate: '<h1>Title</h1>',
footerTemplate: '<div><span class="pageNumber"></span></div>',
preferCSSPageSize: true
}).then(data => {
fs.writeFile(pdfPath, data, (error) => {
if (error) throw error
console.log(`Wrote PDF successfully to ${pdfPath}`)
})
}).catch(error => {
console.log(`Failed to write PDF to ${pdfPath}: `, error)
})

예정된 주요 API 변경 사항 (20.0)

제거됨: macOS 10.11 / 10.12 지원

macOS 10.11 (El Capitan)과 macOS 10.12 (Sierra)는 더 이상 Chromium에서 지원하지 않는다.

이전 버전의 Electron은 여전히 해당 운영체제에서 실행되지만, Electron v20.0.0 이상을 실행하려면 macOS 10.13 (High Sierra) 이상이 필요하다.

기본값 변경: nodeIntegration: true가 없는 렌더러는 기본적으로 샌드박스 처리됨

이전에는 프리로드 스크립트(preload script)를 지정한 렌더러가 기본적으로 샌드박스 처리되지 않았다. 이는 기본적으로 프리로드 스크립트가 Node.js에 접근할 수 있음을 의미했다. Electron 20부터 이 기본값이 변경되었다. Electron 20부터는 nodeIntegration: true 또는 sandbox: false를 명시적으로 지정하지 않는 한, 렌더러는 기본적으로 샌드박스 처리된다.

만약 프리로드 스크립트가 Node.js에 의존하지 않는다면, 별도의 조치가 필요 없다. 하지만 프리로드 스크립트가 Node.js에 의존한다면, 렌더러에서 Node.js 사용을 제거하도록 리팩토링하거나, 해당 렌더러에 대해 sandbox: false를 명시적으로 지정해야 한다.

Linux에서 skipTaskbar 제거됨

X11 환경에서 skipTaskbar는 X11 윈도우 매니저에 _NET_WM_STATE_SKIP_TASKBAR 메시지를 보낸다. 하지만 Wayland에서는 이에 직접 대응하는 기능이 없으며, 알려진 해결 방법들은 받아들일 수 없는 단점을 가지고 있다(예: GNOME의 Window.is_skip_taskbar는 안전하지 않은 모드가 필요함). 따라서 Electron은 Linux에서 이 기능을 지원할 수 없다.

API 변경: session.setDevicePermissionHandler(handler)

session.setDevicePermissionHandler(handler)를 사용할 때 호출되는 핸들러의 인자가 변경되었다. 이 핸들러는 더 이상 WebFrameMain 프레임을 전달받지 않으며, 대신 디바이스 권한을 확인하는 origin을 전달받는다.

예정된 주요 API 변경 사항 (19.0)

제거: IA32 Linux 바이너리

이 변경은 Chromium 102.0.4999.0이 IA32 Linux 지원을 중단한 결과로 이루어졌다. 이로써 IA32 Linux 지원 중단이 완료되었다.

예정된 주요 API 변경 사항 (18.0)

제거됨: nativeWindowOpen

Electron 15 이전에는 기본적으로 window.openBrowserWindowProxy를 사용하도록 구현되었다. 이로 인해 window.open('about:blank')과 같은 코드가 동기적으로 스크립트 가능한 자식 윈도우를 열지 못하는 등 여러 호환성 문제가 발생했다. Electron 15부터는 nativeWindowOpen이 기본적으로 활성화되었다.

자세한 내용은 Electron의 window.open 문서를 참고한다.

예정된 주요 API 변경 사항 (17.0)

제거됨: 렌더러 프로세스에서의 desktopCapturer.getSources

desktopCapturer.getSources API는 이제 메인 프로세스에서만 사용할 수 있다. 이 변경은 Electron 애플리케이션의 기본 보안을 강화하기 위해 이루어졌다.

이 기능이 필요하다면 다음과 같이 대체할 수 있다:

// 메인 프로세스
const { ipcMain, desktopCapturer } = require('electron')

ipcMain.handle(
'DESKTOP_CAPTURER_GET_SOURCES',
(event, opts) => desktopCapturer.getSources(opts)
)
// 렌더러 프로세스
const { ipcRenderer } = require('electron')

const desktopCapturer = {
getSources: (opts) => ipcRenderer.invoke('DESKTOP_CAPTURER_GET_SOURCES', opts)
}

하지만 렌더러로 반환되는 정보를 추가로 제한하는 것을 고려해야 한다. 예를 들어, 사용자에게 소스 선택기를 표시하고 선택된 소스만 반환하는 방식이 있다.

더 이상 사용되지 않음: nativeWindowOpen

Electron 15 이전에는 window.open이 기본적으로 BrowserWindowProxy를 사용하도록 구현되었다. 이로 인해 window.open('about:blank')과 같은 코드가 동기적으로 스크립트 가능한 자식 윈도우를 열지 못하는 등 여러 호환성 문제가 발생했다. Electron 15부터는 nativeWindowOpen이 기본적으로 활성화되었다.

자세한 내용은 Electron에서의 window.open 문서를 참고한다.

예정된 API 변경 사항 (16.0)

동작 변경: Linux에서 crashReporter 구현이 Crashpad로 전환됨

Linux에서 crashReporter API의 내부 구현이 Breakpad에서 Crashpad로 변경되었다. 이로 인해 Windows와 Mac과 동일한 방식으로 동작하게 되었다. 이 변경으로 인해 자식 프로세스가 자동으로 모니터링되며, Node 자식 프로세스에서 process.crashReporter.start를 호출할 필요가 없어졌다(오히려 Crashpad 리포터의 두 번째 인스턴스가 시작되므로 권장하지 않는다).

또한 Linux에서 어노테이션이 보고되는 방식에 몇 가지 미묘한 변경 사항이 있다. 긴 값은 더 이상 __1, __2 등으로 분할되지 않고, 대신 (새롭고 더 긴) 어노테이션 값 제한에서 잘리게 된다.

더 이상 사용되지 않음: 렌더러에서의 desktopCapturer.getSources

렌더러에서 desktopCapturer.getSources API를 사용하는 방식은 더 이상 권장되지 않으며, 앞으로 제거될 예정이다. 이 변경은 Electron 앱의 기본 보안을 강화하기 위해 이루어진 것이다.

앱에서 이 API를 대체하는 방법에 대한 자세한 내용은 여기를 참고한다.

예정된 주요 API 변경 사항 (15.0)

기본값 변경: nativeWindowOpen이 기본적으로 true로 설정됨

Electron 15 이전에는 window.open이 기본적으로 BrowserWindowProxy를 사용하도록 구현되어 있었다. 이로 인해 window.open('about:blank')과 같은 코드가 동기적으로 스크립트 가능한 자식 윈도우를 열지 못하는 등 여러 호환성 문제가 발생했다. 이제 nativeWindowOpen은 더 이상 실험적 기능이 아니며, 기본값으로 설정되었다.

자세한 내용은 Electron의 window.open 문서를 참고한다.

더 이상 사용되지 않음: app.runningUnderRosettaTranslation

app.runningUnderRosettaTranslation 프로퍼티는 더 이상 사용되지 않는다. 대신 app.runningUnderARM64Translation을 사용한다.

// 더 이상 사용되지 않음
console.log(app.runningUnderRosettaTranslation)
// 대체 코드
console.log(app.runningUnderARM64Translation)

API 변경 계획 (14.0)

제거됨: remote 모듈

remote 모듈은 Electron 12에서 deprecated(사용 중단) 처리되었으며, Electron 14에서 완전히 제거된다. 이 모듈은 @electron/remote 모듈로 대체된다.

// Electron 12에서 deprecated 처리됨:
const { BrowserWindow } = require('electron').remote
// 다음과 같이 대체:
const { BrowserWindow } = require('@electron/remote')

// 메인 프로세스에서:
require('@electron/remote/main').initialize()

삭제된 기능: app.allowRendererProcessReuse

app.allowRendererProcessReuse 속성은 보안, 성능 및 유지보수성을 위해 Chromium의 프로세스 모델과 더 긴밀하게 통합하려는 계획의 일환으로 제거되었다.

자세한 내용은 #18397을 참고한다.

제거됨: 브라우저 윈도우 연결성(affinity)

보안, 성능, 유지보수성을 위해 Chromium의 프로세스 모델과 더욱 긴밀하게 통합하려는 계획의 일환으로, 새로운 BrowserWindow를 생성할 때 사용하던 affinity 옵션이 제거된다.

자세한 내용은 #18397을 참고한다.

변경된 API: window.open()

선택적 인자 frameName은 더 이상 윈도우의 제목을 설정하지 않는다. 이제는 공식 문서에서 설명한 windowName 인자에 대한 명세를 따른다.

이 인자를 사용해 윈도우 제목을 설정하던 경우, 대신 win.setTitle(title)을 사용할 수 있다.

Electron 14에서는 worldSafeExecuteJavaScript가 제거된다. 이에 대한 대체 기능은 없으므로, 해당 속성이 활성화된 상태에서 코드가 정상적으로 동작하는지 확인해야 한다. 이 속성은 Electron 12부터 기본적으로 활성화되어 있다.

webFrame.executeJavaScript 또는 webFrame.executeJavaScriptInIsolatedWorld를 사용한다면 이 변경의 영향을 받는다. 이 메서드들이 반환하는 값이 Context Bridge API에서 지원되는지 확인해야 한다. 이 메서드들은 동일한 값 전달 방식을 사용하기 때문이다.

Electron 14 이전에는 window.open으로 열린 윈도우가 부모 윈도우로부터 transparentresizable 같은 BrowserWindow 생성자 옵션을 상속받았다. 하지만 Electron 14부터 이 동작은 제거되었고, 윈도우는 더 이상 부모로부터 BrowserWindow 생성자 옵션을 상속받지 않는다.

대신, setWindowOpenHandler를 사용해 새 윈도우의 옵션을 명시적으로 설정해야 한다:

webContents.setWindowOpenHandler((details) => {
return {
action: 'allow',
overrideBrowserWindowOptions: {
// ...
}
}
})

삭제됨: additionalFeatures

WebContents의 new-windowdid-create-window 이벤트에서 사용되던 additionalFeatures 속성이 제거되었다. new-window는 위치 기반 인자를 사용하기 때문에 해당 인자는 여전히 존재하지만, 항상 빈 배열 []로 표시된다. (단, new-window 이벤트 자체도 더 이상 사용되지 않으며, setWindowOpenHandler로 대체되었다.) 윈도우 기능에서 단순 키는 이제 옵션 객체에서 값이 true인 키로 표시된다.

// Electron 14에서 제거됨
// window.open('...', '', 'my-key')에 의해 트리거됨
webContents.on('did-create-window', (window, details) => {
if (details.additionalFeatures.includes('my-key')) {
// ...
}
})

// 대체 방법
webContents.on('did-create-window', (window, details) => {
if (details.options['my-key']) {
// ...
}
})

예정된 주요 API 변경 사항 (13.0)

변경된 API: session.setPermissionCheckHandler(handler)

handler 메서드의 첫 번째 매개변수는 이전에는 항상 webContents였지만, 이제는 경우에 따라 null이 될 수 있다. 따라서 권한 확인에 대한 응답을 올바르게 처리하려면 requestingOrigin, embeddingOrigin, securityOrigin 속성을 사용해야 한다. webContentsnull일 수 있기 때문에 더 이상 이 값에 의존할 수 없다.

// 기존 코드
session.setPermissionCheckHandler((webContents, permission) => {
if (webContents.getURL().startsWith('https://google.com/') && permission === 'notification') {
return true
}
return false
})

// 변경된 코드
session.setPermissionCheckHandler((webContents, permission, requestingOrigin) => {
if (new URL(requestingOrigin).hostname === 'google.com' && permission === 'notification') {
return true
}
return false
})

제거됨: shell.moveItemToTrash()

더 이상 사용되지 않는 동기 방식의 shell.moveItemToTrash() API가 제거되었다. 대신 비동기 방식의 shell.trashItem()을 사용한다.

// Electron 13에서 제거됨
shell.moveItemToTrash(path)
// 대체 코드
shell.trashItem(path).then(/* ... */)

제거됨: BrowserWindow 확장 API

더 이상 사용되지 않는 확장 API가 제거되었다:

  • BrowserWindow.addExtension(path)
  • BrowserWindow.addDevToolsExtension(path)
  • BrowserWindow.removeExtension(name)
  • BrowserWindow.removeDevToolsExtension(name)
  • BrowserWindow.getExtensions()
  • BrowserWindow.getDevToolsExtensions()

대신 세션 API를 사용한다:

  • ses.loadExtension(path)
  • ses.removeExtension(extension_id)
  • ses.getAllExtensions()
// Electron 13에서 제거됨
BrowserWindow.addExtension(path)
BrowserWindow.addDevToolsExtension(path)
// 대체 방법
session.defaultSession.loadExtension(path)
// Electron 13에서 제거됨
BrowserWindow.removeExtension(name)
BrowserWindow.removeDevToolsExtension(name)
// 대체 방법
session.defaultSession.removeExtension(extension_id)
// Electron 13에서 제거됨
BrowserWindow.getExtensions()
BrowserWindow.getDevToolsExtensions()
// 대체 방법
session.defaultSession.getAllExtensions()

제거됨: systemPreferences의 메서드

다음 systemPreferences 메서드는 더 이상 사용되지 않는다:

  • systemPreferences.isDarkMode()
  • systemPreferences.isInvertedColorScheme()
  • systemPreferences.isHighContrastColorScheme()

대신 다음 nativeTheme 속성을 사용한다:

  • nativeTheme.shouldUseDarkColors
  • nativeTheme.shouldUseInvertedColorScheme
  • nativeTheme.shouldUseHighContrastColors
// Electron 13에서 제거됨
systemPreferences.isDarkMode()
// 대체할 코드
nativeTheme.shouldUseDarkColors

// Electron 13에서 제거됨
systemPreferences.isInvertedColorScheme()
// 대체할 코드
nativeTheme.shouldUseInvertedColorScheme

// Electron 13에서 제거됨
systemPreferences.isHighContrastColorScheme()
// 대체할 코드
nativeTheme.shouldUseHighContrastColors

폐기 예정: WebContents new-window 이벤트

WebContents의 new-window 이벤트는 더 이상 사용되지 않는다. 이제는 webContents.setWindowOpenHandler()로 대체되었다.

// Electron 13에서 폐기 예정
webContents.on('new-window', (event) => {
event.preventDefault()
})

// 대체 코드
webContents.setWindowOpenHandler((details) => {
return { action: 'deny' }
})

계획된 주요 API 변경 사항 (12.0)

제거: Pepper Flash 지원

Chromium이 Flash 지원을 중단했기 때문에, 우리도 이를 따라야 한다. 자세한 내용은 Chromium의 Flash 로드맵을 참고한다.

기본값 변경: worldSafeExecuteJavaScript의 기본값이 true로 설정됨

Electron 12부터 worldSafeExecuteJavaScript는 기본적으로 활성화된다. 이전 동작을 유지하려면 WebPreferences에서 worldSafeExecuteJavaScript: false를 명시적으로 설정해야 한다. 다만, 이 옵션을 false로 설정하는 것은 보안상 위험하므로 주의가 필요하다.

이 옵션은 Electron 14에서 제거될 예정이므로, 코드를 기본값을 지원하도록 마이그레이션해야 한다.

Electron 12부터 contextIsolation이 기본적으로 활성화된다. 이전 동작을 유지하려면 WebPreferences에서 contextIsolation: false를 명시해야 한다.

애플리케이션 보안을 위해 contextIsolation 활성화를 권장한다.

또한 nodeIntegrationtrue이고 contextIsolationfalse인 경우에만 렌더러 프로세스에서 require()를 사용할 수 있다.

자세한 내용은 다음 링크를 참고한다: https://github.com/electron/electron/issues/23506

제거됨: crashReporter.getCrashesDirectory()

crashReporter.getCrashesDirectory 메서드가 제거되었다. 이 메서드 대신 app.getPath('crashDumps')를 사용해야 한다.

// Electron 12에서 제거됨
crashReporter.getCrashesDirectory()
// 대체 코드
app.getPath('crashDumps')

렌더러 프로세스에서 더 이상 사용할 수 없는 crashReporter 메서드가 다음과 같이 제거되었다:

  • crashReporter.start
  • crashReporter.getLastCrashReport
  • crashReporter.getUploadedReports
  • crashReporter.getUploadToServer
  • crashReporter.setUploadToServer
  • crashReporter.getCrashesDirectory

이 메서드들은 이제 메인 프로세스에서만 호출해야 한다.

자세한 내용은 #23265를 참고한다.

crashReporter.start({ compress: true })의 기본값이 변경되었다.

이제 compress 옵션의 기본값이 false에서 true로 바뀌었다. 이 변경으로 인해 크래시 덤프가 Content-Encoding: gzip 헤더와 함께 압축된 상태로 크래시 수집 서버에 업로드된다.

크래시 수집 서버가 압축된 데이터를 지원하지 않는다면, crashReporter 옵션에 { compress: false }를 지정해 압축을 끌 수 있다.

더 이상 사용되지 않음: remote 모듈

remote 모듈은 Electron 12에서 더 이상 사용되지 않으며, Electron 14에서는 완전히 제거될 예정이다. 이 모듈은 @electron/remote 모듈로 대체되었다.

// Electron 12에서 더 이상 사용되지 않음:
const { BrowserWindow } = require('electron').remote
// 대체 코드:
const { BrowserWindow } = require('@electron/remote')

// 메인 프로세스에서:
require('@electron/remote/main').initialize()

더 이상 사용되지 않음: shell.moveItemToTrash()

동기 방식의 shell.moveItemToTrash()는 새로운 비동기 방식의 shell.trashItem()로 대체되었다.

// Electron 12에서 더 이상 사용되지 않음
shell.moveItemToTrash(path)
// 대체 방법
shell.trashItem(path).then(/* ... */)

예정된 주요 API 변경 사항 (11.0)

제거됨: BrowserView.{destroy, fromId, fromWebContents, getAllViews}BrowserViewid 속성

실험적 API였던 BrowserView.{destroy, fromId, fromWebContents, getAllViews}가 이제 제거되었다. 또한, BrowserViewid 속성도 함께 제거되었다.

자세한 내용은 #23578을 참고한다.

예정된 주요 API 변경 사항 (10.0)

더 이상 사용되지 않음: crashReporter.start()companyName 인자

이전에는 필수였던 crashReporter.start()companyName 인자가 이제 선택 사항이 되었고, 더 이상 사용하지 않는 것으로 표시되었다. 이와 동일한 동작을 유지하려면 globalExtracompanyName 값을 전달하면 된다.

// Electron 10에서 더 이상 사용되지 않음
crashReporter.start({ companyName: 'Umbrella Corporation' })
// 대체 방법
crashReporter.start({ globalExtra: { _companyName: 'Umbrella Corporation' } })

더 이상 사용되지 않음: crashReporter.getCrashesDirectory()

crashReporter.getCrashesDirectory 메서드는 더 이상 사용되지 않는다. 이제 app.getPath('crashDumps')를 사용해야 한다.

// Electron 10에서 더 이상 사용되지 않음
crashReporter.getCrashesDirectory()
// 대체 방법
app.getPath('crashDumps')

렌더러 프로세스에서 다음과 같은 crashReporter 메서드를 호출하는 것은 더 이상 사용되지 않는다:

  • crashReporter.start
  • crashReporter.getLastCrashReport
  • crashReporter.getUploadedReports
  • crashReporter.getUploadToServer
  • crashReporter.setUploadToServer
  • crashReporter.getCrashesDirectory

렌더러에서 사용 가능한 crashReporter 모듈의 메서드는 addExtraParameter, removeExtraParameter, getParameters만 남았다.

메인 프로세스에서 호출할 때는 위의 모든 메서드가 여전히 사용 가능하다.

자세한 내용은 #23265를 참고한다.

crashReporter.start({ compress: false })는 더 이상 사용하지 않는 기능이다. 대부분의 크래시 수집 서버가 gzip 압축을 지원하기 때문이다. 이 옵션은 향후 Electron 버전에서 제거될 예정이다.

기본값 변경: enableRemoteModule이 기본적으로 false로 설정됨

Electron 9에서는 enableRemoteModule WebPreferences 옵션을 명시적으로 활성화하지 않고 remote 모듈을 사용할 경우 경고 메시지가 표시되기 시작했다. Electron 10부터는 remote 모듈이 기본적으로 비활성화된다. remote 모듈을 사용하려면 WebPreferences에서 enableRemoteModule: true를 명시해야 한다:

const w = new BrowserWindow({
webPreferences: {
enableRemoteModule: true
}
})

우리는 remote 모듈 사용을 지양할 것을 권장한다.

protocol.unregisterProtocol

protocol.uninterceptProtocol

이제 API가 동기 방식으로 변경되었으며, 옵셔널 콜백은 더 이상 필요하지 않다.

// Deprecated
protocol.unregisterProtocol(scheme, () => { /* ... */ })
// Replace with
protocol.unregisterProtocol(scheme)

protocol.registerFileProtocol

protocol.registerBufferProtocol

protocol.registerStringProtocol

protocol.registerHttpProtocol

protocol.registerStreamProtocol

protocol.interceptFileProtocol

protocol.interceptStringProtocol

protocol.interceptBufferProtocol

protocol.interceptHttpProtocol

protocol.interceptStreamProtocol

이제 API는 동기 방식으로 동작하며, 더 이상 선택적 콜백이 필요하지 않다.

// 이전 방식 (더 이상 사용되지 않음)
protocol.registerFileProtocol(scheme, handler, () => { /* ... */ })
// 새로운 방식으로 대체
protocol.registerFileProtocol(scheme, handler)

등록하거나 가로챈 프로토콜은 네비게이션이 발생할 때까지 현재 페이지에 영향을 미치지 않는다.

protocol.isProtocolHandled

이 API는 더 이상 사용되지 않으며, 대신 protocol.isProtocolRegisteredprotocol.isProtocolIntercepted를 사용해야 한다.

// 더 이상 사용되지 않음
protocol.isProtocolHandled(scheme).then(() => { /* ... */ })
// 대체 코드
const isRegistered = protocol.isProtocolRegistered(scheme)
const isIntercepted = protocol.isProtocolIntercepted(scheme)

계획된 API 변경 사항 (9.0)

기본값 변경: 렌더러 프로세스에서 컨텍스트 인식이 없는 네이티브 모듈 로딩이 기본적으로 비활성화됨

Electron 9부터는 렌더러 프로세스에서 컨텍스트 인식이 없는 네이티브 모듈을 로드하지 않는다. 이 변경은 Electron 프로젝트의 보안, 성능, 유지보수성을 개선하기 위해 도입되었다.

이 변경으로 인해 문제가 발생한다면, app.allowRendererProcessReusefalse로 설정해 이전 동작으로 되돌릴 수 있다. 하지만 이 플래그는 Electron 11까지만 유효하므로, 네이티브 모듈을 컨텍스트 인식으로 업데이트할 계획을 세워야 한다.

자세한 내용은 #18397을 참고한다.

더 이상 사용되지 않는 BrowserWindow 확장 API

다음 확장 API는 더 이상 사용되지 않는다:

  • BrowserWindow.addExtension(path)
  • BrowserWindow.addDevToolsExtension(path)
  • BrowserWindow.removeExtension(name)
  • BrowserWindow.removeDevToolsExtension(name)
  • BrowserWindow.getExtensions()
  • BrowserWindow.getDevToolsExtensions()

대신 세션 API를 사용한다:

  • ses.loadExtension(path)
  • ses.removeExtension(extension_id)
  • ses.getAllExtensions()
// Electron 9에서 더 이상 사용되지 않음
BrowserWindow.addExtension(path)
BrowserWindow.addDevToolsExtension(path)
// 대신 다음을 사용
session.defaultSession.loadExtension(path)
// Electron 9에서 더 이상 사용되지 않음
BrowserWindow.removeExtension(name)
BrowserWindow.removeDevToolsExtension(name)
// 대신 다음을 사용
session.defaultSession.removeExtension(extension_id)
// Electron 9에서 더 이상 사용되지 않음
BrowserWindow.getExtensions()
BrowserWindow.getDevToolsExtensions()
// 대신 다음을 사용
session.defaultSession.getAllExtensions()

제거됨: <webview>.getWebContents()

Electron 8.0에서 더 이상 사용되지 않던 이 API는 이제 완전히 제거되었다.

// Electron 9.0에서 제거됨
webview.getWebContents()
// 대체 방법
const { remote } = require('electron')
remote.webContents.fromId(webview.getWebContentsId())

Chromium에서 레이아웃 줌 레벨 제한을 변경하는 기능을 제거했으며, Electron이 이를 유지할 수 있는 능력이 없다. 이 함수는 Electron 8.x에서 더 이상 사용되지 않았고, Electron 9.x에서 완전히 제거되었다. 레이아웃 줌 레벨 제한은 이제 최소 0.25, 최대 5.0으로 고정되었다. 이는 여기에 정의된 대로 적용된다.

동작 변경: IPC를 통해 비 JS 객체 전송 시 예외 발생

Electron 8.0에서 IPC는 Structured Clone Algorithm을 사용하도록 변경되어 성능이 크게 개선되었다. 전환을 원활하게 하기 위해, Structured Clone으로 직렬화할 수 없는 일부 객체에 대해 이전의 IPC 직렬화 알고리즘을 유지했다. 특히, DOM 객체(예: Element, Location, DOMMatrix), C++ 클래스로 지원되는 Node.js 객체(예: process.env, Stream의 일부 멤버), 그리고 C++ 클래스로 지원되는 Electron 객체(예: WebContents, BrowserWindow, WebFrame)는 Structured Clone으로 직렬화할 수 없다. 이전 알고리즘이 호출될 때마다 사용 중단 경고가 출력되었다.

Electron 9.0에서는 이전 직렬화 알고리즘이 제거되었고, 이제 직렬화할 수 없는 객체를 전송하면 "객체를 복제할 수 없음" 오류가 발생한다.

API 변경: shell.openItemshell.openPath로 변경됨

shell.openItem API가 비동기 방식의 shell.openPath API로 대체되었다. 원본 API 제안과 변경 이유는 여기에서 확인할 수 있다.

계획된 API 변경 사항 (8.0)

동작 변경: IPC를 통해 전송되는 값이 Structured Clone Algorithm으로 직렬화됨

IPC(ipcRenderer.send, ipcRenderer.sendSync, WebContents.send 및 관련 메서드)를 통해 전송되는 객체를 직렬화하는 알고리즘이 커스텀 알고리즘에서 V8의 내장 Structured Clone Algorithm로 변경되었다. 이 알고리즘은 postMessage에서 메시지를 직렬화하는 데 사용되는 것과 동일하다. 이로 인해 대용량 메시지의 성능이 2배 향상되었지만, 몇 가지 주요한 동작 변경도 발생했다.

  • 함수, Promise, WeakMap, WeakSet 또는 이와 같은 값을 포함하는 객체를 IPC로 전송할 경우, 이전처럼 함수를 undefined로 변환하지 않고 예외를 발생시킨다.
// 이전:
ipcRenderer.send('channel', { value: 3, someFunction: () => {} })
// => 메인 프로세스에서 { value: 3 }이 도착함

// Electron 8부터:
ipcRenderer.send('channel', { value: 3, someFunction: () => {} })
// => Error("() => {} could not be cloned.") 예외 발생
  • NaN, Infinity, -Infinity는 이제 null로 변환되지 않고 정확히 직렬화된다.
  • 순환 참조를 포함하는 객체는 이제 null로 변환되지 않고 정확히 직렬화된다.
  • Set, Map, Error, RegExp 값은 이제 {}로 변환되지 않고 정확히 직렬화된다.
  • BigInt 값은 이제 null로 변환되지 않고 정확히 직렬화된다.
  • 희소 배열은 null로 채워진 밀집 배열로 변환되지 않고 그대로 직렬화된다.
  • Date 객체는 ISO 문자열 표현으로 변환되지 않고 Date 객체로 전송된다.
  • Uint8Array, Uint16Array, Uint32Array와 같은 타입 배열은 Node.js Buffer로 변환되지 않고 그대로 전송된다.
  • Node.js Buffer 객체는 Uint8Array로 전송된다. Uint8Array를 다시 Node.js Buffer로 변환하려면 다음과 같이 ArrayBuffer를 감싸면 된다:
Buffer.from(value.buffer, value.byteOffset, value.byteLength)

DOM 객체(예: Element, Location, DOMMatrix), Node.js 객체(예: process.env, Stream), 또는 Electron 객체(예: WebContents, BrowserWindow, WebFrame)와 같은 네이티브 JS 타입이 아닌 객체를 전송하는 것은 더 이상 권장되지 않는다. Electron 8에서는 이러한 객체를 이전과 동일하게 직렬화하되 DeprecationWarning 메시지를 표시하지만, Electron 9부터는 이러한 객체를 전송할 경우 'could not be cloned' 오류가 발생한다.

더 이상 사용되지 않음: <webview>.getWebContents()

이 API는 remote 모듈을 사용해 구현됐다. remote 모듈은 성능과 보안 측면에서 문제를 일으킬 수 있다. 따라서 이 API의 사용은 명시적이어야 한다.

// 더 이상 사용되지 않음
webview.getWebContents()
// 대체 코드
const { remote } = require('electron')
remote.webContents.fromId(webview.getWebContentsId())

하지만 remote 모듈 사용을 완전히 피하는 것이 좋다.

// 메인 프로세스
const { ipcMain, webContents } = require('electron')

const getGuestForWebContents = (webContentsId, contents) => {
const guest = webContents.fromId(webContentsId)
if (!guest) {
throw new Error(`Invalid webContentsId: ${webContentsId}`)
}
if (guest.hostWebContents !== contents) {
throw new Error('Access denied to webContents')
}
return guest
}

ipcMain.handle('openDevTools', (event, webContentsId) => {
const guest = getGuestForWebContents(webContentsId, event.sender)
guest.openDevTools()
})

// 렌더러 프로세스
const { ipcRenderer } = require('electron')

ipcRenderer.invoke('openDevTools', webview.getWebContentsId())

더 이상 사용되지 않음: webFrame.setLayoutZoomLevelLimits()

Chromium에서는 레이아웃 줌 레벨 제한을 변경하는 기능을 제거했으며, Electron이 이를 유지할 수 있는 능력을 벗어났다. 이 함수는 Electron 8.x에서 경고를 발생시키고, Electron 9.x에서는 완전히 제거될 예정이다. 레이아웃 줌 레벨 제한은 이제 최소 0.25, 최대 5.0으로 고정되었다. 이는 여기에서 정의된 바와 같다.

systemPreferences에서 더 이상 사용되지 않는 이벤트

다음 systemPreferences 이벤트는 더 이상 사용되지 않는다:

  • inverted-color-scheme-changed
  • high-contrast-color-scheme-changed

대신 nativeTheme 모듈의 새로운 updated 이벤트를 사용한다.

// 더 이상 사용되지 않음
systemPreferences.on('inverted-color-scheme-changed', () => { /* ... */ })
systemPreferences.on('high-contrast-color-scheme-changed', () => { /* ... */ })

// 대체 코드
nativeTheme.on('updated', () => { /* ... */ })

더 이상 사용되지 않음: systemPreferences의 메서드

다음 systemPreferences 메서드는 더 이상 사용되지 않는다:

  • systemPreferences.isDarkMode()
  • systemPreferences.isInvertedColorScheme()
  • systemPreferences.isHighContrastColorScheme()

대신 다음과 같은 nativeTheme 속성을 사용한다:

  • nativeTheme.shouldUseDarkColors
  • nativeTheme.shouldUseInvertedColorScheme
  • nativeTheme.shouldUseHighContrastColors
// 더 이상 사용되지 않음
systemPreferences.isDarkMode()
// 대체 방법
nativeTheme.shouldUseDarkColors

// 더 이상 사용되지 않음
systemPreferences.isInvertedColorScheme()
// 대체 방법
nativeTheme.shouldUseInvertedColorScheme

// 더 이상 사용되지 않음
systemPreferences.isHighContrastColorScheme()
// 대체 방법
nativeTheme.shouldUseHighContrastColors

예정된 주요 API 변경 사항 (7.0)

폐기 예정: Atom.io Node 헤더 URL

이 URL은 .npmrc 파일 내 disturl로 지정되거나, 네이티브 Node 모듈을 빌드할 때 --dist-url 커맨드라인 플래그로 사용된다. 두 방식 모두 당분간 지원되지만, 가능한 한 빨리 변경하는 것을 권장한다.

폐기 예정: https://atom.io/download/electron

대체 URL: https://electronjs.org/headers

API 변경: session.clearAuthCache()는 더 이상 옵션을 허용하지 않음

session.clearAuthCache API는 이제 어떤 항목을 지울지에 대한 옵션을 받지 않으며, 대신 전체 캐시를 무조건적으로 지운다.

// 더 이상 사용되지 않음
session.clearAuthCache({ type: 'password' })
// 대신 이렇게 사용
session.clearAuthCache()

API 변경: powerMonitor.querySystemIdleStatepowerMonitor.getSystemIdleState로 변경됨

// Electron 7.0에서 제거됨
powerMonitor.querySystemIdleState(threshold, callback)
// 동기식 API로 대체
const idleState = powerMonitor.getSystemIdleState(threshold)

API 변경 사항: powerMonitor.querySystemIdleTimepowerMonitor.getSystemIdleTime로 변경됨

// Electron 7.0에서 제거됨
powerMonitor.querySystemIdleTime(callback)
// 동기식 API로 대체
const idleTime = powerMonitor.getSystemIdleTime()

API 변경: webFrame.setIsolatedWorldInfo가 개별 메서드를 대체함

// Electron 7.0에서 제거됨
webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp)
webFrame.setIsolatedWorldHumanReadableName(worldId, name)
webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin)
// 아래 메서드로 대체됨
webFrame.setIsolatedWorldInfo(
worldId,
{
securityOrigin: 'some_origin',
name: 'human_readable_name',
csp: 'content_security_policy'
})

getBlinkMemoryInfomarked 속성은 Chromium 77에서 제거되었으며, 더 이상 사용할 수 없다.

동작 변경: <input type="file"/>webkitdirectory 속성이 이제 디렉터리 내용을 나열합니다.

HTML 파일 입력의 webkitdirectory 속성을 사용하면 폴더를 선택할 수 있다. 이전 버전의 Electron에서는 이 속성이 잘못 구현되어 event.target.files가 선택한 폴더에 해당하는 하나의 File 객체를 반환했다.

Electron 7부터는 Chrome, Firefox, Edge와 마찬가지로 이제 FileList가 폴더 내에 포함된 모든 파일의 목록을 반환한다 (MDN 문서 링크).

예를 들어, 다음과 같은 구조의 폴더가 있다고 가정해 보자.

folder
├── file1
├── file2
└── file3

Electron <=6에서는 이 폴더를 선택하면 다음과 같은 File 객체를 가진 FileList가 반환되었다.

path/to/folder

Electron 7에서는 이제 다음과 같은 File 객체를 가진 FileList가 반환된다.

/path/to/folder/file3
/path/to/folder/file2
/path/to/folder/file1

webkitdirectory는 더 이상 선택한 폴더의 경로를 노출하지 않는다. 폴더 내용이 아닌 선택한 폴더의 경로가 필요하다면 dialog.showOpenDialog API를 참고하길 바란다 (링크).

API 변경: Promise 기반 API로 대체된 콜백 기반 버전

Electron 5와 Electron 6에서는 기존의 비동기 API를 Promise 기반으로 변경하고, 이전의 콜백 기반 버전을 더 이상 사용하지 않도록 권장했다. Electron 7부터는 더 이상 사용되지 않는 콜백 기반 API가 완전히 제거되었다.

이제 다음 함수들은 Promise만 반환한다:

  • app.getFileIcon() #15742
  • app.dock.show() #16904
  • contentTracing.getCategories() #16583
  • contentTracing.getTraceBufferUsage() #16600
  • contentTracing.startRecording() #16584
  • contentTracing.stopRecording() #16584
  • contents.executeJavaScript() #17312
  • cookies.flushStore() #16464
  • cookies.get() #16464
  • cookies.remove() #16464
  • cookies.set() #16464
  • debugger.sendCommand() #16861
  • dialog.showCertificateTrustDialog() #17181
  • inAppPurchase.getProducts() #17355
  • inAppPurchase.purchaseProduct()#17355
  • netLog.stopLogging() #16862
  • session.clearAuthCache() #17259
  • session.clearCache() #17185
  • session.clearHostResolverCache() #17229
  • session.clearStorageData() #17249
  • session.getBlobData() #17303
  • session.getCacheSize() #17185
  • session.resolveProxy() #17222
  • session.setProxy() #17222
  • shell.openExternal() #16176
  • webContents.loadFile() #15855
  • webContents.loadURL() #15855
  • webContents.hasServiceWorker() #16535
  • webContents.printToPDF() #16795
  • webContents.savePage() #16742
  • webFrame.executeJavaScript() #17312
  • webFrame.executeJavaScriptInIsolatedWorld() #17312
  • webviewTag.executeJavaScript() #17312
  • win.capturePage() #15743

다음 함수들은 이제 동기식과 Promise 기반 비동기식 두 가지 형태를 제공한다:

  • dialog.showMessageBox()/dialog.showMessageBoxSync() #17298
  • dialog.showOpenDialog()/dialog.showOpenDialogSync() #16973
  • dialog.showSaveDialog()/dialog.showSaveDialogSync() #17054

예정된 주요 API 변경 사항 (6.0)

변경된 API: win.setMenu(null)win.removeMenu()

// 더 이상 사용되지 않음
win.setMenu(null)
// 대체할 코드
win.removeMenu()

API 변경: 렌더러 프로세스에서 electron.screenremote를 통해 접근해야 한다

// Deprecated
require('electron').screen
// Replace with
require('electron').remote.screen

API 변경: 샌드박스된 렌더러에서 노드 내장 모듈을 require()할 때 더 이상 remote 버전을 암시적으로 로드하지 않음

// 더 이상 사용되지 않음
require('child_process')
// 대체 방법
require('electron').remote.require('child_process')

// 더 이상 사용되지 않음
require('fs')
// 대체 방법
require('electron').remote.require('fs')

// 더 이상 사용되지 않음
require('os')
// 대체 방법
require('electron').remote.require('os')

// 더 이상 사용되지 않음
require('path')
// 대체 방법
require('electron').remote.require('path')

powerMonitor.querySystemIdleState는 더 이상 사용되지 않으며, powerMonitor.getSystemIdleState로 대체되었다.

// 더 이상 사용되지 않음
powerMonitor.querySystemIdleState(threshold, callback)
// 동기 API로 대체
const idleState = powerMonitor.getSystemIdleState(threshold)

더 이상 사용되지 않음: powerMonitor.querySystemIdleTimepowerMonitor.getSystemIdleTime로 대체됨

// 더 이상 사용되지 않음
powerMonitor.querySystemIdleTime(callback)
// 동기식 API로 대체
const idleTime = powerMonitor.getSystemIdleTime()

Deprecated: app.enableMixedSandbox()는 더 이상 필요하지 않음

// Deprecated
app.enableMixedSandbox()

Mixed-sandbox 모드는 이제 기본적으로 활성화되어 있다.

더 이상 사용되지 않음: Tray.setHighlightMode

macOS Catalina에서 기존 Tray 구현이 동작하지 않는다. Apple의 기본 대체 기능은 하이라이트 동작 변경을 지원하지 않는다.

// 더 이상 사용되지 않음
tray.setHighlightMode(mode)
// 이 API는 v7.0에서 대체 기능 없이 제거될 예정이다.

예정된 주요 API 변경 사항 (5.0)

기본값 변경: nodeIntegrationwebviewTag는 기본적으로 false로, contextIsolation은 true로 설정됨

아래 나열된 webPreferences 옵션의 기본값이 새로운 기본값으로 변경된다. 이전 기본값은 더 이상 사용되지 않는다.

속성이전 기본값새로운 기본값
contextIsolationfalsetrue
nodeIntegrationtruefalse
webviewTagnodeIntegration이 설정된 경우 그 값, 그렇지 않으면 truefalse

예를 들어, webviewTag를 다시 활성화하려면 다음과 같이 설정한다.

const w = new BrowserWindow({
webPreferences: {
webviewTag: true
}
})

nativeWindowOpen 옵션을 사용해 열린 자식 윈도우에서는 nodeIntegrationInSubFramestrue로 설정되지 않는 한 항상 Node.js 통합이 비활성화된다.

API 변경: 권한 있는 스키마 등록은 이제 앱 준비 전에 완료해야 함

렌더러 프로세스 API인 webFrame.registerURLSchemeAsPrivilegedwebFrame.registerURLSchemeAsBypassingCSP, 그리고 브라우저 프로세스 API인 protocol.registerStandardSchemes가 제거되었다.

새로운 API인 protocol.registerSchemesAsPrivileged가 추가되었으며, 이 API를 사용해 필요한 권한을 가진 커스텀 스키마를 등록해야 한다. 커스텀 스키마는 앱 준비 전에 등록해야 한다.

더 이상 사용되지 않음: webFrame.setIsolatedWorld*webFrame.setIsolatedWorldInfo로 대체됨

// 더 이상 사용되지 않음
webFrame.setIsolatedWorldContentSecurityPolicy(worldId, csp)
webFrame.setIsolatedWorldHumanReadableName(worldId, name)
webFrame.setIsolatedWorldSecurityOrigin(worldId, securityOrigin)
// 대체 방법
webFrame.setIsolatedWorldInfo(
worldId,
{
securityOrigin: 'some_origin',
name: 'human_readable_name',
csp: 'content_security_policy'
})

API 변경: webFrame.setSpellCheckProvider가 비동기 콜백을 받도록 변경됨

spellCheck 콜백이 비동기 방식으로 변경되었고, autoCorrectWord 매개변수가 제거되었다.

// 이전 방식 (더 이상 사용되지 않음)
webFrame.setSpellCheckProvider('en-US', true, {
spellCheck: (text) => {
return !spellchecker.isMisspelled(text)
}
})
// 변경된 방식
webFrame.setSpellCheckProvider('en-US', {
spellCheck: (words, callback) => {
callback(words.filter(text => spellchecker.isMisspelled(text)))
}
})

API 변경: webContents.getZoomLevelwebContents.getZoomFactor가 동기 방식으로 변경됨

webContents.getZoomLevelwebContents.getZoomFactor는 더 이상 콜백 인자를 받지 않으며, 대신 직접 숫자 값을 반환한다.

// 더 이상 사용되지 않는 방식
webContents.getZoomLevel((level) => {
console.log(level)
})
// 변경된 방식
const level = webContents.getZoomLevel()
console.log(level)
// 더 이상 사용되지 않는 방식
webContents.getZoomFactor((factor) => {
console.log(factor)
})
// 변경된 방식
const factor = webContents.getZoomFactor()
console.log(factor)

예정된 주요 API 변경 사항 (4.0)

아래 목록은 Electron 4.0에서 이루어진 주요 API 변경 사항을 포함한다.

app.makeSingleInstance

// 더 이상 사용되지 않음
app.makeSingleInstance((argv, cwd) => {
/* ... */
})
// 대체 방법
app.requestSingleInstanceLock()
app.on('second-instance', (event, argv, cwd) => {
/* ... */
})

app.releaseSingleInstance

// 더 이상 사용되지 않음
app.releaseSingleInstance()
// 대신 이걸 사용
app.releaseSingleInstanceLock()

app.getGPUInfo

app.getGPUInfo('complete')
// 이제 macOS에서 `basic`과 동일하게 동작한다
app.getGPUInfo('basic')

윈도우용 네이티브 모듈을 빌드할 때, 모듈의 binding.gyp 파일에 있는 win_delay_load_hook 변수는 반드시 true로 설정해야 한다(기본값이 true이다). 이 훅이 없으면 윈도우에서 네이티브 모듈을 로드하지 못하고 Cannot find module과 같은 오류 메시지가 표시된다. 자세한 내용은 네이티브 모듈 가이드를 참고한다.

IA32 Linux 지원 중단

Electron 18부터는 32비트 Linux 시스템에서 더 이상 실행되지 않는다. 자세한 내용은 32비트 Linux 지원 중단을 참고한다.

API 변경 사항 (3.0 버전)

아래 목록은 Electron 3.0 버전에서 발생한 주요 API 변경 사항을 정리한 것이다.

app

// 더 이상 사용되지 않음
app.getAppMemoryInfo()
// 대체 방법
app.getAppMetrics()

// 더 이상 사용되지 않음
const metrics = app.getAppMetrics()
const { memory } = metrics[0] // 더 이상 사용되지 않는 속성

BrowserWindow

// 더 이상 사용되지 않음
const optionsA = { webPreferences: { blinkFeatures: '' } }
const windowA = new BrowserWindow(optionsA)
// 대체 방법
const optionsB = { webPreferences: { enableBlinkFeatures: '' } }
const windowB = new BrowserWindow(optionsB)

// 더 이상 사용되지 않음
window.on('app-command', (e, cmd) => {
if (cmd === 'media-play_pause') {
// 특정 동작 수행
}
})
// 대체 방법
window.on('app-command', (e, cmd) => {
if (cmd === 'media-play-pause') {
// 특정 동작 수행
}
})

clipboard

// Deprecated
clipboard.readRtf()
// Replace with
clipboard.readRTF()

// Deprecated
clipboard.writeRtf()
// Replace with
clipboard.writeRTF()

// Deprecated
clipboard.readHtml()
// Replace with
clipboard.readHTML()

// Deprecated
clipboard.writeHtml()
// Replace with
clipboard.writeHTML()

crashReporter

// Deprecated
crashReporter.start({
companyName: 'Crashly',
submitURL: 'https://crash.server.com',
autoSubmit: true
})
// Replace with
crashReporter.start({
companyName: 'Crashly',
submitURL: 'https://crash.server.com',
uploadToServer: true
})

nativeImage

// 사용 중단됨
nativeImage.createFromBuffer(buffer, 1.0)
// 대체 코드
nativeImage.createFromBuffer(buffer, {
scaleFactor: 1.0
})

process

// 더 이상 사용되지 않음
const info = process.getProcessMemoryInfo()

screen

// 더 이상 사용되지 않음
screen.getMenuBarHeight()
// 대체 방법
screen.getPrimaryDisplay().workArea

session

// 더 이상 사용되지 않음
ses.setCertificateVerifyProc((hostname, certificate, callback) => {
callback(true)
})
// 대체 방법
ses.setCertificateVerifyProc((request, callback) => {
callback(0)
})

Tray

// 더 이상 사용되지 않음
tray.setHighlightMode(true)
// 대체 방법
tray.setHighlightMode('on')

// 더 이상 사용되지 않음
tray.setHighlightMode(false)
// 대체 방법
tray.setHighlightMode('off')

webContents

// 더 이상 사용되지 않음(deprecated)
webContents.openDevTools({ detach: true })
// 대체 방법
webContents.openDevTools({ mode: 'detach' })

// 제거됨
webContents.setSize(options)
// 이 API를 대체할 수 있는 방법은 없음

webFrame

// 더 이상 사용되지 않음
webFrame.registerURLSchemeAsSecure('app')
// 대체 방법
protocol.registerStandardSchemes(['app'], { secure: true })

// 더 이상 사용되지 않음
webFrame.registerURLSchemeAsPrivileged('app', { secure: true })
// 대체 방법
protocol.registerStandardSchemes(['app'], { secure: true })

<webview>

// 제거됨
webview.setAttribute('disableguestresize', '')
// 이 API를 대체할 기능은 없음

// 제거됨
webview.setAttribute('guestinstance', instanceId)
// 이 API를 대체할 기능은 없음

// webview 태그에서 키보드 리스너가 더 이상 작동하지 않음
webview.onkeydown = () => { /* 핸들러 */ }
webview.onkeyup = () => { /* 핸들러 */ }

Node Headers URL

이 URL은 .npmrc 파일에서 disturl로 지정하거나, 네이티브 Node 모듈을 빌드할 때 --dist-url 커맨드라인 플래그로 사용된다.

더 이상 사용되지 않는 URL: https://atom.io/download/atom-shell

대체 URL: https://atom.io/download/electron

주요 API 변경 사항 (2.0 버전)

다음은 Electron 2.0에서 발생한 주요 API 변경 사항 목록이다.

BrowserWindow

// 더 이상 사용되지 않음
const optionsA = { titleBarStyle: 'hidden-inset' }
const windowA = new BrowserWindow(optionsA)
// 대체 방법
const optionsB = { titleBarStyle: 'hiddenInset' }
const windowB = new BrowserWindow(optionsB)
// 이전 코드
menu.popup(browserWindow, 100, 200, 2)
// 변경된 코드
menu.popup(browserWindow, { x: 100, y: 200, positioningItem: 2 })

nativeImage

// 제거됨
nativeImage.toPng()
// 대체됨
nativeImage.toPNG()

// 제거됨
nativeImage.toJpeg()
// 대체됨
nativeImage.toJPEG()

process

  • process.versions.electronprocess.version.chrome은 Node에서 설정된 다른 process.versions 프로퍼티와 일관성을 유지하기 위해 읽기 전용 프로퍼티로 변경된다.

webContents

// 제거됨
webContents.setZoomLevelLimits(1, 2)
// 대체됨
webContents.setVisualZoomLevelLimits(1, 2)

webFrame

// 제거됨
webFrame.setZoomLevelLimits(1, 2)
// 대체됨
webFrame.setVisualZoomLevelLimits(1, 2)

<webview>

// 제거됨
webview.setZoomLevelLimits(1, 2)
// 대체됨
webview.setVisualZoomLevelLimits(1, 2)

중복된 ARM 에셋

각 Electron 릴리스에는 파일명이 약간 다른 두 개의 동일한 ARM 빌드가 포함된다. 예를 들어 electron-v1.7.3-linux-arm.zipelectron-v1.7.3-linux-armv7l.zip이 있다. v7l 접두사가 붙은 에셋은 사용자에게 어떤 ARM 버전을 지원하는지 명확히 하기 위해 추가되었으며, 향후 생성될 수 있는 armv6l 및 arm64 에셋과 구별하기 위한 목적도 있다.

접두사가 없는 파일은 여전히 이를 사용 중인 설정이 깨지지 않도록 게시되고 있다. 하지만 2.0 버전부터는 접두사가 없는 파일은 더 이상 게시되지 않을 예정이다.

자세한 내용은 69867189을 참고한다.