尝试使用electron将React生成的静态网页打包成桌面应用。
0. 项目结构
静态网页资源dist应先移动到application项目中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| . ├── application │ ├── package.json │ └── main.js ├── dist | └── index.html └── web ├── package.json ├── vite.config.js ├── src ├── App.jsx └── components └── Navigation.jsx
|
1. 项目初始化与安装
参考:教程
但是在安装时出现问题,是网络的原因。运行以下命令后安装,解决:
1
| npm config set registry https://registry.npmmirror.com; $env:ELECTRON_MIRROR = "https://npmmirror.com/mirrors/electron/"
|
后面运行命令出现网络问题也如此。
2. 打包
对web项目使用npm run build后生成的静态网页进行打包。
但需要注意:
- Vite 的构建产物默认使用以 “/” 开头的资源路径(如 /assets/…),在 Electron 以 file:// 加载本地文件时,这种绝对路径会解析到磁盘根目录。因此应该改为:
1 2 3 4 5 6 7 8 9
| import { defineConfig } from 'vite' import react from '@vitejs/plugin-react'
export default defineConfig({ plugins: [react()], base: './', })
|
- 在
application项目中,文件加载路径的写法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| const { app, BrowserWindow } = require('electron/main') const path = require('path')
const createWindow = () => { const win = new BrowserWindow({ width: 800, height: 600 })
win.loadFile(path.join(__dirname, '..', 'dist', 'index.html')); }
app.whenReady().then(() => { createWindow()
app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) { createWindow() } }) })
app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } })
|
但即使是这样,路由也会出现问题。发现是由于src源文件中React Router没有配置好。
更新后的src/App.jsx:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import { BrowserRouter, HashRouter, Routes, Route } from 'react-router-dom' import { Container } from 'react-bootstrap' import Navigation from './components/Navigation' import Home from './pages/Home' import Books from './pages/Books' import Borrowings from './pages/Borrowings' import 'bootstrap/dist/css/bootstrap.min.css' import './App.css'
const RouterComponent = window.location.protocol === 'file:' ? HashRouter : BrowserRouter
function App() { return ( <RouterComponent> <Navigation /> <Container className="mt-3"> <Routes> <Route path="/" element={<Home />} /> <Route path="/books" element={<Books />} /> <Route path="/borrowings" element={<Borrowings />} /> </Routes> </Container> </RouterComponent> ) }
export default App
|
同时在Navigation组件中,注意LinkContainer 包裹品牌区,避免 file:// 下 href=”/“ 的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import { Navbar, Nav, Container } from 'react-bootstrap' import { LinkContainer } from 'react-router-bootstrap'
function Navigation() { return ( <Navbar bg="dark" variant="dark" expand="lg"> <Container> <LinkContainer to="/"> <Navbar.Brand>图书管理系统</Navbar.Brand> </LinkContainer> <Navbar.Toggle aria-controls="basic-navbar-nav" /> <Navbar.Collapse id="basic-navbar-nav"> <Nav className="me-auto"> <LinkContainer to="/"> <Nav.Link>首页</Nav.Link> </LinkContainer> <LinkContainer to="/books"> <Nav.Link>图书管理</Nav.Link> </LinkContainer> <LinkContainer to="/borrowings"> <Nav.Link>借阅管理</Nav.Link> </LinkContainer> </Nav> </Navbar.Collapse> </Container> </Navbar> ) }
export default Navigation
|
再重新npm run build生成静态网页, 并将dist目录移动到application项目中。