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": [ "runtimeArgs": [
"--remote-debugging-port=9229", "--remote-debugging-port=9229",
"${workspaceRoot}/dist/main/index.cjs" "${workspaceRoot}/dist/electron/main/index.js"
], ],
"envFile": "${workspaceFolder}/.vscode/.debug.env" "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 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) ![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. 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. 😋 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 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 ## 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) ![electron-vite-react-debug.gif](https://github.com/electron-vite/electron-vite-react/blob/main/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
```
-->
## Directory structure ## 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 ```tree
├── build Resources for the production build ├── electron Electron-related code
| ├── icon.icns Icon for the application on macOS | ├── main Main-process source code
| ├── icon.ico Icon for the application | ├── preload Preload-script source code
| ├── installerIcon.ico Icon for the application installer | └── resources Resources for the production build
| └── uninstallerIcon.ico Icon for the application uninstaller | ├── icon.icns Icon for the application on macOS
| | ├── icon.ico Icon for the application
├── dist Generated after build according to the "packages" directory | ├── installerIcon.ico Icon for the application installer
| ├── main | └── uninstallerIcon.ico Icon for the application uninstaller
| ├── preload
| └── renderer
| |
├── release Generated after production build, contains executables ├── release Generated after production build, contains executables
| └──{version} | └──{version}
| ├── win-unpacked Contains unpacked application executable | ├── {os}-unpacked Contains unpacked application executable
| └── Setup.exe Installer for the application | └── Setup.{ext} Installer for the application
| |
├── scripts ├── public Static assets
| ├── build.mjs Develop script -> npm run build └── src Renderer source code, your React application
| └── 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
``` ```
## Use Electron and NodeJS API ## 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` #### Invoke Electron and NodeJS API in `Preload-script`
- **packages/preload/index.ts** - **electron/preload/index.ts**
```typescript ```typescript
import fs from "fs" import fs from "fs";
import { contextBridge, ipcRenderer } from "electron" import { contextBridge, ipcRenderer } from "electron";
// --------- Expose some API to Renderer-process. --------- // --------- Expose some API to Renderer-process. ---------
contextBridge.exposeInMainWorld("fs", fs) contextBridge.exposeInMainWorld("fs", fs);
contextBridge.exposeInMainWorld("ipcRenderer", ipcRenderer) contextBridge.exposeInMainWorld("ipcRenderer", ipcRenderer);
``` ```
- **packages/renderer/src/global.d.ts** - **src/global.d.ts**
```typescript ```typescript
// Defined in the window // Defined in the window
interface Window { interface Window {
fs: typeof import("fs") fs: typeof import("fs");
ipcRenderer: import("electron").IpcRenderer ipcRenderer: import("electron").IpcRenderer;
} }
``` ```
- **packages/renderer/src/main.ts** - **src/main.ts**
```typescript ```typescript
// Use Electron and NodeJS API in the Renderer-process // Use Electron and NodeJS API in the Renderer-process
console.log("fs", window.fs) console.log("fs", window.fs);
console.log("ipcRenderer", window.ipcRenderer) console.log("ipcRenderer", window.ipcRenderer);
``` ```
## Use SerialPort, SQLite3, or other node-native addons in the Main-process ## 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. - 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). - 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. 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)
```js ```js
export default { export default {
@ -138,7 +106,7 @@ export default {
external: ["serialport", "sqlite3"], external: ["serialport", "sqlite3"],
}, },
}, },
} };
``` ```
## `dependencies` vs `devDependencies` ## `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. - 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. - 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 * @see https://www.electron.build/configuration/configuration
*/ */
{ {
"appId": "YourAppID", appId: "YourAppID",
"productName": "YourAppName", productName: "YourAppName",
"copyright": "Copyright © 2022 ${author}", copyright: "Copyright © 2022 ${author}",
"asar": true, asar: true,
"directories": { directories: {
"output": "release/${version}", output: "release/${version}",
"buildResources": "electron/resources" buildResources: "electron/resources",
}, },
"files": ["dist"], files: ["dist"],
"win": { win: {
"target": [ target: [
{ {
"target": "nsis", target: "nsis",
"arch": ["x64"] arch: ["x64"],
} },
], ],
"artifactName": "${productName}-${version}-Setup.${ext}" artifactName: "${productName}-${version}-Setup.${ext}",
}, },
"nsis": { nsis: {
"oneClick": false, oneClick: false,
"perMachine": false, perMachine: false,
"allowToChangeInstallationDirectory": true, allowToChangeInstallationDirectory: true,
"deleteAppDataOnUninstall": false deleteAppDataOnUninstall: false,
}, },
"mac": { mac: {
"target": ["dmg"], target: ["dmg"],
"artifactName": "${productName}-${version}-Installer.${ext}" artifactName: "${productName}-${version}-Installer.${ext}",
}, },
"linux": { linux: {
"target": ["AppImage"], target: ["AppImage"],
"artifactName": "${productName}-${version}-Installer.${ext}" artifactName: "${productName}-${version}-Installer.${ext}",
} },
} }

View File

@ -15,9 +15,9 @@ if (!app.requestSingleInstanceLock()) {
process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true' process.env['ELECTRON_DISABLE_SECURITY_WARNINGS'] = 'true'
let win: BrowserWindow | null = null 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') 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']}` const url = `http://${process.env['VITE_DEV_SERVER_HOST']}:${process.env['VITE_DEV_SERVER_PORT']}`
async function createWindow() { async function createWindow() {

View File

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

View File

@ -2,9 +2,9 @@ import { useState } from 'react'
import electron from '/electron.png' import electron from '/electron.png'
import react from '/react.svg' import react from '/react.svg'
import vite from '/vite.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) const [count, setCount] = useState(0)
return ( return (

3
src/global.d.ts vendored
View File

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

View File

@ -1,9 +1,9 @@
import React from 'react' import React from 'react'
import ReactDOM from 'react-dom/client' import ReactDOM from 'react-dom/client'
import App from './App' 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> <React.StrictMode>
<App /> <App />
</React.StrictMode> </React.StrictMode>

View File

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

1
types.d.ts vendored
View File

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

View File

@ -5,10 +5,16 @@ import react from '@vitejs/plugin-react'
import electron from 'vite-plugin-electron' import electron from 'vite-plugin-electron'
import renderer from 'vite-plugin-electron/renderer' 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/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig({
resolve: {
alias: {
'@': join(__dirname, 'src'),
'styles': join(__dirname, 'src/assets/styles'),
},
},
plugins: [ plugins: [
react(), react(),
electron({ electron({
@ -22,7 +28,7 @@ export default defineConfig({
}, },
preload: { preload: {
input: { input: {
// You can configure multiple preload here // You can configure multiple preload scripts here
splash: join(__dirname, 'electron/preload/splash.ts'), splash: join(__dirname, 'electron/preload/splash.ts'),
}, },
vite: { 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(), renderer(),
] ]
}) })