Merge pull request #35 from PAXANDDOS/fix/v2.0.0

v2.0.0 improved
This commit is contained in:
草鞋没号 2022-06-07 07:24:19 +08:00 committed by GitHub
commit d949120836
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 102 additions and 121 deletions

10
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"editorconfig.editorconfig",
"mrmlnc.vscode-json5",
"rbbit.typescript-hero",
"syler.sass-indented",
]
}

2
.vscode/launch.json vendored
View File

@ -30,7 +30,7 @@
},
"runtimeArgs": [
"--remote-debugging-port=9229",
"${workspaceRoot}/dist/main/index.cjs"
"${workspaceRoot}/dist/electron/main/index.js"
],
"envFile": "${workspaceFolder}/.vscode/.debug.env"
},

122
README.md
View File

@ -1,4 +1,4 @@
# vite-react-electron
# electron-vite-react
![GitHub stars](https://img.shields.io/github/stars/caoxiemeihao/vite-react-electron?color=fa6470&style=flat)
![GitHub issues](https://img.shields.io/github/issues/caoxiemeihao/vite-react-electron?color=d8b22d&style=flat)
@ -11,7 +11,7 @@
This is a `Vite`-integrated `Electron` template built with simplification in mind.
The repo contains only the most basic files, dependencies and functionalities to ensure flexibility for various scenarios.
The repo contains only the most basic files, dependencies and functionalities to ensure flexibility for various scenarios.
You need a basic understanding of `Electron` and `Vite` to get started. But that's not mandatory - you can learn almost all the details by reading through the source code. Trust me, this repo is not that complex. 😋
@ -21,108 +21,76 @@ You need a basic understanding of `Electron` and `Vite` to get started. But that
npm create electron-vite
```
![electron-vite-react.gif](https://github.com/electron-vite/electron-vite-react/blob/main/packages/renderer/public/electron-vite-react.gif?raw=true)
![electron-vite-react.gif](https://github.com/electron-vite/electron-vite-react/blob/main/public/electron-vite-react.gif?raw=true)
## Debug
![electron-vite-react-debug.gif](https://github.com/electron-vite/electron-vite-react/blob/main/packages/renderer/public/electron-vite-react-debug.gif?raw=true)
<!--
```sh
# clone the project
git clone https://github.com/caoxiemeihao/vite-react-electron.git
# open the project directory
cd vite-react-electron
# install dependencies
npm install
# start the application
npm run dev
# make a production build
npm run build
```
-->
![electron-vite-react-debug.gif](https://github.com/electron-vite/electron-vite-react/blob/main/public/electron-vite-react-debug.gif?raw=true)
## Directory structure
Once `dev` or `build` npm-script is executed, the `dist` folder will be generated. It has the same structure as the `packages` folder, the purpose of this design is to ensure the correct path calculation.
Once `dev` or `build` npm-script is executed, the `dist` folder will be generated. It has the same structure as the project, the purpose of this design is to ensure the correct path calculation.
```tree
├── build Resources for the production build
| ├── icon.icns Icon for the application on macOS
| ├── icon.ico Icon for the application
| ├── installerIcon.ico Icon for the application installer
| └── uninstallerIcon.ico Icon for the application uninstaller
|
├── dist Generated after build according to the "packages" directory
| ├── main
| ├── preload
| └── renderer
├── electron Electron-related code
| ├── main Main-process source code
| ├── preload Preload-script source code
| └── resources Resources for the production build
| ├── icon.icns Icon for the application on macOS
| ├── icon.ico Icon for the application
| ├── installerIcon.ico Icon for the application installer
| └── uninstallerIcon.ico Icon for the application uninstaller
|
├── release Generated after production build, contains executables
| └──{version}
| ├── win-unpacked Contains unpacked application executable
| └── Setup.exe Installer for the application
| ├── {os}-unpacked Contains unpacked application executable
| └── Setup.{ext} Installer for the application
|
├── scripts
| ├── build.mjs Develop script -> npm run build
| └── watch.mjs Develop script -> npm run dev
|
├── packages
| ├── main Main-process source code
| | └── vite.config.ts
| ├── preload Preload-script source code
| | └── vite.config.ts
| └── renderer Renderer-process source code
| └── vite.config.ts
├── public Static assets
└── src Renderer source code, your React application
```
## Use Electron and NodeJS API
> 🚧 By default, Electron doesn't support the use of API related to Electron and NodeJS in the Renderer process, but someone might need to use it. If so, you can see the template 👉 **[electron-vite-boilerplate](https://github.com/caoxiemeihao/electron-vite-boilerplate)**
> 🚧 By default, Electron doesn't support the use of API related to Electron and NodeJS in the Renderer process, but someone might need to use it. If so, you can see the template 👉 **[electron-vite-boilerplate](https://github.com/electron-vite/electron-vite-boilerplate)**
#### Invoke Electron and NodeJS API in `Preload-script`
- **packages/preload/index.ts**
- **electron/preload/index.ts**
```typescript
import fs from "fs"
import { contextBridge, ipcRenderer } from "electron"
```typescript
import fs from "fs";
import { contextBridge, ipcRenderer } from "electron";
// --------- Expose some API to Renderer-process. ---------
contextBridge.exposeInMainWorld("fs", fs)
contextBridge.exposeInMainWorld("ipcRenderer", ipcRenderer)
```
// --------- Expose some API to Renderer-process. ---------
contextBridge.exposeInMainWorld("fs", fs);
contextBridge.exposeInMainWorld("ipcRenderer", ipcRenderer);
```
- **packages/renderer/src/global.d.ts**
- **src/global.d.ts**
```typescript
// Defined in the window
interface Window {
fs: typeof import("fs")
ipcRenderer: import("electron").IpcRenderer
}
```
```typescript
// Defined in the window
interface Window {
fs: typeof import("fs");
ipcRenderer: import("electron").IpcRenderer;
}
```
- **packages/renderer/src/main.ts**
- **src/main.ts**
```typescript
// Use Electron and NodeJS API in the Renderer-process
console.log("fs", window.fs)
console.log("ipcRenderer", window.ipcRenderer)
```
```typescript
// Use Electron and NodeJS API in the Renderer-process
console.log("fs", window.fs);
console.log("ipcRenderer", window.ipcRenderer);
```
## Use SerialPort, SQLite3, or other node-native addons in the Main-process
- First, you need to make sure that the dependencies in the `package.json` are NOT in the "devDependencies". Because the project will need them after packaged.
- Main-process, Preload-script are also built with Vite, and they're built as [build.lib](https://vitejs.dev/config/#build-lib).
So they just need to configure Rollup.
**Click to see more** 👉 [packages/main/vite.config.ts](https://github.com/caoxiemeihao/vite-react-electron/blob/main/packages/main/vite.config.ts)
So they just need to configure Rollup.
```js
export default {
@ -138,7 +106,7 @@ export default {
external: ["serialport", "sqlite3"],
},
},
}
};
```
## `dependencies` vs `devDependencies`
@ -148,9 +116,3 @@ export default {
- Like [serialport](https://www.npmjs.com/package/serialport), [sqlite3](https://www.npmjs.com/package/sqlite3) they are node-native modules and should be placed in `dependencies`. In addition, Vite will not build them, but treat them as external modules.
- Dependencies like [Vue](https://www.npmjs.com/package/vue) and [React](https://www.npmjs.com/package/react), which are pure javascript modules that can be built with Vite, can be placed in `devDependencies`. This reduces the size of the application.
<!--
## Result
<img width="400px" src="https://raw.githubusercontent.com/caoxiemeihao/blog/main/vite-react-electron/react-win.png" />
-->

View File

@ -2,36 +2,36 @@
* @see https://www.electron.build/configuration/configuration
*/
{
"appId": "YourAppID",
"productName": "YourAppName",
"copyright": "Copyright © 2022 ${author}",
"asar": true,
"directories": {
"output": "release/${version}",
"buildResources": "electron/resources"
appId: "YourAppID",
productName: "YourAppName",
copyright: "Copyright © 2022 ${author}",
asar: true,
directories: {
output: "release/${version}",
buildResources: "electron/resources",
},
"files": ["dist"],
"win": {
"target": [
files: ["dist"],
win: {
target: [
{
"target": "nsis",
"arch": ["x64"]
}
target: "nsis",
arch: ["x64"],
},
],
"artifactName": "${productName}-${version}-Setup.${ext}"
artifactName: "${productName}-${version}-Setup.${ext}",
},
"nsis": {
"oneClick": false,
"perMachine": false,
"allowToChangeInstallationDirectory": true,
"deleteAppDataOnUninstall": false
nsis: {
oneClick: false,
perMachine: false,
allowToChangeInstallationDirectory: true,
deleteAppDataOnUninstall: false,
},
"mac": {
"target": ["dmg"],
"artifactName": "${productName}-${version}-Installer.${ext}"
mac: {
target: ["dmg"],
artifactName: "${productName}-${version}-Installer.${ext}",
},
"linux": {
"target": ["AppImage"],
"artifactName": "${productName}-${version}-Installer.${ext}"
}
}
linux: {
target: ["AppImage"],
artifactName: "${productName}-${version}-Installer.${ext}",
},
}

View File

@ -15,9 +15,9 @@ if (!app.requestSingleInstanceLock()) {
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
let win: BrowserWindow | null = null
// Here, you can also use other preload
// Here you can add more preload scripts
const splash = join(__dirname, '../preload/splash.js')
// 🚧 Use ['ENV_NAME'] avoid vite:define plugin
// 🚧 Use ['ENV_NAME'] to avoid vite:define plugin
const url = `http://${process.env['VITE_DEV_SERVER_HOST']}:${process.env['VITE_DEV_SERVER_PORT']}`
async function createWindow() {

View File

@ -1,4 +1,3 @@
function domReady(condition: DocumentReadyState[] = ['complete', 'interactive']) {
return new Promise(resolve => {
if (condition.includes(document.readyState)) {

View File

@ -2,9 +2,9 @@ import { useState } from 'react'
import electron from '/electron.png'
import react from '/react.svg'
import vite from '/vite.svg'
import styles from './styles/app.module.scss'
import styles from 'styles/app.module.scss'
const App = () => {
const App: React.FC = () => {
const [count, setCount] = useState(0)
return (

3
src/global.d.ts vendored
View File

@ -1,9 +1,8 @@
export { }
declare global {
interface Window {
// Expose some Api through preload script
// Expose API through preload script
fs: typeof import('fs')
ipcRenderer: import('electron').IpcRenderer
removeLoading: () => void

View File

@ -1,9 +1,9 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './styles/index.css'
import 'styles/index.css'
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>

View File

@ -1,8 +1,13 @@
{
"compilerOptions": {
"baseUrl": ".",
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"paths": {
"@/*": ["src/*"],
"styles/*": ["src/assets/styles/*"]
},
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": false,
@ -19,3 +24,4 @@
"include": ["src", "types.d.ts"],
"references": [{ "path": "./tsconfig.node.json" }]
}

1
types.d.ts vendored
View File

@ -1,4 +1,3 @@
declare namespace NodeJS {
interface ProcessEnv {
NODE_ENV: 'development' | 'production'

View File

@ -5,10 +5,16 @@ import react from '@vitejs/plugin-react'
import electron from 'vite-plugin-electron'
import renderer from 'vite-plugin-electron/renderer'
rmSync('dist', { recursive: true, force: true }) // v14.14.0
rmSync(join(__dirname, 'dist'), { recursive: true, force: true }) // v14.14.0
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: {
'@': join(__dirname, 'src'),
'styles': join(__dirname, 'src/assets/styles'),
},
},
plugins: [
react(),
electron({
@ -22,7 +28,7 @@ export default defineConfig({
},
preload: {
input: {
// You can configure multiple preload here
// You can configure multiple preload scripts here
splash: join(__dirname, 'electron/preload/splash.ts'),
},
vite: {
@ -33,7 +39,7 @@ export default defineConfig({
},
},
}),
// Enable use Electron, Node.js API in Renderer-process
// Enables use of Node.js API in the Renderer-process
renderer(),
]
})