Electron Study Notes
npm init electron-app@latest my-new-app -- --template=webpack-typescript
React code requires, add JSX support
{
"compilerOptions": {
"jsx": "react-jsx"
}
}
Switch npm to pnpm and need to install
pnpm install @electron-forge/plugin-base @electron-forge/maker-base @types/webpack --save-dev
Routing
pnpm install react-router-dom
LESS
pnpm install less less-loader --save-dev
webpack.rules.ts
{
test: /\.less$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
mode: 'local',
localIdentName: '[name]__[local]___[hash:base64:5]',
},
importLoaders: 1,
},
},
'less-loader',
],
}
Ant Design Pro
pnpm install antd --save
pnpm install @ant-design/pro-components --save
pnpm install @ant-design/pro-card
pnpm install @ant-design/pro-descriptions
pnpm install @ant-design/pro-field
pnpm install @ant-design/pro-form
pnpm install @ant-design/pro-layout
pnpm install @ant-design/pro-list
pnpm install @ant-design/pro-provider
pnpm install @ant-design/pro-skeleton
pnpm install @ant-design/pro-table
pnpm install @ant-design/pro-utils
Compile using babel-plugin-import to optimize the packaging volume of antd
pnpm install babel-plugin-import --save-dev
pnpm install @ant-design/icons --save
Data storage electron-store
conf is installed to handle type errors
pnpm install electron-store conf
tsconfig.jsonThe default template is: "moduleResolution": "node", electron-forge seems to find it difficult or does not support configuring "moduleResolution": "node16" or other property values. Here, an opportunistic way to configure aliases is used to fix the type errors of electron-store.
tsconfig.json
{
"compilerOptions": {
"paths": {
"conf": ["node_modules/conf/dist/source"]
}
}
}
Set up path aliases
tsconfig.json
{
"compilerOptions": {
"paths": {
"@/*": ["src/*"]
}
}
}
webpack.renderer.config.ts
{
resolve: {
alias: { '@': path.resolve(__dirname, './src') },
},
}
In addition to tsconfig.json webpack.renderer.config.ts configuring aliases, you also need to fix ESLint prompts
pnpm install eslint-import-resolver-typescript --save-dev
.eslintrc.json
"settings": {
"import/resolver": {
"typescript": {}
}
}
Process Communication (IPC)
Using the ipcMain and ipcRenderer modules: The main process listens for events through the ipcMain module, and the rendering process sends events through the ipcRenderer module to achieve two-way communication.
Using the remote module: Allows direct calling of modules and methods in the main process from the rendering process, achieving simple cross-process communication.
Using the webContents module: You can directly send messages to a specified rendering process through this module to achieve communication.
Using shared variables between processes: Achieve cross-process communication by establishing global variables or shared memory.
Using ipcMain and ipcRenderer modules
Rendering Process -> Main Process
Method one:
// 渲染进程 发出事件
ipcRenderer.send("channel1", 1, 2, 3);
// 主进程 监听事件
ipcMain.on("channel1", (e, a, b, c) => {
console.log("监听到渲染进程的发出的事件(callback)", a, b, c);
})
Method two:
// 渲染进程 发出事件
ipcRenderer.invoke("channel2", 1, 2, 3);
// 主进程 监听事件
ipcMain.handle("channel2", (e, a, b, c) => {
console.log("监听到渲染进程的发出的事件(Promise)", a, b, c)
})
Main Process -> Rendering Process
Method one:
// 渲染进程 监听事件
ipcRenderer.on(channel, handler)
// 主进程 发出事件
mainWindow.webContents.send("channel3");
Network Requests
pnpm install axios
// forge.config.ts 配置Content-Security-Policy 不是配置html中
const config: ForgeConfig = {
plugins: [
new WebpackPlugin({
devContentSecurityPolicy: "default-src 'self'; connect-src *; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline';",
devServer: {
//配置代理 解决跨域
proxy: {
'/login': {
target: 'http://localhost:8080', // 另一个API服务器地址
changeOrigin: true,
},
},
},
}),
],
};
//对应axios拓展文件 requestUtil.ts
const request = axios.create({
baseURL: 'http://localhost:4000',
});
The detailed requestUtil.ts file is as follows
import axios from 'axios';
const request = axios.create({
baseURL: 'http://localhost:4000',
timeout: 1000,
headers: {
'X-Custom-Header': 'foobar',
// 'Content-Type': 'application/json',
},
// withCredentials: true, //保持跨域请求的cookie信息
});
request.interceptors.request.use(
function (config) {
const token = localStorage.getItem('token');
config.headers.Authorization = token ? `Bearer ${token}` : '';
return config;
},
function (error) {
return Promise.reject(error);
}
);
request.interceptors.response.use(
function (response) {
// 对响应数据做一些处理
return response;
},
function (error) {
// 对响应错误做处理
return Promise.reject(error);
}
);
export default request;