forked from extern/bruno
feat: electron + nextjs
This commit is contained in:
parent
7b3808f27b
commit
1f2b64c7cc
4
.gitignore
vendored
4
.gitignore
vendored
@ -25,3 +25,7 @@ yarn-error.log*
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# next.js
|
||||
/renderer/.next/
|
||||
/renderer/out/
|
||||
|
1
.next/package.json
Normal file
1
.next/package.json
Normal file
@ -0,0 +1 @@
|
||||
{"type": "commonjs"}
|
21
index.html
21
index.html
@ -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
44
main.js
@ -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
40
main/index.js
Normal 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
9
main/preload.js
Normal 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
3046
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
23
package.json
23
package.json
@ -5,10 +5,20 @@
|
||||
"packages/grafnode-components",
|
||||
"packages/grafnode-www"
|
||||
],
|
||||
"main": "main.js",
|
||||
"main": "main/index.js",
|
||||
"scripts": {
|
||||
"clean": "rimraf dist renderer/.next renderer/out",
|
||||
"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": {
|
||||
"@babel/core": "^7.16.0",
|
||||
@ -19,14 +29,21 @@
|
||||
"babel-loader": "^8.2.3",
|
||||
"css-loader": "^6.5.1",
|
||||
"electron": "^17.1.0",
|
||||
"electron-builder": "^22.14.13",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-loader": "^3.0.1",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"lerna": "^4.0.0",
|
||||
"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",
|
||||
"webpack": "^5.64.4",
|
||||
"webpack-cli": "^4.9.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"electron-is-dev": "^2.0.0",
|
||||
"electron-next": "^3.1.5"
|
||||
}
|
||||
}
|
||||
|
4
renderer/.babelrc
Normal file
4
renderer/.babelrc
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"presets": ["next/babel"],
|
||||
"plugins": [["styled-components", { "ssr": true }]]
|
||||
}
|
3
renderer/next.config.js
Normal file
3
renderer/next.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
reactStrictMode: true,
|
||||
}
|
46
renderer/pages/index.js
Normal file
46
renderer/pages/index.js
Normal 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;
|
Loading…
Reference in New Issue
Block a user