feat: electron + nextjs

This commit is contained in:
Anoop M D 2022-03-05 23:07:48 +05:30
parent 7b3808f27b
commit 1f2b64c7cc
11 changed files with 2980 additions and 261 deletions

4
.gitignore vendored
View File

@ -25,3 +25,7 @@ yarn-error.log*
.env.development.local .env.development.local
.env.test.local .env.test.local
.env.production.local .env.production.local
# next.js
/renderer/.next/
/renderer/out/

1
.next/package.json Normal file
View File

@ -0,0 +1 @@
{"type": "commonjs"}

View File

@ -1,21 +0,0 @@
<!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'; style-src 'self' 'unsafe-inline'">
<title>grafnode!</title>
<style>
html { font-family: sans-serif; background: #2B2E3B; color: #9FEAF9; }
</style>
</head>
<body>
<h1>Hello Electron!</h1>
<p>Build cross-platform desktop apps with JavaScript, HTML, and CSS</p>
<script>
require('./renderer.js')
</script>
</body>
</html>

44
main.js
View File

@ -1,44 +0,0 @@
// Modules
const {app, BrowserWindow} = require('electron')
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow
// Create a new BrowserWindow when `app` is ready
function createWindow () {
mainWindow = new BrowserWindow({
width: 1000, height: 800,
webPreferences: {
// Disable 'contextIsolation' to allow 'nodeIntegration'
// 'contextIsolation' defaults to "true" as from Electron v12
contextIsolation: false,
nodeIntegration: true
}
})
// Load index.html into the new BrowserWindow
mainWindow.loadFile('index.html')
// Open DevTools - Remove for PRODUCTION!
// mainWindow.webContents.openDevTools();
// Listen for window being closed
mainWindow.on('closed', () => {
mainWindow = null
})
}
// Electron `app` is ready
app.on('ready', createWindow)
// Quit when all windows are closed - (Not macOS - Darwin)
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') app.quit()
})
// When app icon is clicked and app is running, (macOS) recreate the BrowserWindow
app.on('activate', () => {
if (mainWindow === null) createWindow()
})

40
main/index.js Normal file
View File

@ -0,0 +1,40 @@
// Native
const { join } = require('path');
const { format } = require('url');
// Packages
const { BrowserWindow, app, ipcMain } = require('electron');
const isDev = require('electron-is-dev');
const prepareNext = require('electron-next');
// Prepare the renderer once the app is ready
app.on('ready', async () => {
await prepareNext('./renderer');
const mainWindow = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false,
preload: join(__dirname, 'preload.js'),
},
});
const url = isDev
? 'http://localhost:8000'
: format({
pathname: join(__dirname, '../renderer/out/index.html'),
protocol: 'file:',
slashes: true,
})
mainWindow.loadURL(url);
});
// Quit the app once all windows are closed
app.on('window-all-closed', app.quit);
// listen the channel `message` and resend the received message to the renderer process
ipcMain.on('message', (event, message) => {
event.sender.send('message', message);
});

9
main/preload.js Normal file
View File

@ -0,0 +1,9 @@
const { ipcRenderer, contextBridge } = require('electron');
contextBridge.exposeInMainWorld('electron', {
message: {
send: (payload) => ipcRenderer.send('message', payload),
on: (handler) => ipcRenderer.on('message', handler),
off: (handler) => ipcRenderer.off('message', handler),
}
});

3046
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,10 +5,20 @@
"packages/grafnode-components", "packages/grafnode-components",
"packages/grafnode-www" "packages/grafnode-www"
], ],
"main": "main.js", "main": "main/index.js",
"scripts": { "scripts": {
"clean": "rimraf dist renderer/.next renderer/out",
"start": "electron .", "start": "electron .",
"watch": "nodemon --exec electron ." "build": "next build renderer && next export renderer",
"pack-app": "npm run build && electron-builder --dir",
"dist": "npm run build && electron-builder"
},
"build": {
"asar": true,
"files": [
"main",
"renderer/out"
]
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.16.0", "@babel/core": "^7.16.0",
@ -19,14 +29,21 @@
"babel-loader": "^8.2.3", "babel-loader": "^8.2.3",
"css-loader": "^6.5.1", "css-loader": "^6.5.1",
"electron": "^17.1.0", "electron": "^17.1.0",
"electron-builder": "^22.14.13",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"html-loader": "^3.0.1", "html-loader": "^3.0.1",
"html-webpack-plugin": "^5.5.0", "html-webpack-plugin": "^5.5.0",
"lerna": "^4.0.0", "lerna": "^4.0.0",
"mini-css-extract-plugin": "^2.4.5", "mini-css-extract-plugin": "^2.4.5",
"nodemon": "^2.0.15", "next": "^12.1.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"style-loader": "^3.3.1", "style-loader": "^3.3.1",
"webpack": "^5.64.4", "webpack": "^5.64.4",
"webpack-cli": "^4.9.1" "webpack-cli": "^4.9.1"
},
"dependencies": {
"electron-is-dev": "^2.0.0",
"electron-next": "^3.1.5"
} }
} }

4
renderer/.babelrc Normal file
View File

@ -0,0 +1,4 @@
{
"presets": ["next/babel"],
"plugins": [["styled-components", { "ssr": true }]]
}

3
renderer/next.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
reactStrictMode: true,
}

46
renderer/pages/index.js Normal file
View File

@ -0,0 +1,46 @@
import { useState, useEffect } from 'react'
const Home = () => {
const [input, setInput] = useState('')
const [message, setMessage] = useState(null)
useEffect(() => {
const handleMessage = (event, message) => setMessage(message)
window.electron.message.on(handleMessage)
return () => {
window.electron.message.off(handleMessage)
}
}, [])
const handleSubmit = (event) => {
event.preventDefault()
window.electron.message.send(input)
setMessage(null)
}
return (
<div>
<h1>Hello Electron!</h1>
{message && <p>{message}</p>}
<form onSubmit={handleSubmit}>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
/>
</form>
<style jsx>{`
h1 {
color: red;
font-size: 50px;
}
`}</style>
</div>
)
}
export default Home;