일렉트론

일렉트론 dom과 node사이의 bridge를 놓아보자

2023. 11. 7. 07:33
글 목차


원래 index.html에서 로컬컴퓨터를 컨트롤 하는건 보안적으로 좋지 않다.

 

예를 들어 https://~~.com 에 접속했더니 내컴퓨터에서 node.js가 실행되서 컴퓨터를 그냥 파괴해버리는 명령이 실행되면

얼탱이가 없지 않을까??

 

그래서 index.html에 참조되는 script는 그냥 웹브라우저 상에서 작동하는 코드만 적는거고 내컴퓨터를 뒤지거나 망가뜨릴만한 것은 안적는다.

 

하지만 그래서야 그냥 웹페이지를 만들고말지 일렉트론 같은 데스크탑앱을 왜 만들겠는가. 따라서 index.html에서 node를 실행할 수 있는 브릿지를 놓아서 이를 실행하고자 한다.

 

https://www.electronjs.org/docs/latest/tutorial/tutorial-preload

이 페이지에서 설명하고 있는 preload.js가 바로 node와 dom을 이어주는 브릿지이다.

 

일단 main.js의 브라우저 객체안에

webPreferences: {
	preload: path.join(__dirname, 'preload.js')
}

라는 속성을 추가해 준다. preload.js를 앱실행하기전에 실행해 주겠다는 뜻이다.

 

<index.html>

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta
      http-equiv="Content-Security-Policy"
      content="default-src 'self'; script-src 'self'"
    />
    <meta
      http-equiv="X-Content-Security-Policy"
      content="default-src 'self'; script-src 'self'"
    />
    <title>Hello from Electron renderer!</title>
  </head>
  <body>
    <h1>Hello from Electron renderer!</h1>
    <p>👋</p>
    <p id="info"></p>
    asfefasefsae1111
  </body>
  <script src="./renderer.js"></script>  // renderer.js 참조
</html>

 

 

<render.js>

const func = async () => {
    const response = await window.versions.ping()
    console.log(response)
}

func()

 

 

<preload.js>

const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('versions', {
  node: () => process.versions.node,
  chrome: () => process.versions.chrome,
  electron: () => process.versions.electron,
  ping: () => ipcRenderer.invoke('ping')
})

 

<main.js>

const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')

const createWindow = () => {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })
  win.loadFile('index.html')
}
app.whenReady().then(() => {
  ipcMain.handle('ping', () => {return 'pong'})
  createWindow()
})

 

index.html이 참조하고 있는 render.js에서 preload에서 정의한 window.versions이라는 객체의 ping()을 호출한다.

그럼 main.js에서 ipc.handle에서 정의한 ping이란 함수가 실행되서 pong을 반환한다.

 

이때! render.js는 index.html에서 참조하고 있는 js이기 때문에 개발자 도구에 console이 찍히는 거고 terminal에는 아무것도 찍히지 않는다.

 

정리하자면

 

일렉트론 dom과 node사이의 bridge를 놓아보자