Electron: main.js ์™ธ๋ถ€์— ์ „์ž๊ฐ€ ํ•„์š”ํ•˜๋ฉด TypeError๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2016๋…„ 09์›” 22์ผ  ยท  82์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: electron/electron

  • ์ „์ž ๋ฒ„์ „: 1.3.5
  • ์šด์˜ ์ฒด์ œ: ๋ฏผํŠธ 17

์•ˆ๋…•ํ•˜์„ธ์š”

์ €๋Š” ๋‹ค๋ฅธ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ค‘์—์„œ React.js ๋ฐ babelify์™€ ํ•จ๊ป˜ Electron์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(ํ•˜๋‹จ ๋ชฉ๋ก).
์˜ˆ๋ฅผ ๋“ค์–ด ์ „์ž์˜ BrowserWindow ์— ์•ก์„ธ์Šคํ•˜๊ธฐ ์œ„ํ•ด require('electron') ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์ฝ˜์†”์— ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
index.js:4 Uncaught TypeError: fs.readFileSync is not a function

๊ทธ๋Ÿฌ๋‚˜ main.js์—์„œ const electron = require('electron'); ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋งŒํ•œ ๊ฐ€์น˜๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— watchify๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ๊ฒƒ์„ js ๋ฒˆ๋“ค๋กœ ๋ฌถ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ ๋‚ด package.json์˜ ์ „์ฒด ์ข…์†์„ฑ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

"devDependencies": {
        "axios": "^0.9.1",
        "babel-preset-es2015": "^6.6.0",
        "babel-preset-react": "^6.5.0",
        "babelify": "^7.2.0",
        "classnames": "^2.2.3",
        "electron": "^1.3.5",
        "electron-reload": "^0.2.0",
        "jquery": "^2.2.3",
        "react": "^0.14.8",
        "react-autocomplete": "^1.0.0-rc2",
        "react-dom": "^0.14.7",
        "react-sound": "^0.4.0",
        "soundmanager2": "^2.97.20150601-a"
    },
blockeneed-info โŒ

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋ฏธ๋ž˜์— ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ฝ๋Š” ์‚ฌ๋žŒ์—๊ฒŒ๋Š” require ๋Œ€์‹  window.require ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ „์ž์™€ browserify์˜ require ํ•จ์ˆ˜ ๊ฐ„์˜ ์ถฉ๋Œ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ ๊ฐ€์ง€ ๊ฐ€๋Šฅ์„ฑ์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  82 ๋Œ“๊ธ€

index.js:4 ์žกํžˆ์ง€ ์•Š์€ TypeError: fs.readFileSync๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์— index.js ์˜ 4ํ–‰์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์•„๋‹ˆ๋ฉด ์ „์ฒด ์Šคํƒ ์ถ”์ ?

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ํ”„๋กœ์ ํŠธ์˜ ๋…ธ๋“œ ๋ชจ๋“ˆ์— ์œ„์น˜ํ•œ ์ „์ž์˜ index.js๋ฅผ ์ฐธ์กฐํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์˜ ๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

var fs = require('fs')
var path = require('path')

module.exports = path.join(__dirname, fs.readFileSync(path.join(__dirname, 'path.txt'), 'utf-8'))

์ „์ฒด ์Šคํƒ ์ถ”์ ์€ React.js์™€์˜ ์ถฉ๋Œ์„ ์•”์‹œํ•ฉ๋‹ˆ๋‹ค.

Stack trace

๊ฐœ๋ฐœ์ž ๋„๊ตฌ์˜ ์ฝ˜์†” ํƒญ์—์„œ require('fs').readFileSync ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ฉ๋‹ˆ๊นŒ?

electron-prebuilt ๋…ธ๋“œ ๋ชจ๋“ˆ(๋ถ™์—ฌ๋„ฃ์€ ํŒŒ์ผ)์ด ๋‚ด์žฅ๋œ electron require๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›ํ•˜์ง€ ์•Š๋Š” ํŒจํ‚ค์ง€ ์•ฑ์—์„œ ๋๋‚˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

@nukeop ์•ฑ์„ ์–ด๋–ป๊ฒŒ ๋Ÿฐ์นญํ•˜๊ณ  ์žˆ๋‚˜์š”? `์‹œ์ž‘ ์Šคํฌ๋ฆฝํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

"scripts": {
  "start": "electron ."
}

๋…ธ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ main.js ๋ฅผ ์‹คํ–‰ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๋Š๋‚Œ์ด ๋“ญ๋‹ˆ๋‹ค.

node main.js

์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ

dev ๋„๊ตฌ์˜ ์ฝ˜์†” ํƒญ์—์„œ require('fs').readFileSync๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ฉ๋‹ˆ๊นŒ?

์ด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์งํ›„์— ์ฝ˜์†”์—์„œ require('fs').existsSync ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ํ•จ์ˆ˜ ์ •์˜๋ฅผ ์ธ์‡„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ์ „์—๋„ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์ „์ž๊ฐ€ ๋ฏธ๋ฆฌ ๋นŒ๋“œ๋œ ๋…ธ๋“œ ๋ชจ๋“ˆ(๋ถ™์—ฌ ๋„ฃ์€ ํŒŒ์ผ)์ด ๋‚ด์žฅ ์ „์ž ์š”๊ตฌ๋ฅผ ๋Œ€์‹  ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์›ํ•˜์ง€ ์•Š๋Š” ํŒจํ‚ค์ง€ ์•ฑ์—์„œ ๋๋‚˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค.

๊ณ„์†ํ•ด์„œ ํŒจํ‚ค์ง€๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฐœ๋ฐœ ์ค‘์ธ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰ ์ค‘์ธ watchify ์ธ์Šคํ„ด์Šค๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด package.json์˜ ์Šคํฌ๋ฆฝํŠธ ์„น์…˜์—์„œ ์ •์˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

"watch": "watchify app/app.js -t babelify -o public/js/bundle.js --debug --verbose"

electron-prebuilt ๋ฒˆ๋“ค์„ ํ”ผํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์กฐ์–ธ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@nukeop Electron ์ง€์›์€ ๋‚ด๋ถ€์ ์œผ๋กœ ํ•„์š”ํ•˜๋ฏ€๋กœ browserify๋ฅผ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋‚ด๊ฐ€ ์•„๋Š” ํ•œ Browserify๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด "์ „์ž"๋ฅผ ์ œ์™ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํฅ๋ฏธ๋กญ์Šต๋‹ˆ๋‹ค. watchify/browserify๊ฐ€ ์ด๊ฒƒ์„ ๋ง์น  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์ง€๊ธˆ๊นŒ์ง€ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ์€ ๊ทธ๊ฒƒ ์—†์ด ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ง ๊ทธ๋Œ€๋กœ ๊ทธ๋ƒฅ ์‹คํ–‰

electron .

Electron์€ ๋‚ด๋ถ€์ ์œผ๋กœ ์ „์ฒด ๋…ธ๋“œ ํ™˜๊ฒฝ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ ์•ฑ ํด๋”์—์„œ ์•„๋ฌด ๊ฒƒ๋„ ๋ฒˆ๋“คํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

_Browserify ๋ฌธ์ œ์ด๋ฏ€๋กœ ์ข…๋ฃŒํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค_

๊ทธ๊ฒƒ์ด ๋‚ด๊ฐ€ ์ค„๊ณง ํ•ด์˜จ ์ผ์ด๋ฉฐ, ํ”„๋กœ๊ทธ๋žจ์„ ๋‹จ์ผ .js ํŒŒ์ผ๋กœ ๋ฌถ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์€ ๋‹ค์Œ์ด ํฌํ•จ๋œ ๊ฐ„๋‹จํ•œ html ํŒŒ์ผ์— ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

  <script src="public/js/bundle.js">
  </script>

๊ทธ๋ฆฌ๊ณ  ๋‚ด๊ฐ€ require๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋ฅผ ์ œ์™ธํ•˜๊ณ  ๋ชจ๋“  ๊ฒƒ์ด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‘ ๋ชจ๋“ˆ ๊ฐ„์˜ ์ƒํ˜ธ ์ž‘์šฉ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

์ „์ฒด ํ”„๋กœ๊ทธ๋žจ์„ ๋ฒˆ๋“ค๋กœ ๋ฌถ์ง€ ์•Š์œผ๋ฉด main.js๊ฐ€ ์ „์ž๋งŒ ์‹œ์ž‘ํ•˜๊ณ  ๋ฒˆ๋“ค์„ ํฌํ•จํ•˜๋Š” html ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๋ฏ€๋กœ ์‰ฝ๊ฒŒ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

@nukeop Electron ๋‚ด๋ถ€์˜ ๋ Œ๋”๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋Š” ์ „์ฒด ๋…ธ๋“œ/commonjs ํ™˜๊ฒฝ์—๋„ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ฒˆ๋“ค๋กœ ์ œ๊ณตํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

์ „์ฒด ํ”„๋กœ๊ทธ๋žจ์„ ๋ฒˆ๋“ค๋กœ ๋ฌถ์ง€ ์•Š์œผ๋ฉด main.js๊ฐ€ ์ „์ž๋งŒ ์‹œ์ž‘ํ•˜๊ณ  ๋ฒˆ๋“ค์„ ํฌํ•จํ•˜๋Š” html ํŒŒ์ผ์„ ๋กœ๋“œํ•˜๋ฏ€๋กœ ์‰ฝ๊ฒŒ ์‹คํ–‰ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

HTML ํŒŒ์ผ์— ๋กœ๋“œํ•˜๋Š” ๋ชจ๋“  ์Šคํฌ๋ฆฝํŠธ์—๋Š” ์™„์ „ํ•œ commonjs ํ™˜๊ฒฝ์ด ์žˆ์œผ๋ฏ€๋กœ require ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €ํ™”ํ•˜์ง€ ์•Š๊ณ ๋„ ์ถ”๊ฐ€ ํŒŒ์ผ์„ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฏธ๋ž˜์— ์ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์ฝ๋Š” ์‚ฌ๋žŒ์—๊ฒŒ๋Š” require ๋Œ€์‹  window.require ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ „์ž์™€ browserify์˜ require ํ•จ์ˆ˜ ๊ฐ„์˜ ์ถฉ๋Œ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ ๊ฐ€์ง€ ๊ฐ€๋Šฅ์„ฑ์ž…๋‹ˆ๋‹ค.

FWIW, ๋‚˜๋Š” ๋ธŒ๋ผ์šฐ์ €ํ™” ๋Œ€์‹  ๋ฐฑ์—”๋“œ์—์„œ ์›นํŒฉ์„ ์‚ฌ์šฉํ•˜๋Š” create-react-app๊ณผ ํ•จ๊ป˜ ๋ Œ๋”๋Ÿฌ ํ”„๋กœ์„ธ์Šค์—์„œ ์ „์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ์‹œ๋„ํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•œ ๋ฌธ์ œ์— ๋ถ€๋”ช์ณค์Šต๋‹ˆ๋‹ค. window.require ์ด์œ ๋Š” ํ™•์‹คํ•˜์ง€ ์•Š์ง€๋งŒ ์ €์—๊ฒŒ๋„ ํ•ด๊ฒฐ๋˜๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

ํŽธ์ง‘ : ์ด์œ ๋ฅผ ์•Œ์•„ ๋ƒˆ์Šต๋‹ˆ๋‹ค :-) webpack์—์„œ ์ปดํŒŒ์ผํ•˜๋Š” ๋™์•ˆ ์‚ฌ์šฉํ•˜๋Š” nodejs ํ™˜๊ฒฝ์ด ์•„๋‹ˆ๋ผ ๋Ÿฐํƒ€์ž„์— ์ œ๊ณต๋˜๋Š” nodejs ํ™˜๊ฒฝ์—์„œ ๋Ÿฐํƒ€์ž„ ์ค‘์— require electron ๋ฅผ ์›ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ „์—ญ์€ window ์— ๋ฐ”์ธ๋”ฉ๋˜๊ณ  webpack ์ปดํŒŒ์ผ์€ window ์ „์—ญ์„ ๋ฌด์‹œํ•˜๋ฏ€๋กœ window.require ๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

webpack์— ์ „์—ญ ์ด๋ฆ„์„ ๋ฌด์‹œํ•˜๋„๋ก ์ง€์‹œํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ JS ํŒŒ์ผ์—์„œ /*global Android*/ ์™€ ๊ฐ™์€ ์ฃผ์„์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Android WebView์—์„œ CRA ๋นŒ๋“œ ์•ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” Webview์—์„œ ์ œ๊ณตํ•˜๋Š” JavaScript ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด JS์— ๋…ธ์ถœ๋œ Java ๊ฐ์ฒด์— ์•ก์„ธ์Šคํ•˜๊ธฐ ์œ„ํ•ด ์œ„์˜ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

@nukeop - ๋งˆ์ง€๋ง‰ ๊ฒŒ์‹œ๋ฌผ์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋งŽ์€ ๋„์›€์ด ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. window.require ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค.

๋„ค, ๋ฐ˜์‘ ์•ฑ ์ƒ์„ฑ/์›นํŒฉ ๋ฌธ์ œ๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
๋ณ€ํ™”

import electron, { ipcRenderer } from 'electron'

์—๊ฒŒ

const electron = window.require("electron")

@srinathh CRA ์•ฑ์„ ๋ฉ”์ธ์—์„œ ๋ Œ๋”๋Ÿฌ๋กœ ์–ด๋–ป๊ฒŒ ๋…ธ์ถœ/๋กœ๋“œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? ๋‹น์‹ ์ด ๋จผ์ € ๊ตฌ์ถ•ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ (๊ทธ๋ฆฌ๊ณ  html ์ •์  ๋ฆฌ์†Œ์Šค ๊ฒฝ๋กœ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ)

์˜ˆ, ํ˜„์žฌ ๋‚ด ์ž‘์—… ํ๋ฆ„์€ ๊ธฐ๋ณธ์ ์œผ๋กœ CRA ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ npm run build ๋ฅผ ์‹คํ–‰ํ•œ ๋‹ค์Œ ์ „์ž๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ build ํด๋”์—์„œ ์ถœ๋ ฅ์„ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ˆ˜๋™์œผ๋กœ ์ •์  ๋ฆฌ์†Œ์Šค ๊ฒฝ๋กœ๋ฅผ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. package.json for CRA ์Šคํฌ๋ฆฝํŠธ์—์„œ ์ด๋ ‡๊ฒŒ homepage ์„ค์ •ํ•˜๋ฉด ๊ฒฝ๋กœ๊ฐ€ ์ ์ ˆํ•˜๊ฒŒ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

    "homepage": "./"

๋˜ํ•œ public ํด๋”์— ์ „์ž ์•ฑ์šฉ main.js ๋ฐ package.json ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋นŒ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ณต์‚ฌ๋˜๊ณ  electron build/ ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์•ฑ์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ์‹ค์ œ๋กœ ๊ฐœ๋ฐœ์„ ์œ„ํ•ด ์ „์ž๋กœ npm start ๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•˜์ง€๋งŒ ๊ทธ ์ผ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋‚ด์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. eject ํ•˜๊ณ  ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์†์œผ๋กœ ์ˆ˜์ •ํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์„ค์ •์˜ ์˜ˆ๋ฅผ ๋ณด๋ ค๋ฉด https://github.com/srinathh/snippetfu ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

์ €๋Š” Electron์ด ์•„๋‹ˆ๋ผ Node-Webkit(nw.js)์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
window.require ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋‚ด ๋ฌธ์ œ๋„ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋Œ€๋‹จํžˆ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

@nukeop window.require ์ €๋„ ์ž˜ํ•ด์คฌ์Šต๋‹ˆ๋‹ค ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค! ๐ŸŽ‰

@nukeop ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์ง€๋งŒ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค window.require ํŠธ๋ฆญ, ์ •๋ง ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!

window.require ๋Š” fs.existsSync is not a function ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ์ง€๋งŒ ๋˜ ๋‹ค๋ฅธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. window.require ๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ• ๊นŒ์š”?

@steric85 browserify , babel ๋˜๋Š” webpack์„ ์‚ฌ์šฉ ์ค‘์ด์‹ ๊ฐ€์š”? ์ฝ”๋“œ๋ฅผ ๋ณ€ํ™˜ํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

@Alxmerino ์›นํŒฉ ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธ

@steric85 , ๋‚˜๋Š” typescript์—์„œ window.require is not a function ์— ์ง๋ฉดํ–ˆ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.

declare global {
  interface Window {
    require: any;
  }
}

const electron = window.require('electron');

๋‚ด Angular ์•ฑ์˜ ์ „์ž์—์„œ ipcRenderer์— ์•ก์„ธ์Šคํ•˜๊ธฐ ์œ„ํ•ด ์œ„์˜ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋งŒ ipcRenderer ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Observable์„ ์—…๋ฐ์ดํŠธํ•  ๋•Œ ๊ฐ๋„ ๋ณ€๊ฒฝ ๊ฐ์ง€๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
Angular๊ฐ€ ipcRenderer๊ฐ€ EventEmitter์ด๊ณ  ipcRenderer ์ด๋ฒคํŠธ๊ฐ€ ๋“ค์–ด์˜ฌ ๋•Œ ๋ณ€๊ฒฝ ๊ฐ์ง€๋ฅผ ์‹คํ–‰ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๊นŒ?

Angular 2์—์„œ๋Š” applicationRef.tick() ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ Angular์— ์ƒํƒœ๋ฅผ ์ƒˆ๋กœ ๊ณ ์น˜๋„๋ก ๋ช…์‹œ์ ์œผ๋กœ ์ง€์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. https://angular.io/api/core/ApplicationRef

@nukeop ๋ฐ @srinathh ์™€ ๋งค์šฐ ์œ ์‚ฌํ•œ ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ์‚ฌ ๊ฐ€์ด๋“œ์— ๋”ฐ๋ผ Electron + React + Webpack ํ”„๋กœ์ ํŠธ๋ฅผ ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์— ์ž‘์„ฑ์ž๊ฐ€ window.require ๋กœ ํŠธ๋ฆญ์„ ์–ธ๊ธ‰ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ํ”„๋กœ์ ํŠธ์— require('electron') ๋‘ ๊ณณ๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค. Electron์˜ ์ง„์ž…์ ๊ณผ ์ผ๋ถ€ React ๊ตฌ์„ฑ ์š”์†Œ์— ํ•„์š”ํ•œ JavaScript ์ปจํŠธ๋กค๋Ÿฌ ํด๋ž˜์Šค์— ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด Electron ์ง„์ž…์  ํŒŒ์ผ์—์„œ๋Š” ๋‹จ์ˆœํžˆ const electron = require('electron'); ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์ธ ํ”„๋กœ์„ธ์Šค์—์„œ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค(๋งž๋‚˜์š”?), ์ปจํŠธ๋กค๋Ÿฌ ํด๋ž˜์Šค์—์„œ const Electron = window.require('electron').remote; ๋‹ค์Œ์— const Jsonfile = Electron.require('jsonfile'); , ์ด๋Š” ๋ Œ๋”๋Ÿฌ ํ”„๋กœ์„ธ์Šค์—์„œ ์‹คํ–‰ ์ค‘์ด๋ฏ€๋กœ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋‹ค์Œ๊ณผ ๊ฐ™์€ node_modules/electron/index.js์˜ 6๋ฒˆ์งธ ์ค„์—์„œ @nukeop ("TypeError: fs.ExistsSync๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค")๊ณผ ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

var fs = require('fs')
var path = require('path')

var pathFile = path.join(__dirname, 'path.txt')

if (fs.existsSync(pathFile)) {
  module.exports = path.join(__dirname, fs.readFileSync(pathFile, 'utf-8'))
} else {
  throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again')
}

node_modules/electron์„ ์‚ญ์ œํ•˜๊ณ  ๋‹ค์‹œ ์„ค์น˜๋ฅผ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ €๋Š” macOS 10.12.6์—์„œ Electron 1.7.5๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๊ธฐ์‚ฌ์˜ ์„ค์ •์œผ๋กœ npm run dev ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ; ๋‚ด ์˜ค๋ฅ˜๋ฅผ ์ผ์œผํ‚จ require ์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค. React index.js์—์„œ require('electron-react-devtools') ๋ฅผ ์‹œ๋„ํ–ˆ์Šต๋‹ˆ๋‹ค. const ReactDevtools = Electron.require('electron-react-devtools'); ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ์ค‘์ง€๋˜์—ˆ์ง€๋งŒ ์ด์ œ๋Š” ReactDevtools ์ธ์Šคํ„ด์Šค์—์„œ .inject() ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค("ํ•จ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค"). ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์„œ ๋…ผ์˜ํ•  ๋‚ด์šฉ์ด ์•„๋‹ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. .

@steric85 ์›นํŽ˜์ด์ง€ ํ™˜๊ฒฝ์—์„œ ์•ฑ์„ ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค => Electron ํ™˜๊ฒฝ(Nodejs ํ™˜๊ฒฝ)์—์„œ ์•ฑ์„ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

  • require('electron') => Webpack์€ ์ „์ž ๋ชจ๋“ˆ์„ bundle.js์— ๋ฌถ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค => electron์€ fs ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค => Webpack์€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค
  • window.require('electron') => Webpack์€ ํ•„์ˆ˜ ๊ธฐ๋Šฅ์„ ๋ฌด์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ์›น ํŽ˜์ด์ง€ ํ™˜๊ฒฝ์—์„œ window.require๋Š” ์ •์˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • nodejs ํ™˜๊ฒฝ์—์„œ๋Š” window.require๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.
    => Electron ์ฐฝ์—์„œ ์•ฑ์„ ์—ฝ๋‹ˆ๋‹ค(Chrome, Firefox ๋“ฑ๊ณผ ๊ฐ™์€ ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์ด ์•„๋‹Œ

๋‚˜๋Š” ์—ฌ์ „ํžˆ window.require is not a function ๋ฐ›๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” React Starter Kit(https://github.com/kriasoft/react-starter-kit)์™€ ํ•จ๊ป˜ Electron์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ์ œ์™ธํ•˜๊ณ ๋Š” ๋ชจ๋“  ๊ฒƒ์ด ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

์›น์—์„œ ์•ฑ์„ ๋กœ๋“œํ•˜๋„๋ก Electron ์•ฑ์„ ์„ค์ •ํ–ˆ์œผ๋ฏ€๋กœ ์•ฑ์ด ๋กœ์ปฌ์—์„œ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
https://gist.github.com/holgersindbaek/68f6db82f507967a51ca75c527faeff6

๋‚ด๊ฐ€ํ•˜๋ ค๋Š” ๊ฒƒ์€ ๋‚ด React ํŒŒ์ผ ์ค‘ ํ•˜๋‚˜์—์„œ ipcRenderer ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‚ด ์•ฑ์ด ์›น์—์„œ ๋กœ๋“œ๋  ๋•Œ๋„ ๊ฐ€๋Šฅํ•œ์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ์ œ์•ˆ?

@holgersindbaek ํฌ๋กฌ, ํŒŒ์ด์–ดํญ์Šค ๋“ฑ์˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์•ฑ์„ ๋ณด๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค. ์›นํŽ˜์ด์ง€ ํ™˜๊ฒฝ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
Electron ์ฐฝ์—์„œ ์•ฑ์„ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” ๊ทธ๋ ‡์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์–ด๋–ค ์‹์œผ๋กœ๋“  Electron์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ ์‹คํ–‰ ์‹œ ์›น์‚ฌ์ดํŠธ์—์„œ ์•ฑ์„ ๋กœ๋“œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ „์ž ์•ฑ์— ์›น์‚ฌ์ดํŠธ๋ฅผ ํ‘œ์‹œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„ ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜์„ธ์š”. ์ •๋ง ๋‚ด๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š” ์ผ์ด ์—†๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์„ ๋ฟ์ด์•ผ?!

Electron์€ ๋ชจ๋“  URL์„ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. URL์„ ๋กœ๋“œํ•˜๋ ค๋ฉด ์ด ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. mainWindow.loadURL(url)
=> ์ „์ž ์ฐฝ ๋ณด๊ธฐ์—์„œ ํ•ด๋‹น URL ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋Š” require, ipc ๋“ฑ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ™•์ธ. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ์‹œ๋„ํ•  ๊ฒƒ์ด๋‹ค.

์ „์ž์˜ window.require ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ window.require ์— ๋Œ€ํ•œ fs ๋Š” ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด์œ ๋Š” ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๊ฒƒ์€ ์ž‘๋™ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ž‘์€ ๊ฐœ์ธ ํ”„๋กœ์ ํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๋ฅผ ํ‘ธ์‹œํ•˜์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

@nukeop ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

์•ˆ๋…•ํ•˜์„ธ์š”, ์ด๊ฒƒ์€ ๋‚ด package.json์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” webpack์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ๋“ค ์ค‘ ์–ด๋Š ๊ฒƒ๋„ ๋‚ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๋„ ํ•ด๊ฒฐ์ฑ…์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ? window.require๋ฅผ ์‚ฌ์šฉํ•œ ํ›„ "window is not defined" ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

'์—„๊ฒฉํ•œ ์‚ฌ์šฉ';

var ์ „์ž = ํ•„์š”('์ „์ž')
var ์•ฑ = ์ „์ž.์•ฑ;
var BrowserWindow = ์ „์ž.BrowserWindow;
var ๋ฉ”์ธ ์ฐฝ = null;

app.on('์ค€๋น„', function() {
mainWindow = new BrowserWindow({๋„ˆ๋น„: 800, ๋†’์ด: 600});

mainWindow.loadURL('file://' + __dirname + '/index.electron.html');

mainWindow.webContents.openDevTools();

});

๋‚˜๋Š” typescript๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์‚ฌ์šฉํ•ด์•ผํ–ˆ์Šต๋‹ˆ๋‹ค.

const electron = (<any>window).require("electron");

๋‚ด ๋ Œ๋”๋Ÿฌ๊ฐ€ ๋‚ด ๋ฉ”์ธ๊ณผ ํ†ต์‹ ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์ด ๋ˆ„๊ตฐ๊ฐ€๋ฅผ ๋•๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ์›๊ฒฉ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ

const ์ฐฝ ์„ ์–ธ: ๋ชจ๋‘;
const { ์›๊ฒฉ } = window.require('์ „์ž');

์•ˆ๋…•ํ•˜์„ธ์š”, ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

2017๋…„ 12์›” 3์ผ ์ผ์š”์ผ ์˜คํ›„ 9์‹œ 29๋ถ„, Michael - แˆšแŠซแŠคแˆ แˆฐแˆแŒ 
[email protected]>์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ผ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ์›๊ฒฉ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ

const ์ฐฝ ์„ ์–ธ: ๋ชจ๋‘;
const { ์›๊ฒฉ } = window.require('์ „์ž');

โ€”
๋‹น์‹ ์ด ๋Œ“๊ธ€์„ ๋‹ฌ์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๊ฒƒ์„ ๋ฐ›๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด ์ด๋ฉ”์ผ์— ์ง์ ‘ ๋‹ต์žฅํ•˜๊ณ  GitHub์—์„œ ํ™•์ธํ•˜์„ธ์š”.
https://github.com/electron/electron/issues/7300#issuecomment-348801405 ,
๋˜๋Š” ์Šค๋ ˆ๋“œ ์Œ์†Œ๊ฑฐ
https://github.com/notifications/unsubscribe-auth/ARDyd4c3aOkMbb058xklujMMbnmaoxKGks5s8uGVgaJpZM4KDU6t
.

@solominh ์—ฌ๊ธฐ ์— ์„ค๋ช…ํ•ด์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ @holgersindbaek ๊ณผ ์œ ์‚ฌํ•œ ๊ตฌ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ํ™˜๊ฒฝ์ด webview์—์„œ ์‚ฌ์ „ ๋กœ๋“œ ์Šคํฌ๋ฆฝํŠธ์ž…๋‹ˆ๊นŒ?

์ •๋ณด:

  • ๋‚ด ์ „์ž ํ•ญ๋ชฉ์€ mainWindow.loadURL(url) ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ url์€ ๋กœ์ปฌ index.html์ž…๋‹ˆ๋‹ค.
  • ์ด index.html์—๋Š” <webview> ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  • webview์—๋Š” injection.js๋ฅผ ๋กœ๋“œํ•˜๋Š” preload ํ•„๋“œ๊ฐ€ ์žˆ์œผ๋ฉฐ ์ด ์Šคํฌ๋ฆฝํŠธ๋Š” window.require('electron')๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๋น„๊ณ :

  • const electron = require('electron') ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด fs.readFileSync is not a function ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  • const electron = window.require('electron') ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด window.require is not a function ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
  • injection.js๋Š” webpack์„ ํ†ตํ•ด ๋ฒˆ๋“ค๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค(ํ•ด๋‹น๋˜๋Š” ๊ฒฝ์šฐ ๊ตฌ์„ฑ์„ ๋ถ™์—ฌ๋„ฃ์„ ์ˆ˜ ์žˆ์Œ).

ํŽธ์ง‘: <webview nodeintegration="true"> ๋ฐ window.require๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์ค‘์— ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋„๋ก ์—ฌ๊ธฐ์— ๋ฉ”๋ชจ๋ฅผ ๋‚จ๊น๋‹ˆ๋‹ค.

window.require๊ฐ€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค! ๊ณ ๋งˆ์›Œ ์–˜๋“ค์•„!

https://imgur.com/a/ekWwD

๋‚ด๊ฐ€ ์ด๊ฒƒ์„ ์‹œ๋„ํ–ˆ์„ ๋•Œ ๋ธŒ๋ผ์šฐ์ €์˜ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€

window.require().. ๋„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” nodeIntegration: false ๋˜๋Œ๋ฆฌ๋Š” ๊ฒƒ์„ ์žŠ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฉ์ฒญํ•œ ์‹ค์ˆ˜. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํ•œ ์‹œ๊ฐ„ ๋™์•ˆ ์—ฐ๊ตฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@phil294 ๊ณ ๋งˆ์›Œ์š”! ์กฐ์‚ฌํ•˜๋Š” ๋ฐ ํ•œ ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ–ˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @micsel ์ž…๋‹ˆ๋‹ค .
๋‚˜๋Š” ์„ ์–ธ const ์ฐฝ์„ ํฌํ•จํ–ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ๊ตฌ๋ฌธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
์–ด๋–ค ์•„์ด๋””์–ด๊ฐ€ ์žˆ์Šต๋‹ˆ๊นŒ?

์˜ˆ, ์„ ์–ธ const ์ฐฝ์„ ๋„ฃ์Šต๋‹ˆ๋‹ค. ์ƒ๋‹จ, ์ˆ˜์ž…ํ’ˆ์ด ์žˆ๋Š” ๋ฐ”๋กœ ๋’ค์— ์žˆ์Šต๋‹ˆ๋‹ค.

window.require๊ฐ€ ํ•จ์ˆ˜๊ฐ€ ์•„๋‹ˆ๊ณ  Angular-CLI๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ Window ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•ฉ๋‹ˆ๋‹ค.

./src/typings.d.ts

declare var window: Window;
interface Window {
    require: any;
}

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ „์ž๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
const { ipcRenderer } = window.require('electron');

์ „์ž ์•ฑ์—์„œ ๊ฐ๋„ 2+๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ "ngx-electron" lib๋ฅผ ๊ฐ€์ ธ์™€์„œ any.componets.ts์—์„œ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

import { ElectronService } from 'ngx-electron';

//constructor
constructor(
    private elt: ElectronService
  ){
  var fs = this.elt.remote.require('fs');
}

๋‚˜๋Š” ์ „์ž์™€ ํ•จ๊ป˜ ๋ฐ˜์‘ js๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ์ด ์ค„์„ ํ„ฐ๋ฏธ๋„ ์›์‚ฌ ์‹คํ–‰ ์‹œ์ž‘์— ์‹คํ–‰ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. Uncaught Type Error: window.require is not a function ๋‚ด๊ฐ€ typescript๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์–ด๋–ป๊ฒŒ React Js์—์„œ ์ฐฝ์„ ์„ ์–ธํ•ฉ๋‹ˆ๊นŒ?

์—ฌ์ „ํžˆ ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์€ ์–ด๋–ป๊ฒŒ๋“  window.require() ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ์ฝ”๋“œ๋ฒ ์ด์Šค ์ „์ฒด์—์„œ import ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋Š” ์ผ๊ด€์„ฑ์„ ๋ง์นฉ๋‹ˆ๋‹ค. ์‰ฌ์šด ๋Œ€์•ˆ์€ webpack target ์„ electron-renderer ๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Create React App ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๊บผ๋‚ด๊ธฐ๊ฐ€ ์—‰๋ง์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์›นํŒฉ ํ›„ํ‚น์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ด ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์˜ˆ๋ฅผ ๋“ค์–ด React ๊ตฌ์„ฑ ์š”์†Œ(๋˜๋Š” ๋‹ค๋ฅธ ๋…ธ๋“œ ๋ชจ๋“ˆ)์—์„œ import fs from 'fs' ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Vue CLI 3์ด ์žˆ๋Š” ์ฐฝ์—์„œ window.require๋Š” ์ž‘๋™ํ•˜์ง€๋งŒ "node_modules/"์˜ ์ƒ๋Œ€ ๊ฒฝ๋กœ ๋Œ€์‹  ์ „์ฒด ๊ฒฝ๋กœ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ React์˜ ๊ฒฝ์šฐ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ vue.config.js๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ Vue์— ๋งž๊ฒŒ webpack์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด "require"๊ฐ€ ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

vue.config.js:

module.exports = {
    configureWebpack: config => {
      if (process.env.NODE_ENV === 'production') {
        config.output.publicPath = `${process.cwd()}/dist/`
      }
      config.target = 'electron-renderer'
    }
  }

router.js(์ด๊ฒƒ์€ ๋‹จ์ง€ ์˜ˆ์ผ ๋ฟ์ด๋ฉฐ ๋‹ค๋ฅธ ๋ชจ๋“  vue js ํŒŒ์ผ์—์„œ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค)

const Store = require("electron-store");
const store = new Store();

_๋‚˜๋Š” ์ด๊ฒƒ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์ง€๋งŒ ๋””๋ฒ„๊น…ํ•˜๋Š” ๋ฐ ํ•œ๋‘ ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค._

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด rm -rf node_modules && npm install ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ window.require window ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ  ์ž‘์—…์ด ๋‹ค์‹œ ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋ผ๊ฑด๋Œ€ ๊ทธ๊ฒƒ์ด ๋‹ค๋ฅธ ๋ˆ„๊ตฐ๊ฐ€๋ฅผ ๋•๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@cperthuis ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!! ใ…Žใ…Ž ์ €๋Š” Vue๋„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์žˆ์ง€๋งŒ ๋…ผ๋ฆฌ์ ์ธ ์ƒ๊ฐ์œผ๋กœ webpack.config.js๋ฅผ ๋Œ€์ƒ ์†์„ฑ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. :)
image
๋งค๋ ฅ์ฒ˜๋Ÿผ ์ผํ–ˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•,

window.require ๋Š” ๊ฐœ๋ฐœ ๋กœ์ปฌ ์„œ๋ฒ„ ํ™˜๊ฒฝ์—์„œ ์ž‘๋™ํ•˜์ง€๋งŒ ์ถ•์†Œ๋œ HTML ํŒŒ์ผ์— React ์•ฑ์„ ๋นŒ๋“œํ•œ ํ›„ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

function createWindow() {
  win = new BrowserWindow({
    width: 1280,
    height: 720,
    icon: path.join(__dirname, 'assets/icons/png/64x64.png'),
    webPreferences: {
      nodeIntegration: true,
      preload: __dirname + '/preload.js'
    }
  })

  win.setPosition(0, 0)

  win.loadURL(isDev ? 'http://localhost:3000' : `file://${path.join(__dirname, 'build/index.html')}`)
}

localhost:3000 ์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€๋งŒ file://${path.join(__dirname, 'build/index.html')} ์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

https://imgur.com/EE7jxZq

@cperthuis , 'react-app-rewired'๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊บผ๋‚ด์ง€ ์•Š์€ CRA ์•ฑ์—์„œ ์ˆ˜์ • ์‚ฌํ•ญ์ด ์ž‘๋™ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌ ํ•ด์š”.
image

Create-React-App 2์—์„œ๋Š” craco npm ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://www.npmjs.com/package/@craco/craco

package.json์—์„œ craco react-scripts ๋ณ€๊ฒฝ

craco.config.js

module.exports = {
    webpack: {
        configure: {
            target: 'electron-renderer'
        }
    }
};

๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด Electron ์ปจํ…์ŠคํŠธ์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import Electron from 'electron';
const { dialog } = Electron.remote;

@Maxou44 craco & electron์— ๋Œ€ํ•œ ์ •๋ณด ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‚ด๊ฐ€ ํ•„์š”๋กœ ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ์˜ˆ๋ฅผ ์ฐพ๊ณ  ์žˆ๋‹ค๋ฉด ...

https://github.com/wwlib/cra-craco-electron-example

@wwlib ๋ฌธ์ œ์—†์Šต๋‹ˆ๋‹ค. ๋„์›€์ด ๋˜์…จ๋‹ค๋‹ˆ ๋‹คํ–‰์ž…๋‹ˆ๋‹ค ๐Ÿฅณ

window.require().. ๋„ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” nodeIntegration: false ๋˜๋Œ๋ฆฌ๋Š” ๊ฒƒ์„ ์žŠ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฉ์ฒญํ•œ ์‹ค์ˆ˜. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํ•œ ์‹œ๊ฐ„ ๋™์•ˆ ์—ฐ๊ตฌํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ •๋ง ๊ณ ๋ง™์Šต๋‹ˆ๋‹ค.

์›๊ฒฉ ์ฝ˜ํ…์ธ ๋ฅผ ๋กœ๋“œํ•˜๋Š” ๊ฒฝ์šฐ nodeIntegration ๋ฅผ false๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. https://electronjs.org/docs/tutorial/security#2 -disable-nodejs-integration-for-remote -์ฝ˜ํ…์ธ 

์•ˆ๋…•,
๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. window.require๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ Uncaught TypeError: fs.readFileSync is not a function ์˜ค๋ฅ˜๊ฐ€ ์ˆ˜์ •๋˜์—ˆ์ง€๋งŒ Uncaught TypeError: window.require is not a function ๋˜ ๋‹ค๋ฅธ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๊นŒ? ๋…ธ๋“œ js์—์„œ browserify๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

$ BrowserWindow ๋ฅผ ์„ ์–ธํ•  ๋•Œ nodeIntergation ๋ฅผ true $๋กœ ๋ช…์‹œ์ ์œผ๋กœ ์„ ์–ธํ•˜์ง€ ์•Š๋Š” ํ•œ window.require is not a function ์˜ค๋ฅ˜๊ฐ€ ๊ณ„์† ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
    }
});

๋‚ด๊ฐ€ ์ฐพ์€ ์œ ์ผํ•œ ํ•ด๊ฒฐ์ฑ… ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ๊ฐœ๋ฐœ ์ข…์†์„ฑ react-app-rewired ํŒจํ‚ค์ง€๋กœ ์„ค์น˜
  2. CRA๋ฅผ eject ์—†์ด ์‚ฌ์šฉ์ž ์ •์˜ Webpack ๊ตฌ์„ฑ์„ ์‚ฝ์ž…ํ•˜๋ ค๋ฉด ์ด ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.
 "scripts": {
   ...
    "start": "react-app-rewired start",
  },
  1. ๋‹ค์Œ ๋‚ด์šฉ๊ณผ ํ•จ๊ป˜ config-overrides.js ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
module.exports = function override (config, env) {
  config.target = 'electron-renderer'
  return config;
}

@Lilanga comment , @agrublev comment ๋ฐ react-app- rewired ์ œ์ž‘์ž ๋•๋ถ„์ž…๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ๋จ:
์‹ค์ œ๋กœ ๋™์ผํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์˜ ๋‘ ๋ฒˆ์งธ ๋ฒ„์ „: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

์—…๋ฐ์ดํŠธ๋จ2:
@nukeop Browserify ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ  ๋˜๋Š” ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•œ ํ† ๋ก ์„ ๋”ฐ๋ฅผ ์‹œ๊ฐ„์ด ๋ถ€์กฑํ•˜์—ฌ ์˜คํ•ด์˜ ์†Œ์ง€๊ฐ€ ์žˆ๋Š” ์ผ๋ถ€ ์ง„์ˆ ์„ ์‚ญ์ œํ–ˆ์œผ๋ฉฐ ์ง€๊ธˆ ๋‚ด๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๋ฐ”์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์„ ์ž‘์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ " window.require ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋œ๋‹ค"๋Š” ๊ฒƒ์ด ๋งค์šฐ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค๋Š” ๊ฐœ์ธ์ ์ธ ๊ฒฌํ•ด๋ฅผ ์œ ์ง€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ž˜๋ชป๋œ ๋ฐฉ๋ฒ•?

Electron ํ™˜๊ฒฝ ๋‚ด์—์„œ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” React ์•ฑ์ž…๋‹ˆ๋‹ค. ๊ทธ ๋ฐ˜๋Œ€์˜ ๊ฒฝ์šฐ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

๋ญ?

_๋‚˜๋Š” ์ด๊ฒƒ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์ง€ ์•Š์ง€๋งŒ ๋””๋ฒ„๊น…ํ•˜๋Š” ๋ฐ ํ•œ๋‘ ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค._

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด rm -rf node_modules && npm install ํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ window.require window ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์—ˆ๊ณ  ์ž‘์—…์ด ๋‹ค์‹œ ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋ผ๊ฑด๋Œ€ ๊ทธ๊ฒƒ์ด ๋‹ค๋ฅธ ๋ˆ„๊ตฐ๊ฐ€๋ฅผ ๋•๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์™€์šฐ.. ์ด ์Šค๋ ˆ๋“œ์—์„œ ๋ชจ๋“  ๊ฒƒ์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์ถ”์ฒœ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์‹œ ๋ณด๊ธฐ๋ฅผ ๋†“์ณค์Šต๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ window is not a function ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.
node_modules ๋ฐ ์ž‘๋™์„ ์ œ๊ฑฐํ•˜๊ณ  ๋‹ค์‹œ ์„ค์น˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ถ”์‹ : ์—ฌ์ „ํžˆ ๋ชจ๋“  ์†”๋ฃจ์…˜์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜์ง€๋งŒ ๋ชจ๋“  ์ž‘์—…์„ ์ˆ˜ํ–‰ํ–ˆ๋‹ค๋ฉด
์—ฌ์ „ํžˆ ๋™์ผํ•œ ์žฌ์„ค์น˜ node_modules

๋‹น์‹ ์€ ๋‚˜์˜ ํ•˜๋ฃจ๋ฅผ ๊ตฌํ–ˆ์Šต๋‹ˆ๋‹ค @joshuapinter !

react-create-app์„ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผํ•œ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.
์ง€๊ธˆ๊นŒ์ง€์˜ ์†”๋ฃจ์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
const electron = window.require("electron") ์ „์ž ๋ถ€๋ถ„ BrowserWindow ์— nodeIntegration:true ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
mainWindow = new BrowserWindow({ width: 900, height: 680, webPreferences: { webSecurity: false, nodeIntegration: true } });

๋‚ด๊ฐ€ ์ฐพ์€ ์œ ์ผํ•œ ํ•ด๊ฒฐ์ฑ… ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ๊ฐœ๋ฐœ์ž ์ข…์†์„ฑ react-app-rewired ํŒจํ‚ค์ง€๋กœ ์„ค์น˜
  2. CRA๋ฅผ eject ์—†์ด ์‚ฌ์šฉ์ž ์ •์˜ Webpack ๊ตฌ์„ฑ์„ ์‚ฝ์ž…ํ•˜๋ ค๋ฉด ์ด ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.
 "scripts": {
   ...
    "start": "react-app-rewired start",
  },
  1. ๋‹ค์Œ ๋‚ด์šฉ๊ณผ ํ•จ๊ป˜ config-overrides.js ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
module.exports = function override (config, env) {
  config.target = 'electron-renderer'
  return config;
}

@Lilanga comment , @agrublev comment ๋ฐ react-app- rewired ์ œ์ž‘์ž ๋•๋ถ„์ž…๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ๋จ:
์‹ค์ œ๋กœ ๋™์ผํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์˜ ๋‘ ๋ฒˆ์งธ ๋ฒ„์ „: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

์—…๋ฐ์ดํŠธ๋จ2:
@nukeop Browserify ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ  ๋˜๋Š” ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ด์œ ์— ๋Œ€ํ•œ ํ† ๋ก ์„ ๋”ฐ๋ฅผ ์‹œ๊ฐ„์ด ๋ถ€์กฑํ•˜์—ฌ ์˜คํ•ด์˜ ์†Œ์ง€๊ฐ€ ์žˆ๋Š” ์ผ๋ถ€ ์ง„์ˆ ์„ ์‚ญ์ œํ–ˆ์œผ๋ฉฐ ์ง€๊ธˆ ๋‚ด๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๋ฐ”์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์„ ์ž‘์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ " window.require ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋œ๋‹ค"๋Š” ๊ฒƒ์ด ๋งค์šฐ ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค๋Š” ๊ฐœ์ธ์ ์ธ ๊ฒฌํ•ด๋ฅผ ์œ ์ง€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚˜๋ฅผ ์œ„ํ•ด ์ผํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

window.require ์˜ ๋ฌธ์ œ์ ์€ ์ตœ์ƒ์œ„ ํŒจํ‚ค์ง€์—์„œ๋งŒ ์ž‘๋™ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด fs ๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋ฉด ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ fs ์— ๋Œ€ํ•œ ์ข…์†์„ฑ์ด ์žˆ๋Š” ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ์—ฌ์ „ํžˆ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

window.require React App ๋‚ด์—์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. "TypeError: window.require๋Š” ํ•จ์ˆ˜๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค"๋ผ๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

App.js :
```์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ
'๋ฐ˜์‘'์—์„œ React, { useEffect, useState } ๊ฐ€์ ธ์˜ค๊ธฐ;
๊ฐ€์ ธ์˜ค๊ธฐ './App.css';

const ipcRenderer = window.require('์ „์ž').ipcRenderer;

ํ•จ์ˆ˜ ์•ฑ() {

useEffect( () => {

    ipcRenderer.on('ping', (event, message) => { console.log(message) });

}, []);

return (
<div className = 'App'>
    <div className = 'Header-Arrow'></div>
    <div className = 'Box'>
        <p>Press โŒ˜ + โ‡ง + 4</p>
    </div>
</div>
);

}

๊ธฐ๋ณธ ์•ฑ ๋‚ด๋ณด๋‚ด๊ธฐ;
````

Main.js ์˜ ๋ฉ”์ธ ์ฐฝ ๋ณ€์ˆ˜:
```์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ
// ๋ธŒ๋ผ์šฐ์ € ์ฐฝ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
mainWindow = ์ƒˆ๋กœ์šด BrowserWindow({
AlwaysOnTop: ์‚ฌ์‹ค,
ํ”„๋ ˆ์ž„: ๊ฑฐ์ง“,
์ „์ฒด ํ™”๋ฉด ๊ฐ€๋Šฅ: ๊ฑฐ์ง“,
ํˆฌ๋ช…: ์‚ฌ์‹ค,
titleBarStyle: 'customButtonsOnHover',
ํ‘œ์‹œ: ๊ฑฐ์ง“,
๋„ˆ๋น„: 300,
ํ‚ค: 350,
์›น ๊ธฐ๋ณธ ์„ค์ •: {
nodeIntegration: ์ฐธ,
์‚ฌ์ „ ๋กœ๋“œ: __dirname + '/preload.js'
}
});

``` ** Preload.js`**:

javascript window.ipcRenderer = require('electron').ipcRenderer;

๋‚ด๊ฐ€ ๋ฌด์—‡์„ ๋†“์น˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๊ทธ๋ž˜์„œ, ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ํ˜œํƒ์„ ๋ณผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋‚˜๋Š” ์Šค์Šค๋กœ ๋Œ€๋‹ตํ•ฉ๋‹ˆ๋‹ค (๋ช‡ ์‹œ๊ฐ„ ๋™์•ˆ ๋ถ™์–ด์žˆ์—ˆ์Šต๋‹ˆ๋‹ค). Preload.js ํŒŒ์ผ์ด ์žˆ์œผ๋ฉด ร€pp.js (๋ Œ๋”๋Ÿฌ)์—์„œ window.require('electron').ipcRenderer ๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์ด window.ipcRenderer ๋ณ€์ˆ˜๋ฅผ ์ง์ ‘ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

App.js :

````์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ
'๋ฐ˜์‘'์—์„œ React, { useEffect, useState } ๊ฐ€์ ธ์˜ค๊ธฐ;
๊ฐ€์ ธ์˜ค๊ธฐ './App.css';

ํ•จ์ˆ˜ ์•ฑ() {

useEffect( () => {

    window.ipcRenderer.on('ping', (event, message) => { console.log(message) });

}, []);

return (
<div className = 'App'>
    <div className = 'Header-Arrow'></div>
    <div className = 'Box'>
        <p>Press โŒ˜ + โ‡ง + 4</p>
    </div>
</div>
);

}

๊ธฐ๋ณธ ์•ฑ ๋‚ด๋ณด๋‚ด๊ธฐ;
````

Main.js ์˜ ๋ฉ”์ธ ์ฐฝ ๋ณ€์ˆ˜:
javascript // Create the browser window. mainWindow = new BrowserWindow({ alwaysOnTop: true, frame: false, fullscreenable: false, transparent: true, titleBarStyle: 'customButtonsOnHover', show: false, width: 300, height: 350, webPreferences: { nodeIntegration: true, preload: __dirname + '/preload.js' } });
Preload.js :

javascript window.ipcRenderer = require('electron').ipcRenderer;

๋ช…๋ น์ค„์—์„œ ์•ฑ์„ ์‹คํ–‰ํ•œ ํ›„ React ํ”„๋กœ์„ธ์Šค์— ์˜ํ•ด ์ƒ์„ฑ๋œ ์ฐฝ์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค(ipcRenderer๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์Œ). ๋ฌด์‹œํ•ด. Electron ํ”„๋กœ์„ธ์Šค(๋ฉ”์ธ ์•ฑ)์— ์˜ํ•ด ์ƒ์„ฑ๋œ ์ฐฝ์€ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

Create-React-App 2์—์„œ๋Š” craco npm ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

https://www.npmjs.com/package/@craco/craco

package.json์—์„œ craco react-scripts ๋ณ€๊ฒฝ

craco.config.js

module.exports = {
    webpack: {
        configure: {
            target: 'electron-renderer'
        }
    }
};

require("fs") ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ window.require("fs") ๋™์•ˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ํ† ๋ก ์—์„œ CRACO๋ฅผ ์†Œ๊ฐœํ•œ @Maxou44 ์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํ”„๋กœ์ ํŠธ์—์„œ 3๊ฐ€์ง€๋ฅผ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

  1. @Maxou44๊ฐ€ ์ œ์•ˆํ•œ ๋Œ€๋กœ CRACO๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
  2. public/main.js(์ผ๋ถ€๋Š” ์ด ํŒŒ์ผ์˜ ์ด๋ฆ„์„ electron.js๋กœ ์ง€์ •ํ–ˆ์„ ์ˆ˜ ์žˆ์Œ)์—์„œ ๋ณ€๊ฒฝ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
    new BrowserWindow({ width: 1200, height: 800 })
    ์—๊ฒŒ
    new BrowserWindow({ width: 1200, height: 800, webPreferences: { nodeIntegration: true } })
  3. const fs = require("fs") ์„ const fs = require("electron").remote.require("fs") ๋กœ ๋Œ€์ฒด

์ž์„ธํ•œ ์„ค๋ช…์€ @wwlib ์˜ ์ด git repo๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. https://github.com/wwlib/cra-craco-electron-example

์ „์ฒด ์Šค๋ ˆ๋“œ๋ฅผ ์œ„์—์„œ ์•„๋ž˜๋กœ ์ฝ์—ˆ์ง€๋งŒ ์•„๋ฌด ๊ฒƒ๋„ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
์œ„์˜ @Saroopashree ๋ฐฉ๋ฒ•์„ ์ œ์™ธํ•˜๊ณ . ์†”๋ฃจ์…˜์„ ๊ณต์œ ํ•ด ์ฃผ์‹  @Saroopashree ์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.
์Šค๋ ˆ๋“œ๊ฐ€ ์‹œ์ž‘๋œ ์ดํ›„๋กœ react์™€ webpack์ด ๋‹ค์†Œ ๋ณ€๊ฒฝ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์œ„์˜ ์†”๋ฃจ์…˜์€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ํ‹€๋ฆด โ€‹โ€‹์ˆ˜๋„ ์žˆ์ง€๋งŒ ์œ„์˜ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ํšจ๊ณผ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๊ฒƒ์ด ๋‚ด๊ฐ€ ํ•œ ์ผ์ž…๋‹ˆ๋‹ค.

  1. npm install craco -D ์‹คํ–‰
  2. ๊ตฌ์„ฑ ํŒŒ์ผ craco.config.js ๋ฅผ ๋งŒ๋“ค๊ณ  ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ๋ถ™์—ฌ๋„ฃ์Šต๋‹ˆ๋‹ค.
    module.exports = { webpack: { configure: { target: 'electron-renderer' } } };
  3. main.js์—์„œ new BrowserWindow({ width: 1200, height: 800, webPreferences: { nodeIntegration: true } }) ๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ๋„ˆ๋น„์™€ ๋†’์ด๊ฐ€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
  4. npm start ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ create-react-app์„ ์‚ฌ์šฉํ•˜์—ฌ ๋งŒ๋“  ๋ฐ˜์‘ ์•ฑ์šฉ ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ์žˆ๋Š” ํƒญ์„ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” ๋‹ค์‹œ ํ”ผ๊ณคํ•จ์„ ๋Š๊ผˆ๋‹ค.
  5. npm run electron ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ „์ž ์•ฑ์„ ์‹คํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.
    ๊ทธ๋ฆฌ๊ณ  ๋น„์˜ฌ๋ผ!!! ํŽ˜์ด์ง€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

@Saroopashree๋‹˜ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜์‘ ๊ตฌ์„ฑ ์š”์†Œ/ํด๋ž˜์Šค ๋‚ด์˜ '์ „์ž' ๋˜๋Š” ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ์— ์•ก์„ธ์Šคํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค. #336757899

์ €์—๊ฒŒ ์ ํ•ฉํ•œ ์†”๋ฃจ์…˜์— ๋Œ€ํ•œ ๋งํฌ๋ฅผ ๊ฒŒ์‹œํ•ด ์ฃผ์‹  @tumbledwyer ์—๊ฒŒ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์—…๋ฐ์ดํŠธ๋จ:
์‹ค์ œ๋กœ ๋™์ผํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์˜ ๋‘ ๋ฒˆ์งธ ๋ฒ„์ „: https://www.codementor.io/randyfindley/how-to-build-an-electron-app-using-create-react-app-and-electron-builder-ss1k0sfer

Randy Findley์˜ ์†”๋ฃจ์…˜:
์ด์ œ ๋‚ด๊ฐ€ ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ fs ๋ชจ๋“ˆ์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ๋น ๋ฅด๊ฒŒ Module not found ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๋จผ์ € Rescripts ๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

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

๊ทธ๋Ÿฐ ๋‹ค์Œ package.json์˜ ์Šคํฌ๋ฆฝํŠธ ํƒœ๊ทธ๋ฅผ ๋‹ค์Œ์—์„œ ๋ณ€๊ฒฝํ•˜์‹ญ์‹œ์˜ค.

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

์ด์—

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

์ด์ œ ๋‹ค์Œ ๋‚ด์šฉ์ด ํฌํ•จ๋œ .rescriptsrc.js ๋ผ๋Š” ์ƒˆ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

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

๋งˆ์ง€๋ง‰์œผ๋กœ ๋‹ค์Œ ๋‚ด์šฉ์ด ํฌํ•จ๋œ .webpack.config.js ๋ผ๋Š” ๋‹ค๋ฅธ ์ƒˆ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

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

์ด์ œ fs ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์„ธ์š”.

@ledleds ๊ฐ€ ์ง€์ ํ•œ ๊ฒƒ์€ typscript ๋ฐ Electron๊ณผ ํ•จ๊ป˜ CRA๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ €์—๊ฒŒ ํšจ๊ณผ์ ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด webPreferences๋ฅผ ์„ ์–ธํ–ˆ์Šต๋‹ˆ๋‹ค.

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

nodeIntegration์„ ๋ฎ์–ด์“ฐ๊ฑฐ๋‚˜ false๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ ๊ฐ™์œผ๋ฏ€๋กœ true๋กœ ์„ค์ •ํ•˜๊ณ  ์•ฑ์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•˜๋ฉด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค(ํ•ด๋‹น ๊ตฌ์„ฑ์œผ๋กœ Electron ์ฐฝ์„ ๋กœ๋“œํ•˜๋ ค๋ฉด ์•ฑ์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•ด์•ผ ํ•จ).

๋‹ค์Œ๊ณผ ๊ฐ™์ด nodeIntegration์„ true๋กœ ์„ค์ •

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

$ BrowserWindow ๋ฅผ ์„ ์–ธํ•  ๋•Œ nodeIntergation ๋ฅผ true $๋กœ ๋ช…์‹œ์ ์œผ๋กœ ์„ ์–ธํ•˜์ง€ ์•Š๋Š” ํ•œ window.require is not a function ์˜ค๋ฅ˜๊ฐ€ ๊ณ„์† ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
    }
});

๋ฐ˜์‘ ์•ฑ ์žฌ์—ฐ๊ฒฐ

์ด๊ฒƒ์€ ํ™•์žฅ์„ฑ ์ธก๋ฉด์—์„œ ๋‚ด๊ฐ€ ์ฐพ์€ ์œ ์ผํ•œ ์ข‹์€ ์†”๋ฃจ์…˜์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ฌด๋„ window.require์— ์˜์กดํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

window.require๋ฅผ ํ™•์žฅํ•  ์ˆ˜ ์—†๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

์ด ๋ฌธ์ œ ๋˜๋Š” ์ด์™€ ์œ ์‚ฌํ•œ ๋ฌธ์ œ๋กœ ์–ด๋ ค์›€์„ ๊ฒช๊ณ  ์žˆ๊ณ  Vue ๋ฐ vue-electron-builder๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ๋žŒ์€ ์—ฌ๊ธฐ ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

๋ฐ˜์‘ ๋ฒ„ํŠผ์„ ํ†ตํ•ด ์ „์ž ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•˜๋Š” ๊ฒƒ๊ณผ ๊ด€๋ จํ•˜์—ฌ ์—ฌ์ „ํžˆ ์ด๊ฒƒ์œผ๋กœ ์–ด๋ ค์›€์„ ๊ฒช๊ณ  ์žˆ๋Š” ์‚ฌ๋žŒ์€ ๊ณ„์† ์ฝ์œผ์‹ญ์‹œ์˜ค.

์ €์—๊ฒŒ ๋„์›€์ด ๋œ ๊ฒƒ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ์ฐฝ์„ ์„ ์–ธํ•  ๋•Œ ๋ณด์•ˆ์ƒ์˜ ์ด์œ ๋กœ ํ˜„์žฌ ๊ธฐ๋ณธ์ ์œผ๋กœ false nodeIntegration: true ๋ฅผ ์„ค์ •ํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ์ผ๋ฐ˜์ ์œผ๋กœ electron.js ํŒŒ์ผ์—์„œ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.

  2. @packetstracer ๊ฐ€ ์ด๋ฏธ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด: _ํ•ด๋‹น ๊ตฌ์„ฑ์œผ๋กœ Electron ์ฐฝ์„ ๋กœ๋“œํ•˜๋ ค๋ฉด ์•ฑ์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค_

mainWindow = new BrowserWindow({
//...
  webPreferences: {
    nodeIntegration: true,
  },
});
  1. ๋˜ํ•œ electron.js ์—์„œ ์ƒ๋‹จ ๊ทผ์ฒ˜์— ๋‹ค์Œ ๋ช…๋ น๋ฌธ์„ ๋„ฃ์œผ๋ฉด ipcMain ๊ฐ€ _"close-me"_ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
const { ipcMain } = require("electron");
ipcMain.on("close-me", (evt, arg) => {
  app.quit();
});
  1. _"๋‹ซ๊ธฐ"_-๋ฒ„ํŠผ์ด ์žˆ๋Š” ๋ฐ˜์‘ ๊ตฌ์„ฑ ์š”์†Œ์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ ํ›„์— ๋‹ค์Œ window.require ๋ฌธ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ require ๊ฐ€ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค .
const ipcRenderer = window.require("electron").ipcRenderer;
  1. ๊ทธ๋ฆฌ๊ณ  ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์„ ๋‹ซ์œผ๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น๋ฌธ์„ ํ˜ธ์ถœํ•˜์‹ญ์‹œ์˜ค. ์ด๋ฒคํŠธ _"close-me"_๋ฅผ ipcMain์œผ๋กœ ๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
<Button label="close" onClick={(e) => ipcRenderer.send("close-me")} />

์ž์œ ๋กญ๊ฒŒ ์˜๊ฒฌ์„ ๋งํ•˜๊ณ  ํ”ผ๋“œ๋ฐฑ์„ ์ œ๊ณตํ•˜์‹ญ์‹œ์˜ค. ์ €๋Š” ์•„์ง ์ „์ž๋ฅผ ์ฒ˜์Œ ์ ‘ํ•ฉ๋‹ˆ๋‹ค.
์ข…๋ฃŒ ๋ฒ„ํŠผ์ด ์žˆ๋Š” ์ปจํ…์ŠคํŠธ๊ฐ€ ๊ด€๋ จ์ด ์—†๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์ง€๋งŒ ๋” ์ ํ•ฉํ•œ ์Šค๋ ˆ๋“œ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ ์ ˆํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์žˆ์œผ๋ฉด ์–ธ์ œ๋“ ์ง€ ์•Œ๋ ค์ฃผ์„ธ์š”.

๋‚ด ๊ตฌ์„ฑ:

"electron": "9.2.0",
"electron-builder": "22.8.0",
"electron-packager": "15.0.0",

๋‚˜๋ฅผ ์œ„ํ•ด ํ•ด๊ฒฐ!! @nukeop ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

`
`

typescript์—์„œ ์ ์ ˆํ•œ ์œ ํ˜•์„ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•„๋Š” ์‚ฌ๋žŒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

๋‚˜๋Š” ํ˜„์žฌ ๋‹ค์Œ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค

export const electron = window.require('electron').remote

๋‚˜๋Š” ๊ฐ™์€ ๊ฒƒ์„ ์›ํ•œ๋‹ค

export const electron = window.require('electron').remote as ElectronType

๋”ฐ๋ผ์„œ IDE๋Š” ์ „์ž API๋ฅผ ์ž๋™ ์™„์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

@timsamart ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ๋•๋ถ„์— ์ž‘์—… ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿคฃ

์œ„์˜ ๋ชจ๋“  ๊ฒƒ์„ ๋ฌธ์ž ๊ทธ๋Œ€๋กœ ์‹œ๋„ํ•˜๋Š” ๋ฐ ๋งŽ์€ ์‹œ๊ฐ„์„ ๋ณด๋‚ธ ํ›„์— BrowserView ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์— ๋Œ€๋น„ํ•˜์—ฌ $# BrowserWindow ์ฒ˜๋Ÿผ node.js๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•ด์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์„ ๋†“์ณค์Šต๋‹ˆ๋‹ค.

     new BrowserView({ // is a BrowserView not a BrowserWindow
        webPreferences: {
          nodeIntegration: true,
        },
      })
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰