8000 feat: bumps electron@28, vite@5, vite-plugin-electron@0.28.0-beta.2 · coder-long/electron-vite-react@208ab38 · GitHub
[go: up one dir, main page]

Skip to content < 8000 div data-target="react-partial.reactRoot">

Commit 208ab38

Browse files
committed
feat: bumps electron@28, vite@5, vite-plugin-electron@0.28.0-beta.2
1 parent 5303923 commit 208ab38

File tree

12 files changed

+164
-54
lines changed

12 files changed

+164
-54
lines changed

electron/main/index.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
import { app, BrowserWindow, shell, ipcMain } from 'electron'
22
import { release } from 'node:os'
3-
import { join } from 'node:path'
3+
import { dirname, join } from 'node:path'
4+
import { fileURLToPath } from 'node:url'
45
import { update } from './update'
56

7+
const __filename = fileURLToPath(import.meta.url)
8+
const __dirname = dirname(__filename)
9+
610
// The built directory structure
711
//
812
// ├─┬ dist-electron
913
// │ ├─┬ main
1014
// │ │ └── index.js > Electron-Main
1115
// │ └─┬ preload
12-
// │ └── index.js > Preload-Scripts
16+
// │ └── index.mjs > Preload-Scripts
1317
// ├─┬ dist
1418
// │ └── index.html > Electron-Renderer
1519
//
@@ -37,7 +41,7 @@ if (!app.requestSingleInstanceLock()) {
3741

3842
let win: BrowserWindow | null = null
3943
// Here, you can also use other preload
40-
const preload = join(__dirname, '../preload/index.js')
44+
const preload = join(__dirname, '../preload/index.mjs')
4145
const url = process.env.VITE_DEV_SERVER_URL
4246
const indexHtml = join(process.env.DIST, 'index.html')
4347

@@ -48,10 +52,11 @@ async function createWindow() {
4852
webPreferences: {
4953
preload,
5054
// Warning: Enable nodeIntegration and disable contextIsolation is not secure in production
55+
// nodeIntegration: true,
56+
5157
// Consider using contextBridge.exposeInMainWorld
5258
// Read more on https://www.electronjs.org/docs/latest/tutorial/context-isolation
53-
nodeIntegration: true,
54-
contextIsolation: false,
59+
// contextIsolation: false,
5560
},
5661
})
5762

electron/main/update.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { app, ipcMain } from 'electron'
2-
import {
3-
type ProgressInfo,
4-
type UpdateDownloadedEvent,
5-
autoUpdater
2+
import { createRequire } from 'node:module'
3+
import type {
4+
ProgressInfo,
5+
UpdateDownloadedEvent,
66
} from 'electron-updater'
77

8+
const { autoUpdater } = createRequire(import.meta.url)('electron-updater');
9+
810
export function update(win: Electron.BrowserWindow) {
911

1012
// When set to false, the update download will be triggered through the API

electron/preload/index.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,28 @@
1+
import { ipcRenderer, contextBridge } from 'electron'
2+
3+
// --------- Expose some API to the Renderer process ---------
4+
contextBridge.exposeInMainWorld('ipcRenderer', withPrototype(ipcRenderer))
5+
6+
// `exposeInMainWorld` can't detect attributes and methods of `prototype`, manually patching it.
7+
function withPrototype(obj: Record<string, any>) {
8+
const protos = Object.getPrototypeOf(obj)
9+
10+
for (const [key, value] of Object.entries(protos)) {
11+
if (Object.prototype.hasOwnProperty.call(obj, key)) continue
12+
13+
if (typeof value === 'function') {
14+
// Some native APIs, like `NodeJS.EventEmitter['on']`, don't work in the Renderer process. Wrapping them into a function.
15+
obj[key] = function (...args: any) {
16+
return value.call(obj, ...args)
17+
}
18+
} else {
19+
obj[key] = value
20+
}
21+
}
22+
return obj
23+
}
24+
25+
// --------- Preload scripts loading ---------
126
function domReady(condition: DocumentReadyState[] = ['complete', 'interactive']) {
227
return new Promise(resolve => {
328
if (condition.includes(document.readyState)) {

package.json

Lines changed: 4 additions & 6 deletions
< 10000 /tr>
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"VITE_DEV_SERVER_URL": "http://127.0.0.1:7777/"
1212
}
1313
},
14+
"type": "module",
1415
"scripts": {
1516
"dev": "vite",
1617
"build": "tsc && vite build && electron-builder",
@@ -27,18 +28,15 @@
2728
"@types/react-dom": "^18.2.7",
2829
"@vitejs/plugin-react": "^4.0.4",
2930
"autoprefixer": "^10.4.16",
30-
"electron": "^26.0.0",
31+
"electron": "^28.1.0",
3132
"electron-builder": "^24.6.3",
3233
"postcss": "^8.4.31",
3334
"react": "^18.2.0",
3435
"react-dom": "^18.2.0",
3536
"tailwindcss": "^3.3.3",
3637
"typescript": "^5.1.6",
37-
"vite": "^4.4.9",
38-
"vite-plugin-electron": "^0.15.5",
38+
"vite": "^5.0.10",
39+
"vite-plugin-electron": "^0.28.0-beta.2",
3940
"vite-plugin-electron-renderer": "^0.14.5"
40-
},
41-
"engines": {
42-
"node": "^14.18.0 || >=16.0.0"
4341
}
4442
}

src/App.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import logoVite from './assets/logo-vite.svg'
44
import logoElectron from './assets/logo-electron.svg'
55
import './App.css'
66

7-
console.log('[App.tsx]', `Hello world from Electron ${process.versions.electron}!`)
8-
97
function App() {
108
const [count, setCount] = useState(0)
119
return (

src/components/update/index.tsx

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { ipcRenderer } from 'electron'
21
import type { ProgressInfo } from 'electron-updater'
32
import { useCallback, useEffect, useState } from 'react'
43
import Modal from '@/components/update/Modal'
@@ -19,15 +18,15 @@ const Update = () => {
1918
onOk?: () => void
2019
}>({
2120
onCancel: () => setModalOpen(false),
22-
onOk: () => ipcRenderer.invoke('start-download'),
21+
onOk: () => window.ipcRenderer.invoke('start-download'),
2322
})
2423

2524
const checkUpdate = async () => {
2625
setChecking(true)
2726
/**
2827
* @type {import('electron-updater').UpdateCheckResult | null | { message: string, error: Error }}
2928
*/
30-
const result = await ipcRenderer.invoke('check-update')
29+
const result = await window.ipcRenderer.invoke('check-update')
3130
setProgressInfo({ percent: 0 })
3231
setChecking(false)
3332
setModalOpen(true)
@@ -46,7 +45,7 @@ const Update = () => {
4645
...state,
4746
cancelText: 'Cancel',
4847
okText: 'Update',
49-
onOk: () => ipcRenderer.invoke('start-download'),
48+
onOk: () => window.ipcRenderer.invoke('start-download'),
5049
}))
5150
setUpdateAvailable(true)
5251
} else {
@@ -69,22 +68,22 @@ const Update = () => {
6968
...state,
7069
cancelText: 'Later',
7170
okText: 'Install now',
72-
onOk: () => ipcRenderer.invoke('quit-and-install'),
71+
onOk: () => window.ipcRenderer.invoke('quit-and-install'),
7372
}))
7473
}, [])
7574

7675
useEffect(() => {
7776
// Get version information and whether to update
78-
ipcRenderer.on('update-can-available', onUpdateCanAvailable)
79-
ipcRenderer.on('update-error', onUpdateError)
80-
ipcRenderer.on('download-progress', onDownloadProgress)
81-
ipcRenderer.on('update-downloaded', onUpdateDownloaded)
77+
window.ipcRenderer.on('update-can-available', onUpdateCanAvailable)
78+
window.ipcRenderer.on('update-error', onUpdateError)
79+
window.ipcRenderer.on('download-progress', onDownloadProgress)
80+
window.ipcRenderer.on('update-downloaded', onUpdateDownloaded)
8281

8382
return () => {
84-
ipcRenderer.off('update-can-available', onUpdateCanAvailable)
85-
ipcRenderer.off('update-error', onUpdateError)
86-
ipcRenderer.off('download-progress', onDownloadProgress)
87-
ipcRenderer.off('update-downloaded', onUpdateDownloaded)
83+
window.ipcRenderer.off('update-can-available', onUpdateCanAvailable)
84+
window.ipcRenderer.off('update-error', onUpdateError)
85+
window.ipcRenderer.off('download-progress', onDownloadProgress)
86+
window.ipcRenderer.off('update-downloaded', onUpdateDownloaded)
8887
}
8988
}, [])
9089

src/demos/ipc.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { ipcRenderer } from 'electron'
2+
3+
ipcRenderer.on('main-process-message', (_event, ...args) => {
4+
console.log('[Receive Main-process message]:', ...args)
5+
})

src/samples/node-api.ts renamed to src/demos/node.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import { lstat } from 'node:fs/promises'
22
import { cwd } from 'node:process'
3-
import { ipcRenderer } from 'electron'
4-
5-
ipcRenderer.on('main-process-message', (_event, ...args) => {
6-
console.log('[Receive Main-process message]:', ...args)
7-
})
83

94
lstat(cwd()).then(stats => {
105
console.log('[fs.lstat]', stats)

src/main.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import React from 'react'
22
import ReactDOM from 'react-dom/client'
33
import App from './App'
4-
import './samples/node-api'
4+
55
import './index.css'
66

7+
// `nodeIntegration` needs to be enabled in the Main process.
8+
// import './demos/node'
9+
// import './demos/ipc'
10+
711
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
812
<React.StrictMode>
913
<App />

src/vite-env.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
11
/// <reference types="vite/client" />
2+
3+
interface Window {
4+
// expose in the `electron/preload/index.ts`
5+
ipcRenderer: import('electron').IpcRenderer
6+
}

vite.config.flat.txt

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { rmSync } from 'node:fs'
2+
import path from 'node:path'
3+
import { defineConfig } from 'vite'
4+
import react from '@vitejs/plugin-react'
5+
import electron from 'vite-plugin-electron'
6+
import renderer from 'vite-plugin-electron-renderer'
7+
import pkg from './package.json'
8+
9+
// https://vitejs.dev/config/
10+
export default defineConfig(({ command }) => {
11+
rmSync('dist-electron', { recursive: true, force: true })
12+
13+
const isServe = command === 'serve'
14+
const isBuild = command === 'build'
15+
const sourcemap = isServe || !!process.env.VSCODE_DEBUG
16+
17+
return {
18+
resolve: {
19+
alias: {
20+
'@': path.join(__dirname, 'src')
21+
},
22+
},
23+
plugins: [
24+
react(),
25+
electron([
26+
{
27+
// Main-Process entry file of the Electron App.
28+
entry: 'electron/main/index.ts',
29+
onstart(options) {
30+
if (process.env.VSCODE_DEBUG) {
31+
console.log(/* For `.vscode/.debug.script.mjs` */'[startup] Electron App')
32+
} else {
33+
options.startup()
34+
}
35+
},
36+
vite: {
37+
build: {
38+
sourcemap,
39+
minify: isBuild,
40+
outDir: 'dist-electron/main',
41+
rollupOptions: {
42+
external: Object.keys('dependencies' in pkg ? pkg.dependencies : {}),
43+
},
44+
},
45+
},
46+
},
47+
{
48+
entry: 'electron/preload/index.ts',
49+
onstart(options) {
50+
// Notify the Renderer-Process to reload the page when the Preload-Scripts build is complete,
51+
// instead of restarting the entire Electron App.
52+
options.reload()
53+
},
54+
vite: {
55+
build: {
56+
sourcemap: sourcemap ? 'inline' : undefined, // #332
57+
minify: isBuild,
58+
outDir: 'dist-electron/preload',
59+
rollupOptions: {
60+
external: Object.keys('dependencies' in pkg ? pkg.dependencies : {}),
61+
},
62+
},
63+
},
64+
}
65+
]),
66+
// Use Node.js API in the Renderer-process
67+
renderer(),
68+
],
69+
server: process.env.VSCODE_DEBUG && (() => {
70+
const url = new URL(pkg.debug.env.VITE_DEV_SERVER_URL)
71+
return {
72+
host: url.hostname,
73+
port: +url.port,
74+
}
75+
})(),
76+
clearScreen: false,
77+
}
78+
})

vite.config.ts

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ import { rmSync } from 'node:fs'
22
import path from 'node:path'
33
import { defineConfig } from 'vite'
44
import react from '@vitejs/plugin-react'
5-
import electron from 'vite-plugin-electron'
6-
import renderer from 'vite-plugin-electron-renderer'
5+
import electron from 'vite-plugin-electron/simple'
76
import pkg from './package.json'
87

98
// https://vitejs.dev/config/
@@ -22,15 +21,15 @@ export default defineConfig(({ command }) => {
2221
},
2322
plugins: [
2423
react(),
25-
electron([
26-
{
27-
// Main-Process entry file of the Electron App.
24+
electron({
25+
main: {
26+
// Shortcut of `build.lib.entry`
2827
entry: 'electron/main/index.ts',
29-
onstart(options) {
28+
onstart(args) {
3029
if (process.env.VSCODE_DEBUG) {
3130
console.log(/* For `.vscode/.debug.script.mjs` */'[startup] Electron App')
3231
} else {
33-
options.startup()
32+
args.startup()
3433
}
3534
},
3635
vite: {
@@ -44,13 +43,10 @@ export default defineConfig(({ command }) => {
4443
},
4544
},
4645
},
47-
{
48-
entry: 'electron/preload/index.ts',
49-
onstart(options) {
50-
// Notify the Renderer-Process to reload the page when the Preload-Scripts build is complete,
51-
// instead of restarting the entire Electron App.
52-
options.reload()
53-
},
46+
preload: {
47+
// Shortcut of `build.rollupOptions.input`.
48+
// Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`.
49+
input: 'electron/preload/index.ts',
5450
vite: {
5551
build: {
5652
sourcemap: sourcemap ? 'inline' : undefined, // #332
@@ -61,10 +57,10 @@ export default defineConfig(({ command }) => {
6157
},
6258
},
6359
},
64-
}
65-
]),
66-
// Use Node.js API in the Renderer-process
67-
renderer(),
60+
},
61+
// Use Node.js API in the Renderer process
62+
renderer: {},
63+
}),
6864
],
6965
server: process.env.VSCODE_DEBUG && (() => {
7066
const url = new URL(pkg.debug.env.VITE_DEV_SERVER_URL)

0 commit comments

Comments
 (0)
0