前言
很早之前写了一篇手把手教你搭建electron+react+ts环境 最近,将整套架构进行升级
- 抛弃webpack,采用vite+react+ts为主的技术栈
- 优化ipc通信封装
完整源码地址 github.com/qqjay2017/r…
话不多说,直接开始
项目初始化
$ npm create vite@5
分别选择react和typescript,创建完之后就有一个全新的vite+react起始项目
安装依赖
npm install cross-env electron electron-builder npm-run-all vitest -D
都安装最新版本就好了
项目改造
vite.config.ts
export default defineConfig({
plugins: [react()],
base:"./",
build: {
outDir: 'dist-react'
},
server: {
port: 5123,
strictPort:true
}
})
分别修改web项目的base,静态资源输出文件夹,本地开发端口
src文件夹下
分别新建electron 和ui文件夹,将原本src下面的所有文件都移动到ui文件夹下
index.html
<script type="module" src="/src/ui/main.tsx"></script>
修改web的入口
src/electron/main.ts
import { app, BrowserWindow } from "electron";
// 引用模块文件需要手动添加js后缀
import { isDev } from "./util.js";
import { getUIPath } from "./pathResolver.js";
app.on("ready", () => {
const mainWindow = new BrowserWindow({});
if (isDev()) {
mainWindow.loadURL("http://localhost:5123");
} else {
mainWindow.loadFile(getUIPath());
}
});
src/electron/util.ts
export function isDev(): boolean {
return process.env.NODE_ENV === "development";
}
src/electron/pathResolver.ts
import { app } from "electron";
import path from "path";
export function getUIPath() {
return path.join(app.getAppPath(), "/dist-react/index.html");
}
src/electron/tsconfig.json
{
"compilerOptions": {
"types": [
"../../types"
],
"strict": true,
"target": "ESNext",
"module": "ESNext",
"outDir": "../../dist-electron",
"skipLibCheck": true,
"moduleResolution": "bundler"
},
}
.eslintrc.cjs
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
],
ignorePatterns: [
"dist",
".eslintrc.cjs",
"src/electron/preload.cts",
"dist-electron",
"dist-react",
],
parser: "@typescript-eslint/parser",
plugins: ["react-refresh"],
rules: {
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
};
/types.d.ts
根目录下面新建types.d.ts,作为全局的类型文件
/tsconfig.json
{
"compilerOptions": {
"types": [
"./types"
],
"target": "ESNext",
"useDefineForClassFields": true,
"lib": [
"ES2020",
"DOM",
"DOM.Iterable"
],
"module": "ESNext",
"allowJs": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "Node",
"skipLibCheck": true,
/* Bundler mode */
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": [
"src"
],
"exclude": [
"src/electron"
],
"references": [
{
"path": "./tsconfig.node.json"
}
]
}
package.json
添加开发环境的命令
{
"main": "dist-electron/main.js",
"scripts": {
"postinstall": "electron-builder install-app-deps",
"dev": "npm-run-all --parallel dev:react dev:electron",
"dev:react": "vite",
"dev:electron": "npm run transpile:electron && cross-env NODE_ENV=development electron .",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"transpile:electron": "tsc --project src/electron/tsconfig.json"
}
}
main字段记得加
构建相关
electron-builder.json
{
"appId": "com.n-z.electron",
"extraResources": [
"dist-electron/preload.cjs",
"src/assets/**"
],
"files": [
"dist-electron",
"dist-react"
],
"icon": "./desktopIcon.png",
"mac": {
"target": "dmg"
},
"linux": {
"target": "AppImage",
"category": "Utility"
},
"win": {
"target": [
"portable",
"msi"
]
}
}
package.json
{
"scripts": {
"postinstall": "electron-builder install-app-deps",
"dev": "npm-run-all --parallel dev:react dev:electron",
"dev:react": "vite",
"dev:electron": "npm run transpile:electron && cross-env NODE_ENV=development electron .",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"transpile:electron": "tsc --project src/electron/tsconfig.json",
"dist:mac": "npm run transpile:electron && npm run build && electron-builder --mac --arm64",
"dist:win": "npm run transpile:electron && npm run build && electron-builder --win --x64",
"dist:linux": "npm run transpile:electron && npm run build && electron-builder --linux --x64",
"test:e2e": "playwright test",
"test:unit": "vitest src"
},
}
完整的package.json
{
"name": "electron-course",
"private": true,
"version": "0.0.0",
"type": "module",
"main": "dist-electron/main.js",
"author": "huang",
"description": "huang",
"scripts": {
"postinstall": "electron-builder install-app-deps",
"dev": "npm-run-all --parallel dev:react dev:electron",
"dev:react": "vite",
"dev:electron": "npm run transpile:electron && cross-env NODE_ENV=development electron .",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"transpile:electron": "tsc --project src/electron/tsconfig.json",
"dist:mac": "npm run transpile:electron && npm run build && electron-builder --mac --arm64",
"dist:win": "npm run transpile:electron && npm run build && electron-builder --win --x64",
"dist:linux": "npm run transpile:electron && npm run build && electron-builder --linux --x64",
"test:e2e": "playwright test",
"test:unit": "vitest src"
},
"dependencies": {
"os-utils": "^0.0.14",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"recharts": "^2.12.7"
},
"devDependencies": {
"@types/os-utils": "^0.0.4",
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vitejs/plugin-react": "^4.2.1",
"cross-env": "^7.0.3",
"electron": "^32.2.1",
"electron-builder": "^25.1.8",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"npm-run-all": "^4.1.5",
"typescript": "^5.2.2",
"vite": "^5.2.0",
"vitest": "^2.1.1"
},
"overrides": {
"@jridgewell/gen-mapping": "0.3.5"
}
}
当时@jridgewell/gen-mapping这个包出问题了,不知道啥时候修复 github.com/jridgewell/…
启动dev效果
打包成功
小技巧-设置electron代理
export ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
下一篇预告
ipc通信优化