728x90

Main 과 Renderer  프로세스 :: 가장 중요한 개념

Main Process

Main process 는 Node.js 기반으로 Node.js에서 사용하는 모든 모듈들을 사용할 수 있으며, Back-end의 영역에 속합니다.

package.json파일의 main 스크립트를 실행하는 프로세스로 "메인 프로세스"라고 불리며, 메인 프로세스에서 실행되는 스크립트는 웹페이지들을 GUI로 표시해줍니다.

 

Electron 애플리케이션은 항상 하나의 메인프로세스를 가지고 있습니다.

Renderer 프로세스는 여러개 존재할 수 있지만. 메인 프로세스는 애플리케이션  당 하나만 존재할 수 있습니다.


Electron은 웹페이지를 보여주기 위해 Chromium을 사용한다.

Electron은 웹페이지를 보여주기 위해 Chromium을 사용하기 때문에 Chromium의 멀티프로세스 아키텍쳐가 그대로 사용합니다.

Electron안에서 보여지는 각각의 웹페이지는 자신의  프로세스안에서 동작하는데, 이 프로세스를 Renderer 프로세스라 부릅니다.

일반적인 브라우저에서 웹페이지는 대개 샌드박스 환경에서 실행되고 네이티브 리스소에는 엑세스 할 수 없습니다.

그러나 Electron을 사용하는 User는 웹페이지가 Node.js APIs를 이용할 수 있기 때문에, 보다 낮은 수준에서 운영체제와 상호작용하는 것이 허용되어 있습니다.


Renderer Process

Renderer Process 는 HTML, CSS, JavaScript로 이루어지는 영역이며, Font-end영역입니다.

위에서 언급했듯이 Electron안에서 보여지는 각각의 웹페이지는 자신의  프로세스안에서 동작하는데, 이 프로세스를 Renderer 프로세스라 부릅니다.


Main Process와 Renderer Process 의 차이점

1. Main Process 는 BrowserWindow 인스턴스를 생성하여 웹페이지를 만듭니다.

2. 각각의 BrowserWindow 인스턴스는 자체 Renderer Process에서 웹페이지를 실행합니다.

3. BrowserWindow 인스턴스가 소멸되면, 해당 Renderer Process 도 종료합니다.

4. Main Process 는 모든 웹 페이지와 각 페이지들이 소유한 Renderer Process 들을 관리합니다.

5. 각각의 Renderer Process는 서로 독립적으로 동작하고 이들이 실행한 웹페이지 내에서만 관여를 합니다.

 

6. 웹페이지에서 네이티브 GUI관련 API 호출은 허용하지 못합니다. 왜냐하면 이것은 매우 위험한 일이고, 리소스 릭을 발생시키기 쉽기 때문입니다.

 

7. 웹페이지에서 GUI 작업을 수행하려면, 웹페이지의 Renderer Process 가 Main Process에게 네이티브GUI 관련 작업을 수행할 수 있도록 요청해야 합니다.

 

8. Electron은 Main Process와 Renderer Process 에서 사용할 수 있는 API를 제공하고 있는데, 이 API들은 프로세스 타입에 따라 사용됩니다.

 

9. 대부분의 API는 Main Process에서만 사용할 수 있으며, 일부는 Renderer 프로세스에서만, 또 다른 일부는 양쪽 모두 사용할 수 있는 API로 구분되어 사용됩니다.

 

프로세스간 통신 
Electron에서 메세지를 전송하기 위한 ipcRenderer 와 ipcMain 모듈, RPC방식 통신을 위한 remote 모듈과 같이 Main Process와 Renderer Process 가 통신하는 방법이 여러가지 있습니다.

https://electronjs.org/docs/faq#how-to-share-data-between-web-pages 참조

Electron API 사용하기

Electron은 Main Process와 Renderer Process에서 DeskTop 응용프로그램의 개발을 지원하여 여러 API들을 제공합니다.

두 프로세스 모두에서 아래와 같이 모듈을 포함해서 Electron의 API 에 접근할 수 있습니다.

모든 Electron API 들은 프로세스 타입에 따라 사용할 수 있습니다.

위의 BrowserWindow 클래스는 Main Process 만 사용할 수 있습니다.

이 BrowserWindow 클래스를 Renderer Process 에서 사용한다면 "undefined"가 날 것입니다.

 

프로세스간에는 통신이 가능하기 때문에, Renderer Process 는 작업을 수행하기 위해 Main Process를 호출할 수 있습니다.

Electron 은 보통 Main Process에서만 사용가능한 API들을 노출시키는 remote 라는 모듈을 제공합니다.

Renderer Process에서 BrowserWindow 를 만들기 위해 remote 모듈을 중간자로 사용합니다.

const { remote } = require('electron');
const { BrowserWindow } = remote;

const win = new BrowserWindow();

Node.js API 사용하기

Electron 은 Main과 Renderer Process 에서  Node.js 전체 접근이 가능합니다.

이것은 Node.js에서 사용할 수 있는 모든 API들을 Electron 에서 사용할 수 있다는 뜻입니다.

const fs = require('fs');
const root = fs.readdirSync('/');

// 디스크의 최상위 레벨인 / 또는 c:\ 에 있는 모든 파일을 출력하게 됩니다.
console.log(root);

이런 코드를 삽입하게 될 경우에 원격 콘텐츠를 로드하려고 시도한 경우 보안에 중요한 영향을 끼치게 됩니다.

원격 콘텐츠 로드에 대한 더 많은 정보와 지침은 다음 URL에서 확인해 보세요.

https://electronjs.org/docs/tutorial/security

 

'Electron' 카테고리의 다른 글

Electron Quick start (Eelectron & reactJS & electron-builder)  (0) 2020.01.10
728x90

Eelctron 으로 원도우와 MAC용 어플리케이션을 만들 수 있습니다.

앞으로 설명하는 내용들은 "How to build an Electron app using Create React App and Electron Builder" 를 주로 참고하였고, 나머지 추가적인 부분은 아래 blog 를 확인해 보시길 바랍니다.

 

How to build an Electron app using Create React App and Electron Builder
Create React App 과 Eelectron Builder 를 이용하여 Eelectron App 만드는 방법
https://www.codementor.io/@randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer
react-scripts를 rescripts 로 변경하기
https://github.com/harrysolovay/rescripts
Electron 애플리케이션 만들기
https://hsoh1990.github.io/2019/01/18/electron-tutorial/#Quick-start
electron-builder 사용하기
https://itinerant.tistory.com/88

The stack

Eelctron은 native applications을 생성하기 위한 플레임웍으로  Javascript, HTML, CSS 의 웹기술(web technologies)를 이용합니다.

그리고 이번 문서에는 React를 사용할 것입니다.

 

React는 JavaScript library 로 user interfaces를 빌드하고 더많은 것들을 지원해 줍니다.

 

React setup 을 보다 쉽게 만들기 위해 우리는 Create React App 을 사용할 것입니다.

Create React App (CRA) 은 대박입니다. buckget-of-time을 절약해주고, config 설정 지옥을 벗어나게 해줍니다.

Create React App 은 (페이스북 개발자가 만든) 툴 로써, 당신이 React apps을 빌드할 때의 거대한 출발점을 제공해줍니다.

특히 설정(setup) 및 구성(configuration)에 걸리는 시간을 절약해줍니다.

단지 하나의 명령만으로 실행하며, Create React App을 설정하는 툴로 당신이 React project를 시작할때 필요합니다.

 

Rescripts 는 CRA setup 제거(ejecting)없이 사용할 수 있게 해줍니다.

Ejecting CRA 는 실제로 피하고 싶은 것으로, 향후 CRA 개선이 될때 더 이상 혜택을 받을 수 없게 됩니다.

 

Electron Builder는 desktop app 배포를 위해 패키징하는데 이용합니다.

 

(Electron is a framework for creating native applications with web technologies like JavaScript, HTML, and CSS.

In our case we'll be using React.)

 

(React is JavaScript library for building user interfaces... and so much more.)

 

(To make the React setup easier we're going to use Create React App. 

Create React App (CRA) is awesome because it saves buckets-of-time and eliminates config hell.Create React App is a tool (built by developers at Facebook) that gives you a massive head start when building React apps. 

It saves you from time-consuming setup and configuration. You simply run one command and Create React App sets up the tools you need to start your React project.)

 

(Rescripts allows us to customize the CRA setup without ejecting.
Ejecting CRA is something you really want to avoid, because you will no longer benefit from the future improvements to CRA.)

 

(Electron Builder is used to package our desktop app for distribution.)


1. create-react-app 툴을 이용하여 my-app 이라는  my-app 프로젝트를 만듭니다.

$npx  create-react-app my-app
$ cd  my-app

npx  는 npm 5.2.0 이후 버전을 설치하면 npx 라는 새로운 바이너리가 설치됩니다.
npx는 npm의 패키지 사용에 도움이되는 도구입니다.

 

 

2. yarn으로 electron, electron-builder 를 설치합니다.

yarn add electron electron-builder --dev

 

3. yarn 으로 wait-on concurrently, electron-is-dev의 개발도구를 설치합니다.

yarn add wait-on concurrently --dev
yarn
add electron-is-dev

 

4. public/electron.js 의 파일을 생성하고 아래 코드를 삽입합니다.

const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const path = require('path');
const isDev = require('electron-is-dev');

let mainWindow;

function createWindow(){
   mainWindow = new BrowserWindow({width:900, height:680});
   mainWindow.loadURL(isDev ? 'http://localhost:3000' : `file:${path.join(__dirname, '../build/index.html')}`);
   if(isDev){
      mainWindow.webContents.openDevTools();
   }
   mainWindow.on('closed', ()=>mainWindow = null);
}

app.on('ready', createWindow);

app.on('window-all-closed', ()=>{
   if(process.platform !== 'darwin'){
      app.quit();
   }
});

app.on('activate',()=>{
   if(mainWindow === null){
      createWindow();
   }
});

 

5. package.json 파일에 "scripts" 태그에 아래의 코드를 입력하세요.

"electron-dev": "concurrently \"BROWSER=none yarn start\" \"wait-on http://localhost:3000 && electron .\""

이 스크립트는 Electron을 시작하기 전에 CRA가 http://localhost:3000으로 Reac 앱이 실행할 때까지 기다렸다가. electron을 실행하는 스크립트입니다.

 

5. package.json 파일에 태그에 아래의 코드를 입력하세요.

"main": "public/electron.js",

 

6. package.json 의 전체적인 윤곽은 아래와 같습니다.

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "electron-is-dev": "^1.0.1",
    "react": "^16.8.3",
    "react-dom": "^16.8.3",
    "react-scripts": "2.1.5"
  },
  "main": "public/electron.js",
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "electron-dev": "concurrently \"BROWSER=none yarn start\" \"wait-on http://localhost:3000 && electron .\""
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ],
  "devDependencies": {
    "concurrently": "^4.1.0",
    "electron": "^4.0.6",
    "electron-builder": "^20.38.5",
    "wait-on": "^3.2.0"
  }
}

 

7. 이 시점에 개발모드로 새 앱을 실행해 봅시다.

yarn electron-dev

 

command 라인에서 "yarn electron-dev" 를 실행한 로그 화면입니다.

 

 


 

위의 화면처럼 보여진다면, 우리는 앱을 개발할 준비가 드디어 된 것입니다.

이제 우리는 fs module(파일을 핸들링 하는 모듈이라 생각하시면 됩니다.) 와 같은 access가 필요로 한다면, "Module not found" 라는 에러가 뜰 것입니다.

이것을 해결하기 위해 Webpack target에 있는 electron-renderer 를 이용하는 것을 필요로 합니다.

하지만 CRA 를 제거하는 일이 일어나지 않게 말입니다.

그래서 우리는 Rescripts를 이용할 것입니다.

자 한번 보세요.

 

1. Rescripts를 설치합니다.

yarn add @rescripts/cli @rescripts/rescript-env --dev

 

2. 그 다음 package.json 파일에서 "scripts" 태그분에서 아래 부분을 찾아서 변경해 주세요.

변경전

"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",

변경후

"start": "rescripts start",
"build": "rescripts build",
"test": "rescripts test",

 

3. 이제 .rescriptsrc.js 파일을 새로 만들고, 아래 내용을 입력해 주세요.

module.exports = [require.resolve('./.webpack.config.js')]

 

4. 마지막으로  .webpack.config.js 파일을 만들어서 아래 내용을 입력해 주세요. 

// define child rescript
module.exports = config => {
  config.target = 'electron-renderer';
  return config;
}

자 이제 우리는 fs 모듈을 걱정없이 사용할 수 있게 되었습니다.

 


이제 패키지화 합니다.

1.먼저 Electron Builder 와 Typescript 를 추가합니다.

yarn add electron-builder typescript --dev

CRA(Create-React-App)은 기본적으로 절대경로를 이용하는 index.html을 빌드합니다.

Electron 에서 로딩을 할때 실패가 날 수 있습니다. 해서 이 config 를 수정해줘야 합니다.

 

 

2. package.json 파일에서 "homepage"프로퍼티를 추가해 줍니다.

"homepage": "./",

 

3. 다음으로 "electron-pack " command를 이용해서 패키지를 빌드할 수 있도록 package.json 파일에서 scripts태그에 아래의 내용을 추가합니다.

"postinstall": "electron-builder install-app-deps",
"preelectron-pack": "yarn build",
"electron-pack": "electron-builder build -mwl",

 

"postinstall": "electron-builder install-app-deps" 

우리가 가지고 있는 native dependencies를 항상 electron version과 매치가 되도록 보장해 줍니다.

(will ensure that your native dependencies always match the electron version.)

 

"preelectron-pack": "yarn build"

CRA - 리액트 APP을 빌드할 것입니다.

 

"electron-pack": "build -mwl"

Mac (m) 과 Windows (w) 와 Linux (l)의 APP으로 패키지화 합니다.

 

우리가 이 명령문을 실행하기 전에 우리는 Eelectron Builder의 설정 방법을 알아야 합니다.

 

 

4. package.json파일에 아래의 내용을 추가합니다. 

"author": {
  "name": "Your Name",
  "email": "your.email@domain.com",
  "url": "https://your-website.com"
},
"build": {
  "appId": "com.my-website.my-app",
  "productName": "MyApp",
  "copyright": "Copyright © 2019 ${author}",
  "mac": {
    "category": "public.app-category.utilities"
  },
  "files": [
    "build/**/*",
    "node_modules/**/*"
  ],
  "directories": {
    "buildResources": "assets"
  }
}

 

Electron Builder 옵션이 궁금하면 아래 링크를 클릭해 보세요.

https://www.electron.build/configuration/configuration

 

그리고 우리는 우리 app의 icons을 추가하기 위해서 assets 라는 디렉토리를 만들어 사용하면 됩니다.

"directories": {
   "buildResources": "assets",
}

아이콘을 포멧이 궁금하면 아래 링크를 클릭해 보세요.

https://www.electron.build/icons

 

 아래는 제가 테스트 하면서 만든 package.json 파일입니다.

{
  "name": "chiro-20200108",
  "version": "0.1.0",
  "private": true,
  "homepage": "./",
  "main": "public/electron.js",
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "electron-is-dev": "^1.1.0",
    "path": "^0.12.7",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-scripts": "3.3.0"
  },
  "scripts": {
    "start": "rescripts start",
    "build": "rescripts build",
    "test": "rescripts test",
    "eject": "rescripts eject",
    "electron-dev": "concurrently \"BROWSER=none yarn start\" \"wait-on http://localhost:3000 && electron .\"",
    "postinstall": "electron-builder install-app-deps",
    "preelectron-pack": "yarn build",
    "electron-pack": "electron-builder build  -mwl",
    "install:osx": "electron-builder build  --mac",
    "install:linux": "yarn install:linux32 && yarn install:linux64",
    "install:linux32": "electron-builder build  --linux --ia32=true tar.xz",
    "install:linux64": "electron-builder build  --linux --x64=true tar.xz",
    "install:win": "yarn install:win32 && yarn install:win64",
    "install:win32": "electron-builder build -w --ia32=true",
    "install:win64": "electron-builder build -w --x64=true"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@rescripts/cli": "^0.0.13",
    "@rescripts/rescript-env": "^0.0.11",
    "concurrently": "^5.0.2",
    "electron": "^7.1.7",
    "electron-builder": "^21.2.0",
    "typescript": "^3.7.4",
    "wait-on": "^3.3.0"
  },
  "author": {
    "name": "hanchiro",
    "email": "hanchiro@naver.com",
    "url": "http://www.apolo.co.kr"
  },

  "build": {
    "productName": "chiroTest20200109",
    "appId": "com.nuribot.electron.chiro.20200108",
    "copyright": "Copyright © 2019 ${author}",
    "asar": true,
    "protocols": {
         "name": "chiroTest20200109",
         "schemes": [
              "chiroTest20200109"
         ]
    },
    "files": [
      "build/**/*",
      "node_modules/**/*"
    ],
    "mac": {
         "target": [
              "default"
         ],
         "icon": "./logo512.png"
    },
    "dmg": {
         "title": "tournant",
         "icon": "./logo512.png"
    },
    "win": {
        "target": [
             "zip",
             "nsis"
         ],
         "icon": "./logo512.png"
    },
    "linux": {
         "target": [
               "AppImage",
               "deb",
               "rpm",
               "zip",
               "tar.gz"
         ],
         "icon": "./plogo512.png"
    },
    "nsis": {
         "oneClick": false,
         "allowToChangeInstallationDirectory": false,
         "installerLanguages": [
              "en_US",
              "ko_KR"
         ],
         "language": "1042"
    },
    "directories": {
         "buildResources": "build/",
         "output": "dist/",
         "app": "."
    }
  },

  "rescripts": [
    "env"
  ]
}

 

이 부분은 electron-builder의 옵션을 찾아보고서 만든 것입니다.

    "install:osx": "electron-builder build  --mac",
    "install:linux": "yarn install:linux32 && yarn install:linux64",
    "install:linux32": "electron-builder build  --linux --ia32=true tar.xz",
    "install:linux64": "electron-builder build  --linux --x64=true tar.xz",
    "install:win": "yarn install:win32 && yarn install:win64",
    "install:win32": "electron-builder build -w --ia32=true",
    "install:win64": "electron-builder build -w --x64=true"

 

 

5. 이제 app 을 패키지할 준비가 되었습니다. 아래 명령어를 실행하여 APP을 패키지화 합시다.

yarn electron-pack


이제 패키지화된 artifacts  파일들이 dist 디렉토리 아래에 저장되는 것을 확인하실 수 있습니다.

 


참고로 electron 을 빌드할 때 사용하는 tool이 여러개 있습니다.

주로 electron-builder, electron-forge, electron-packager 의 3개 정도를 사용합니다.

그 중에서 electron-builder 가 가장 많이 사용되고 있습니다.

해서 위의 예제에서도  electron-builder을 사용하여 패키지화 하였습니다.

 

electron-builder vs electron-forge vs electron-packager

 

https://www.npmtrends.com/electron-builder-vs-electron-forge-vs-electron-packager

 

electron builder vs electron forge vs electron packager | npm trends

Compare npm package download statistics over time: electron builder vs electron forge vs electron packager

www.npmtrends.com

 

 

- electron-builder

 + GitHub URL : https://github.com/electron-userland/electron-builder

 

- electron-packager

 + GitHub URL : https://github.com/electron-userland/electron-packager

 

'Electron' 카테고리의 다른 글

[Electron] 일렉트론의 구조 / Main Process / Renderer Process  (0) 2020.01.16

+ Recent posts