wip: support electron

This commit is contained in:
Gavin Chain 2021-06-07 12:36:48 +08:00 committed by Vben
parent aee613034f
commit d4c4215b08
7 changed files with 1453 additions and 76 deletions

2
.env
View File

@ -1,3 +1,5 @@
PORT = 3100
# port
VITE_PORT = 3100

View File

@ -0,0 +1,13 @@
import { createServer } from 'vite';
import { execSync } from 'child_process';
import path from 'path';
(async () => {
const server = await createServer({
root: path.resolve(__dirname, '../../'),
});
await server.listen();
execSync('node script/build --env=development --watch');
})();

71
config/electron/index.ts Normal file
View File

@ -0,0 +1,71 @@
/**
* electron
*/
import dotenv from 'dotenv';
import { app, BrowserWindow, ipcMain } from 'electron';
import is_dev from 'electron-is-dev';
// @ts-ignore
import Store from 'electron-store';
import { join } from 'path';
const store = new Store();
// @ts-ignore
ipcMain.on('store:set', async (e, args) => {
store.set(args.key, args.value);
});
// @ts-ignore
ipcMain.handle('store:get', async (e, args) => {
return await store.get(args);
});
// @ts-ignore
ipcMain.on('store:delete', async (e, args) => {
store.delete(args);
});
dotenv.config({ path: join(__dirname, '../../.env') });
let win = null;
class createWin {
// 创建浏览器窗口
constructor() {
// @ts-ignore
win = new BrowserWindow({
width: 930,
height: 700,
frame: false,
transparent: true,
webPreferences: {
devTools: true,
nodeIntegration: true,
enableRemoteModule: true,
},
});
// win.webContents.openDevTools()
// @ts-ignore
win.maximize();
// win.maximize()
const URL = is_dev
? `http://localhost:${process.env.PORT}` // vite 启动的服务器地址
: `file://${join(__dirname, '../../dist/render/index.html')}`; // vite 构建后的静态文件地址
// @ts-ignore
win.loadURL(URL);
}
}
app.whenReady().then(() => new createWin());
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
new createWin();
}
});

View File

@ -6,10 +6,55 @@
"email": "anncwb@126.com",
"url": "https://github.com/anncwb"
},
"build": {
"appId": "xxx@gmail.com",
"electronDownload": {
"mirror": "https://npm.taobao.org/mirrors/electron/"
},
"files": [
"!node_modules",
"dist/**"
],
"asar": false,
"mac": {
"artifactName": "${productName}_setup_${version}.${ext}",
"target": [
"dmg"
]
},
"linux": {
"icon": "build/icons/512x512.png",
"target": [
"deb"
]
},
"win": {
"target": [
{
"target": "nsis",
"arch": [
"x64"
]
}
],
"artifactName": "${productName}_setup_${version}.${ext}"
},
"nsis": {
"oneClick": false,
"perMachine": false,
"allowToChangeInstallationDirectory": true,
"deleteAppDataOnUninstall": false
}
},
"main": "dist/main/build.js",
"scripts": {
"dev": "vite",
"app": "esno ./build/script/runApp.ts",
"app:build": "npm run build && node script/build && electron-builder ",
"app:vue": "vite --force",
"app:ele": "node script/build --env=development --watch",
"bootstrap": "yarn install",
"serve": "npm run dev",
"dev": "vite",
"build": "vite build && esno ./build/script/postBuild.ts",
"build:no-cache": "yarn clean:cache && npm run build",
"report": "cross-env REPORT=true npm run build",
@ -32,6 +77,8 @@
"postinstall": "npm run install:husky"
},
"dependencies": {
"electron-is-dev": "^1.2.0",
"electron-store": "^6.0.0",
"@iconify/iconify": "^2.0.1",
"@logicflow/core": "^0.4.11",
"@logicflow/extension": "^0.4.12",
@ -61,6 +108,18 @@
"xlsx": "^0.17.0"
},
"devDependencies": {
"rollup-plugin-esbuild": "^3.0.2",
"@rollup/plugin-alias": "^3.1.1",
"@rollup/plugin-commonjs": "^15.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"wait-on": "^5.2.1",
"electron-contextmenu-middleware": "^1.0.3",
"electron-input-menu": "^2.1.0",
"electron": "^11.0.0",
"electron-builder": "^22.8.0",
"electron-connect": "^0.6.3",
"concurrently": "^5.3.0",
"@commitlint/cli": "^12.1.4",
"@commitlint/config-conventional": "^12.1.4",
"@iconify/json": "^1.1.350",

74
script/build.js Normal file
View File

@ -0,0 +1,74 @@
/**
* electron 打包
*/
const path = require('path');
const rollup = require('rollup');
const argv = require('minimist')(process.argv.slice(2));
const chalk = require('chalk');
const ora = require('ora');
const waitOn = require('wait-on');
const electron = require('electron-connect').server.create({ stopOnClose: true });
require('dotenv').config({ path: path.join(__dirname, '../.env') });
const options = require('./rollup.config');
const net = require('net');
const { URL } = require('url');
const opt = options(argv.env);
const TAG = '[script/build.js]';
const spinner = ora(`${TAG} Electron build...`);
const watchFunc = function () {
// once here, all resources are available
const watcher = rollup.watch(opt);
watcher.on('change', (filename) => {
const log = chalk.green(`change -- ${filename}`);
console.log(TAG, log);
});
watcher.on('event', (ev) => {
if (ev.code === 'END') {
// init-未启动、started-第一次启动、restarted-重新启动
electron.electronState === 'init' ? electron.start() : electron.restart();
} else if (ev.code === 'ERROR') {
console.log(ev.error);
}
});
};
const resource = `http://localhost:${process.env.PORT}/index.html`; // 因为 vite 不会重定向到 index.html所以直接写 index.html 路由。
if (argv.watch) {
waitOn(
{
resources: [resource],
timeout: 5000,
},
(err) => {
if (err) {
const { port, hostname } = new URL(resource);
const serverSocket = net.connect(port || 80, hostname, () => {
watchFunc();
});
serverSocket.on('error', (e) => {
console.log(err);
console.log(e);
process.exit(1);
});
} else {
watchFunc();
}
}
);
} else {
spinner.start();
rollup
.rollup(opt)
.then((build) => {
spinner.stop();
console.log(TAG, chalk.green('Electron build successed.'));
build.write(opt.output);
})
.catch((error) => {
spinner.stop();
console.log(`\n${TAG} ${chalk.red('构建报错')}\n`, error, '\n');
});
}

63
script/rollup.config.js Normal file
View File

@ -0,0 +1,63 @@
const path = require('path');
const { nodeResolve } = require('@rollup/plugin-node-resolve');
const commonjs = require('@rollup/plugin-commonjs');
const esbuild = require('rollup-plugin-esbuild');
const alias = require('@rollup/plugin-alias');
const json = require('@rollup/plugin-json');
module.exports = (env = 'production') => {
console.log('环境:' + env);
return {
input: path.join(__dirname, '../config/electron/index.ts'),
output: {
file: path.join(__dirname, '../dist/main/build.js'),
format: 'cjs',
name: 'ElectronMainBundle',
sourcemap: true,
},
plugins: [
nodeResolve({ jsnext: true, preferBuiltins: true, browser: true }), // 消除碰到 node.js 模块时⚠警告
commonjs(),
json(),
esbuild({
// All options are optional
include: /\.[jt]sx?$/, // default, inferred from `loaders` option
exclude: /node_modules/, // default
// watch: process.argv.includes('--watch'), // rollup 中有配置
sourceMap: false, // default
minify: process.env.NODE_ENV === 'production',
target: 'es2017', // default, or 'es20XX', 'esnext'
jsxFactory: 'React.createElement',
jsxFragment: 'React.Fragment',
// Like @rollup/plugin-replace
define: {
__VERSION__: '"x.y.z"',
},
// Add extra loaders
loaders: {
// Add .json files support
// require @rollup/plugin-commonjs
'.json': 'json',
// Enable JSX in .js files too
'.js': 'jsx',
},
}),
alias({
entries: [{ find: '@main', replacement: path.join(__dirname, '../src/main') }],
}),
],
external: [
'crypto',
'assert',
'fs',
'util',
'os',
'events',
'child_process',
'http',
'https',
'path',
'electron',
],
};
};

1245
yarn.lock

File diff suppressed because it is too large Load Diff