Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,847 changes: 1,710 additions & 137 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions rsbuild/react-electron/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Local
.DS_Store
*.local
*.log*

# Dist
node_modules
dist/
release/

# IDE
.vscode/*
!.vscode/extensions.json
.idea
node-compile-cache/
23 changes: 23 additions & 0 deletions rsbuild/react-electron/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Rsbuild Project

## Setup

Install the dependencies:

```bash
pnpm install
```

## Get Started

Start the dev server:

```bash
pnpm dev
```

Build the app for production:

```bash
pnpm build
```
55 changes: 55 additions & 0 deletions rsbuild/react-electron/biomed.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false,
"ignore": []
},
"formatter": {
"enabled": true,
"bracketSpacing": true,
"indentStyle": "space",
"lineWidth": 100,
"indentWidth": 2
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"complexity": {
"noStaticOnlyClass": "off"
},
"style": {
"noNonNullAssertion": "off"
},
"recommended": true,
"security": {
"noDangerouslySetInnerHtml": {
"level": "off"
}
},
"suspicious": {
"noAsyncPromiseExecutor": "off",
"noExplicitAny": {
"level": "off"
}
},
"a11y": {
"noSvgWithoutTitle": {
"level": "off"
}
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
}
}
65 changes: 65 additions & 0 deletions rsbuild/react-electron/builder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const { version, name } = require('./package.json');
const { resolve } = require('node:path');

const versionArr = version.split('-');
const bundleShortVersion = versionArr[0];
const bundleVersion = versionArr[1];

const config = {
asar: true,
productName: name,
appId: '',
directories: {
output: 'dist',
},
icon: resolve(__dirname, './icons/icon.icns'),
asarUnpack: '**\\*.{node,dll}',
files: ['./release/dist', 'node_modules', 'package.json'],
mac: {
target: ['dmg'],
bundleVersion: bundleVersion,
bundleShortVersion: bundleShortVersion,
artifactName: '${productName}-${version}-${arch}.${ext}',
extendInfo: {
ElectronTeamID: '',
ITSAppUsesNonExemptEncryption: 'NO',
},
asarUnpack: ['**/*.node'],
},
mas: {
hardenedRuntime: false,
gatekeeperAssess: false,
entitlements: 'mas/entitlements.mas.plist',
entitlementsInherit: 'mas/entitlements.mas.inherit.plist',
entitlementsLoginHelper: 'mas/entitlements.mas.loginhelper.plist',
provisioningProfile: 'TODO: mas/your.provisionprofile',
},
masDev: {
hardenedRuntime: false,
gatekeeperAssess: false,
entitlements: 'mas/entitlements.mas.plist',
entitlementsInherit: 'mas/entitlements.mas.inherit.plist',
entitlementsLoginHelper: 'mas/entitlements.mas.loginhelper.plist',
provisioningProfile: 'TODO: mas/moki_rss.provisionprofile',
},
dmg: {
sign: false,
},
win: {
target: ['nsis'],
verifyUpdateCodeSignature: false,
signingHashAlgorithms: ['sha256'],
signDlls: false,
requestedExecutionLevel: 'asInvoker',
},
nsis: {
oneClick: false,
perMachine: false,
allowToChangeInstallationDirectory: true,
deleteAppDataOnUninstall: false,
createDesktopShortcut: true,
createStartMenuShortcut: true,
shortcutName: name,
},
};
module.exports = config;
12 changes: 12 additions & 0 deletions rsbuild/react-electron/builder/common/paths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const path = require('node:path');

export const rootPath = path.join(__dirname, '../..');

export const srcPath = path.join(rootPath, './src');
export const srcMainPath = path.join(srcPath, './main');
export const srcRenderPath = path.join(srcPath, './render');

export const releasePath = path.join(rootPath, './release');
export const releaseDistPath = path.join(releasePath, './dist');
export const releaseMainPath = path.join(releaseDistPath, './main');
export const releaseRenderPath = path.join(releaseDistPath, './render');
31 changes: 31 additions & 0 deletions rsbuild/react-electron/builder/common/rsbuild.common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { defineConfig, loadEnv } from '@rsbuild/core';
import { join } from 'node:path';
import { rootPath, srcPath } from './paths';

const { publicVars } = loadEnv({
prefixes: [''],
cwd: `${process.cwd()}/env`,
mode: process.env?.NODE_ENV === 'development' ? 'dev' : '',
});

const CommonConfig = defineConfig({
performance: {
buildCache: false,
},
source: {
define: publicVars,
decorators: {
version: 'legacy',
},
},
resolve: {
alias: {
'@/src': join(rootPath, './src/'),
'@/render': join(srcPath, './render/'),
'@/main': join(srcPath, './main/'),
'@/lib': join(srcPath, './src/lib/'),
},
},
});

export default CommonConfig;
27 changes: 27 additions & 0 deletions rsbuild/react-electron/builder/main/rsbuild.main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { defineConfig, mergeRsbuildConfig } from '@rsbuild/core';
import { releaseMainPath, rootPath, srcMainPath } from '../common/paths';
import { join } from 'node:path';
import CommonConfig from '../common/rsbuild.common';

const Config = defineConfig({
tools: {
rspack: {
target: 'electron-main',
},
},
source: {
entry: {
index: join(srcMainPath, './index.ts'),
preload: join(srcMainPath, './preload.ts'),
},
},
output: {
target: 'node',
distPath: {
root: join(releaseMainPath),
},
cleanDistPath: true,
},
});

module.exports = mergeRsbuildConfig(CommonConfig, Config);
33 changes: 33 additions & 0 deletions rsbuild/react-electron/builder/render/rsbuild.dev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { defineConfig, mergeRsbuildConfig } from '@rsbuild/core';
import { pluginReact } from '@rsbuild/plugin-react';
import { join } from 'node:path';
import { spawn } from 'node:child_process';
import { srcRenderPath } from '../common/paths';
import CommonConfig from '../common/rsbuild.common';

const Config = defineConfig({
plugins: [pluginReact()],
source: {
entry: {
index: join(srcRenderPath, './index.tsx'),
},
},
server: {
port: Number(process.env.PORT),
},
dev: {
setupMiddlewares: [
(middlewares) => {
spawn('npm', ['run', 'dev:main'], {
shell: true,
stdio: 'inherit',
}).on('error', (spawnError: Error) => {
console.error(`Main Server err:${spawnError}`);
});
return middlewares;
},
],
},
});

module.exports = mergeRsbuildConfig(CommonConfig, Config);
1 change: 1 addition & 0 deletions rsbuild/react-electron/env/.env.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PORT=8090
10 changes: 10 additions & 0 deletions rsbuild/react-electron/mas/entitlements.mas.inherit.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>
20 changes: 20 additions & 0 deletions rsbuild/react-electron/mas/entitlements.mas.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>
5 changes: 5 additions & 0 deletions rsbuild/react-electron/nodemon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"watch": ["./src/main/**/*"],
"ext": "ts",
"exec": "npm run build:main && electron ./release/dist/main/index.js"
}
29 changes: 29 additions & 0 deletions rsbuild/react-electron/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "rsbuild-react-electron",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "npm run dev:render",
"dev:main": "nodemon",
"dev:render": "rsbuild dev --config ./builder/render/rsbuild.dev.ts",
"build:main": "rsbuild build --config ./builder/main/rsbuild.main.ts",
"postinstall": "electron-builder install-app-deps",
"build": "npm run build:main && npm run build:render && electron-builder -c builder.js ",
"lint": "pnpm biome check --write ./src"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@rsbuild/core": "^1.3.8",
"@rsbuild/plugin-react": "^1.2.0",
"@types/node": "^22.14.1",
"@types/react": "^18.3.20",
"@types/react-dom": "^18.3.6",
"electron": "^35.1.5",
"electron-builder": "^26.0.12",
"nodemon": "^3.1.9",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"typescript": "^5.8.3"
}
}
3 changes: 3 additions & 0 deletions rsbuild/react-electron/src/lib/node-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { app } from 'electron';

export const isAppDev = !app.isPackaged;
28 changes: 28 additions & 0 deletions rsbuild/react-electron/src/main/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { app, BrowserWindow } from 'electron';
import path from 'node:path';
import { isAppDev } from '@/lib/node-utils';

export let mainWindow: BrowserWindow | null = null;

const loadUrl: string = isAppDev
? `http://localhost:${process.env.PORT}`
: `file://${path.resolve(__dirname, '../render/index.html')}`;

const onCreateMainWindow = () => {
mainWindow = new BrowserWindow({
width: 1200,
minWidth: 1000,
height: 820,
minHeight: 700,
webPreferences: {
nodeIntegration: true,
webSecurity: false,
preload: path.resolve(__dirname, './preload.js'),
},
});
mainWindow.loadURL(loadUrl);
};

app.on('ready', async () => {
onCreateMainWindow();
});
14 changes: 14 additions & 0 deletions rsbuild/react-electron/src/main/preload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { type IpcRendererEvent, contextBridge, ipcRenderer } from 'electron';

contextBridge.exposeInMainWorld('IPC', {
invoke: (channel: string, data: any[]) => {
return ipcRenderer.invoke(channel, data);
},
ipcOn: (channel: string, fun: (event: IpcRendererEvent, data: any[]) => void) => {
const subscription = (event: IpcRendererEvent, data: any[]) => fun(event, data);
return ipcRenderer.on(channel, subscription);
},
removeAllListeners: (channel: string) => {
return ipcRenderer.removeAllListeners(channel);
},
});
Loading
Loading