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