1.3 Quick Start 마무리

MunSeoJun·2021년 8월 26일
0
post-thumbnail

preload 스크립트를 사용하여 renderer에서 Node.js 접근하기

이제 마지막으로 해야 할 일은 Electron과 웹 페이지 의존성의 버전 출력하는 것입니다.

이 정보에 접근하는 것은 Node.js 전역 프로세스 객체를 통해 메인 프로세스에서 실행하는 것이 쉽습니다. 그러나 renderer 문서 컨텍스트에 접근할 수 없기 때문에 메인 프로세스에서 DOM을 수정할 수 없습니다. 그것들은 완전히 다른 프로세스입니다!

참고: Electron 프로세스에 대해 더 깊게 알고 싶다면 Process Model 문서를 읽어보세요.

preload 스크립트를 첨부하면 renderer에 도달하기 쉽습니다. perload 스크립트는 renderer 프로세스가 불러와지기 전에 실행되며, renderer 전역과 Node.js 환경 모두 접근할 수 있습니다.

preload.js 스크립트를 다음과 같이 생성합니다.

window.addEventListener('DOMContentLoaded', () => {
  const replaceText = (selector, text) => {
    const element = document.getElementById(selector)
    if (element) element.innerText = text
  }

  for (const dependency of ['chrome', 'node', 'electron']) {
    replaceText(`${dependency}-version`, process.versions[dependency])
  }
})

위의 코드는 Node.js의 process.versions 객체에 접근하고 HTML 문서의 버전을 입력하기 위한 replaceText 함수를 실행합니다.

이 스크립트를 renderer 프로세스와 연결하려면, BrowserWindow 생성자의 webPreferences.preload 옵션에 preload 스크립트의 경로를 전달합니다.

// include the Node.js 'path' module at the top of your file
const path = require('path')

// modify your existing createWindow() function
const createWindow = () => {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  win.loadFile('index.html')
}
// ...

다음은 사용된 Node.js의 컨셉 2개입니다:

  • __dirname 문자열은 현재 실행 중인 스크립트의 경로입니다. (지금의 경우는 프로젝트의 루트 폴더입니다.)
  • path.join API는 여러 경로의 세그먼트를 함께 결합하여 모든 플렛폼에서 동작하는 경로 문자열을 만듭니다.

현재 실행 중인 JavaScript 파일은에 대한 상대 경로를 사용하므로 상대 경로가 개발 보드와 패키지 모드 모두에서 작동합니다.

추가: 웹 콘텐츠에 기능 추가하기

이 시점에서 Application에 더 많은 기능을 추가하는 방법에 대해 궁금하실 겁니다.

웹 콘텐츠와 상호작용을 위해 스크립트를 renderer 프로세스에 추가하려고 합니다. renderer는 일반적은 웹 환경에서 작동하기 때문에 index.html 파일을 닫는 바로 앞에

<script src="./renderer.js"></script>

그런 다음 renderer.js에 포함된 코드는 동일한 JavaScript API를 사용할 수 있고 웹팩을 사용하여 코드를 묶고 축소하거나 React를 사용하여 사용자의 인터페이스를 관리할 수 있습니다.

개괄하기

모든 단계를 성공적으로 따라왔다면 다음과 같은 Electron application을 볼 수 있습니다:

모든 코드:

// main.js

// Modules to control application life and create native browser window
const { app, BrowserWindow } = require('electron')
const path = require('path')

const createWindow = () => {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  // and load the index.html of the app.
  mainWindow.loadFile('index.html')

  // Open the DevTools.
  // mainWindow.webContents.openDevTools()
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  createWindow()

  app.on('activate', () => {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit()
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
// preload.js

// All of the Node.js APIs are available in the preload process.
// It has the same sandbox as a Chrome extension.
window.addEventListener('DOMContentLoaded', () => {
  const replaceText = (selector, text) => {
    const element = document.getElementById(selector)
    if (element) element.innerText = text
  }

  for (const dependency of ['chrome', 'node', 'electron']) {
    replaceText(`${dependency}-version`, process.versions[dependency])
  }
})
<!--index.html-->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
    <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 World!</title>
  </head>
  <body>
    <h1>Hello World!</h1>
    We are using Node.js <span id="node-version"></span>,
    Chromium <span id="chrome-version"></span>,
    and Electron <span id="electron-version"></span>.

    <!-- You can also require other files to run in this process -->
    <script src="./renderer.js"></script>
  </body>
</html>

지금까지 해왔던 내용 요약:

  • Node.js Application을 부트스트랩하고 Electron을 종속성으로 추가하였습니다.
  • 앱을 제어하고 Node.js 환경에서 실행되는 메인 프로세스를 실행하는 main.js 스크립트를 생성하였습니다. Electron의 app와 BrowserWindow 모듈을 사용하여 별도의 프로세서(renderer)에서 웹 콘텐츠를 표시하는 브라우저 창을 생성하였습니다.
  • renderer의 특정 Node.js 기능에 접근하기 위해, preload 스크립트를 BrowserWindow 생성자에 연결하였습니다.

패키지와 배포


Electron Forge를 사용한 빠른 배포 방법

  1. Electron Forge를 개발 종속성에 추가하고 import 명령어를 사용하여 Forge의 scaffolding을 설정합니다.
npm install --save-dev @electron-forge/cli
npx electron-forge import

✔ Checking your system
✔ Initializing Git Repository
✔ Writing modified package.json file
✔ Installing dependencies
✔ Writing modified package.json file
✔ Fixing .gitignore

We have ATTEMPTED to convert your app to be in a format that electron-forge understands.

Thanks for using "electron-forge"!!!
  1. Forge의 make 명령어를 사용하여 배포 가능하게 만듭니다
npm run make

> my-electron-app@1.0.0 make /my-electron-app
> electron-forge make

✔ Checking your system
✔ Resolving Forge Config
We need to package your application before we can make it
✔ Preparing to Package Application for arch: x64
✔ Preparing native dependencies
✔ Packaging Application
Making for the following targets: zip
✔ Making for target: zip - On platform: darwin - For arch: x64

Electron Forge는 패키지가 위치한 out 폴더를 생성합니다.

// Example for macOS
out/
├── out/make/zip/darwin/x64/my-electron-app-darwin-x64-1.0.0.zip
├── ...
└── out/my-electron-app-darwin-x64/my-electron-app.app/Contents/MacOS/my-electron-app
profile
여러 분야를 공부하고 싶은 학생입니다

0개의 댓글