1
0
Fork 0
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:
Sergio Xalambrí 2017-08-09 00:56:23 -05:00 committed by Tim Neutkens
parent fe1b3e89f1
commit 4b0467ed42
5 changed files with 163 additions and 0 deletions

View 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`.

View 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)
})

View 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"
}
}

View 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' }
}
}
}

View 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>
)
}
}