mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Add Electron example (#1430)
* Add Electron usage example * Remove the deploy part * Only allow GET request to our HTTP server * Only allow request from an electron app (checking the user agent) * Add warning about the local HTTP server * Update package.json * Update example to use Next.js v3 * Added required package.json fields with placeholders * Use next:// file protocol to open internal built files * Create next.config.js * Update set-menu.js * Update example to merge it with electron-next-skeleton ideas
This commit is contained in:
parent
fe1b3e89f1
commit
4b0467ed42
25
examples/with-electron/README.md
Normal file
25
examples/with-electron/README.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Electron application example
|
||||
|
||||
## How to use
|
||||
|
||||
Download the example [or clone the repo](https://github.com/zeit/next.js):
|
||||
|
||||
```bash
|
||||
curl https://codeload.github.com/zeit/next.js/tar.gz/master | tar -xz --strip=2 next.js-master/examples/with-electron
|
||||
cd with-electron
|
||||
```
|
||||
|
||||
Install it and run:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
## The idea behind the example
|
||||
|
||||
This example show how you can use Next.js inside an Electron application to avoid a lot of configuration, use Next.js router as view and use server-render to speed up the initial render of the application.
|
||||
|
||||
For development it's going to run a HTTP server and let Next.js handle routing. In production it use `next export` to pre-generate HTML static files and use them in your app instead of running an HTTP server.
|
||||
|
||||
You can create the production app using `npm run dist`.
|
36
examples/with-electron/main/index.js
Normal file
36
examples/with-electron/main/index.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
// 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
|
||||
})
|
||||
|
||||
const url = isDev
|
||||
? 'http://localhost:8000/start'
|
||||
: format({
|
||||
pathname: join(__dirname, '../renderer/start/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)
|
||||
})
|
31
examples/with-electron/package.json
Normal file
31
examples/with-electron/package.json
Normal file
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"name": "electron-next-skeleton",
|
||||
"productName": "ElectronNext",
|
||||
"version": "1.0.0",
|
||||
"main": "main/index.js",
|
||||
"scripts": {
|
||||
"start": "electron .",
|
||||
"build": "next build renderer && next export renderer",
|
||||
"dist": "npm run build && build --dir"
|
||||
},
|
||||
"build": {
|
||||
"asar": false,
|
||||
"extraResources": [
|
||||
{
|
||||
"from": "renderer/out",
|
||||
"to": "app/renderer"
|
||||
}
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "^1.6.11",
|
||||
"electron-builder": "^19.19.1",
|
||||
"next": "beta",
|
||||
"react": "15.6.1",
|
||||
"react-dom": "15.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"electron-is-dev": "0.3.0",
|
||||
"electron-next": "3.0.8"
|
||||
}
|
||||
}
|
14
examples/with-electron/renderer/next.config.js
Normal file
14
examples/with-electron/renderer/next.config.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
module.exports = {
|
||||
webpack (config, { dev }) {
|
||||
config.target = 'electron-renderer'
|
||||
return config
|
||||
},
|
||||
exportPathMap () {
|
||||
// Let Next.js know where to find the entry page
|
||||
// when it's exporting the static bundle for the use
|
||||
// in the production version of your app
|
||||
return {
|
||||
'/start': { page: '/start' }
|
||||
}
|
||||
}
|
||||
}
|
57
examples/with-electron/renderer/pages/start.js
Normal file
57
examples/with-electron/renderer/pages/start.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { Component } from 'react'
|
||||
import { ipcRenderer } from 'electron'
|
||||
|
||||
export default class extends Component {
|
||||
state = {
|
||||
input: '',
|
||||
message: null
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
// start listening the channel message
|
||||
ipcRenderer.on('message', this.handleMessage)
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
// stop listening the channel message
|
||||
ipcRenderer.removeListener('message', this.handleMessage)
|
||||
}
|
||||
|
||||
handleMessage = (event, message) => {
|
||||
// receive a message from the main process and save it in the local state
|
||||
this.setState({ message })
|
||||
}
|
||||
|
||||
handleChange = event => {
|
||||
this.setState({ input: event.target.value })
|
||||
}
|
||||
|
||||
handleSubmit = event => {
|
||||
event.preventDefault()
|
||||
ipcRenderer.send('message', this.state.input)
|
||||
this.setState({ message: null })
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<h1>Hello Electron!</h1>
|
||||
|
||||
{this.state.message &&
|
||||
<p>{this.state.message}</p>
|
||||
}
|
||||
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<input type='text' onChange={this.handleChange} />
|
||||
</form>
|
||||
|
||||
<style jsx>{`
|
||||
h1 {
|
||||
color: red;
|
||||
font-size: 50px;
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue