Skip to content

Commit f75ffc0

Browse files
authored
修改开发和打包流程 (#23)
* 调整组织架构 * 更新图标 * 更新update * 更新方法 * 主进程在开发模式下会自动打开devtools和安装vue-devtools * 去除遗留排除项 * 调整配置 * 调整devtools加载位置 * 回退vite版本,解决element-plus开发时,字体文件丢失的问题 * 修正当启用严格模式时,由于没有声明导致出现undefined问题 * 添加排除对象 * 修改作者 * 修改复制app.zip路径 * 调整github workflows
1 parent ecd8b85 commit f75ffc0

27 files changed

+2546
-2599
lines changed

.electron-vite/build.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
'use strict'
2+
process.env.NODE_ENV = 'production'
3+
4+
const { say } = require('cfonts')
5+
const { sync } = require('del')
6+
7+
const chalk = require('chalk')
8+
const rollup = require("rollup")
9+
const { build } = require('vite')
10+
const Multispinner = require('multispinner')
11+
12+
const mainOptions = require('./rollup.Main.config');
13+
const rendererOptions = require('./vite.config')
14+
const opt = mainOptions(process.env.NODE_ENV);
15+
16+
const doneLog = chalk.bgGreen.white(' DONE ') + ' '
17+
const errorLog = chalk.bgRed.white(' ERROR ') + ' '
18+
const okayLog = chalk.bgBlue.white(' OKAY ') + ' '
19+
const isCI = process.env.CI || false
20+
21+
if (process.env.BUILD_TARGET === 'clean') clean()
22+
else if (process.env.BUILD_TARGET === 'web') web()
23+
else unionBuild()
24+
25+
function clean() {
26+
sync(['dist/electron/main/*', 'dist/electron/renderer/*', 'dist/web/*', 'build/*', '!build/icons', '!build/lib', '!build/lib/electron-build.*', '!build/icons/icon.*'])
27+
console.log(`\n${doneLog}clear done`)
28+
process.exit()
29+
}
30+
31+
function unionBuild() {
32+
greeting()
33+
sync(['dist/electron/main/*', 'dist/electron/renderer/*', 'build/*', '!build/icons', '!build/lib', '!build/lib/electron-build.*', '!build/icons/icon.*'])
34+
35+
const tasks = ['main', 'renderer']
36+
const m = new Multispinner(tasks, {
37+
preText: 'building',
38+
postText: 'process'
39+
})
40+
let results = ''
41+
42+
m.on('success', () => {
43+
process.stdout.write('\x1B[2J\x1B[0f')
44+
console.log(`\n\n${results}`)
45+
console.log(`${okayLog}take it away ${chalk.yellow('`electron-builder`')}\n`)
46+
process.exit()
47+
})
48+
49+
rollup.rollup(opt)
50+
.then(build => {
51+
results += `${doneLog}MainProcess build success` + '\n\n'
52+
build.write(opt.output).then(() => {
53+
m.success('main')
54+
})
55+
})
56+
.catch(error => {
57+
m.error('main')
58+
console.log(`\n ${errorLog}failed to build main process`)
59+
console.error(`\n${error}\n`)
60+
process.exit(1)
61+
});
62+
63+
build(rendererOptions).then(res => {
64+
results += `${doneLog}RendererProcess build success` + '\n\n'
65+
m.success('renderer')
66+
}).catch(err => {
67+
m.error('renderer')
68+
console.log(`\n ${errorLog}failed to build renderer process`)
69+
console.error(`\n${err}\n`)
70+
process.exit(1)
71+
})
72+
}
73+
74+
function web() {
75+
sync(['dist/web/*', '!.gitkeep'])
76+
build(rendererOptions).then(res => {
77+
console.log(`${doneLog}RendererProcess build success`)
78+
process.exit()
79+
})
80+
}
81+
82+
function greeting() {
83+
const cols = process.stdout.columns
84+
let text = ''
85+
86+
if (cols > 85) text = `let's-build`
87+
else if (cols > 60) text = `let's-|build`
88+
else text = false
89+
90+
if (text && !isCI) {
91+
say(text, {
92+
colors: ['yellow'],
93+
font: 'simple3d',
94+
space: false
95+
})
96+
} else console.log(chalk.yellow.bold(`\n let's-build`))
97+
console.log()
98+
}

.electron-vite/dev-runner.js

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
process.env.NODE_ENV = 'development'
2+
3+
const chalk = require('chalk')
4+
const electron = require('electron')
5+
const path = require('path')
6+
const rollup = require("rollup")
7+
const Portfinder = require("portfinder")
8+
9+
const { say } = require('cfonts')
10+
const { spawn } = require('child_process')
11+
const { createServer } = require('vite')
12+
13+
const rendererOptions = require("./vite.config")
14+
const mainOptions = require("./rollup.main.config")
15+
const opt = mainOptions(process.env.NODE_ENV);
16+
17+
let electronProcess = null
18+
let manualRestart = false
19+
20+
function logStats(proc, data) {
21+
let log = ''
22+
23+
log += chalk.yellow.bold(`┏ ${proc} 'Process' ${new Array((19 - proc.length) + 1).join('-')}`)
24+
log += '\n\n'
25+
26+
if (typeof data === 'object') {
27+
data.toString({
28+
colors: true,
29+
chunks: false
30+
}).split(/\r?\n/).forEach(line => {
31+
log += ' ' + line + '\n'
32+
})
33+
} else {
34+
log += ` ${data}\n`
35+
}
36+
37+
log += '\n' + chalk.yellow.bold(`┗ ${new Array(28 + 1).join('-')}`) + '\n'
38+
console.log(log)
39+
}
40+
41+
function removeJunk(chunk) {
42+
// Example: 2018-08-10 22:48:42.866 Electron[90311:4883863] *** WARNING: Textured window <AtomNSWindow: 0x7fb75f68a770>
43+
if (/\d+-\d+-\d+ \d+:\d+:\d+\.\d+ Electron(?: Helper)?\[\d+:\d+] /.test(chunk)) {
44+
return false;
45+
}
46+
47+
// Example: [90789:0810/225804.894349:ERROR:CONSOLE(105)] "Uncaught (in promise) Error: Could not instantiate: ProductRegistryImpl.Registry", source: chrome-devtools://devtools/bundled/inspector.js (105)
48+
if (/\[\d+:\d+\/|\d+\.\d+:ERROR:CONSOLE\(\d+\)\]/.test(chunk)) {
49+
return false;
50+
}
51+
52+
// Example: ALSA lib confmisc.c:767:(parse_card) cannot find card '0'
53+
if (/ALSA lib [a-z]+\.c:\d+:\([a-z_]+\)/.test(chunk)) {
54+
return false;
55+
}
56+
57+
58+
return chunk;
59+
}
60+
61+
function startRenderer() {
62+
return new Promise((resolve, reject) => {
63+
Portfinder.basePort = 9080
64+
Portfinder.getPort(async (err, port) => {
65+
if (err) {
66+
reject("PortError:" + err)
67+
} else {
68+
const server = await createServer(rendererOptions)
69+
process.env.PORT = port
70+
server.listen(port).then(() => {
71+
console.log('\n\n' + chalk.blue(' Preparing main process, please wait...') + '\n\n')
72+
})
73+
resolve()
74+
}
75+
})
76+
})
77+
}
78+
79+
function startMain() {
80+
return new Promise((resolve, reject) => {
81+
const watcher = rollup.watch(opt);
82+
watcher.on('change', filename => {
83+
// 主进程日志部分
84+
logStats('Main-FileChange', filename)
85+
});
86+
watcher.on('event', event => {
87+
if (event.code === 'END') {
88+
if (electronProcess && electronProcess.kill) {
89+
manualRestart = true
90+
process.kill(electronProcess.pid)
91+
electronProcess = null
92+
startElectron()
93+
94+
setTimeout(() => {
95+
manualRestart = false
96+
}, 5000)
97+
}
98+
99+
resolve()
100+
101+
} else if (event.code === 'ERROR') {
102+
reject(event.error)
103+
}
104+
})
105+
})
106+
}
107+
108+
function startElectron() {
109+
110+
var args = [
111+
'--inspect=5858',
112+
path.join(__dirname, '../dist/electron/main/main.js')
113+
]
114+
115+
// detect yarn or npm and process commandline args accordingly
116+
if (process.env.npm_execpath.endsWith('yarn.js')) {
117+
args = args.concat(process.argv.slice(3))
118+
} else if (process.env.npm_execpath.endsWith('npm-cli.js')) {
119+
args = args.concat(process.argv.slice(2))
120+
}
121+
122+
electronProcess = spawn(electron, args)
123+
124+
electronProcess.stdout.on('data', data => {
125+
electronLog(removeJunk(data), 'blue')
126+
})
127+
electronProcess.stderr.on('data', data => {
128+
electronLog(removeJunk(data), 'red')
129+
})
130+
131+
electronProcess.on('close', () => {
132+
if (!manualRestart) process.exit()
133+
})
134+
}
135+
136+
function electronLog(data, color) {
137+
if (data) {
138+
let log = ''
139+
data = data.toString().split(/\r?\n/)
140+
data.forEach(line => {
141+
log += ` ${line}\n`
142+
})
143+
if (/[0-9A-z]+/.test(log)) {
144+
console.log(
145+
chalk[color].bold(`┏ Electron -------------------`) +
146+
'\n\n' +
147+
log +
148+
chalk[color].bold('┗ ----------------------------') +
149+
'\n'
150+
)
151+
}
152+
}
153+
154+
}
155+
156+
function greeting() {
157+
const cols = process.stdout.columns
158+
let text = ''
159+
160+
if (cols > 104) text = 'electron-vite'
161+
else if (cols > 76) text = 'electron-|vite'
162+
else text = false
163+
164+
if (text) {
165+
say(text, {
166+
colors: ['yellow'],
167+
font: 'simple3d',
168+
space: false
169+
})
170+
} else console.log(chalk.yellow.bold('\n electron-vite'))
171+
console.log(chalk.blue(`getting ready...`) + '\n')
172+
}
173+
174+
async function init() {
175+
greeting()
176+
177+
try {
178+
await startRenderer()
179+
await startMain()
180+
await startElectron()
181+
} catch (error) {
182+
console.error(error)
183+
process.exit(1)
184+
}
185+
186+
}
187+
188+
init()
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
const path = require('path')
2+
const { nodeResolve } = require('@rollup/plugin-node-resolve')
3+
const commonjs = require('@rollup/plugin-commonjs')
4+
const esbuild = require('rollup-plugin-esbuild')
5+
const alias = require('@rollup/plugin-alias')
6+
const json = require('@rollup/plugin-json')
7+
8+
module.exports = (env = 'production') => {
9+
return {
10+
input: path.join(__dirname, '../src/main/main.js'),
11+
output: {
12+
file: path.join(__dirname, '../dist/electron/main/main.js'),
13+
format: 'cjs',
14+
name: 'MainProcess',
15+
sourcemap: false,
16+
},
17+
plugins: [
18+
nodeResolve({ jsnext: true, preferBuiltins: true, browser: true }), // 消除碰到 node.js 模块时⚠警告
19+
commonjs(),
20+
json(),
21+
esbuild({
22+
// All options are optional
23+
include: /\.[jt]sx?$/, // default, inferred from `loaders` option
24+
exclude: /node_modules/, // default
25+
// watch: process.argv.includes('--watch'), // rollup 中有配置
26+
sourceMap: false, // default
27+
minify: process.env.NODE_ENV === 'production',
28+
target: 'es2017', // default, or 'es20XX', 'esnext'
29+
// Like @rollup/plugin-replace
30+
define: {
31+
__VERSION__: '"x.y.z"'
32+
},
33+
// Add extra loaders
34+
loaders: {
35+
// Add .json files support
36+
// require @rollup/plugin-commonjs
37+
'.json': 'json',
38+
// Enable JSX in .js files too
39+
'.js': 'jsx'
40+
},
41+
}),
42+
alias({
43+
entries: [
44+
{ find: '@main', replacement: path.join(__dirname, '../src/main'), },
45+
]
46+
})
47+
],
48+
external: [
49+
'crypto',
50+
'assert',
51+
'fs',
52+
'util',
53+
'os',
54+
'events',
55+
'child_process',
56+
'http',
57+
'https',
58+
'path',
59+
'electron',
60+
'original-fs'
61+
],
62+
}
63+
}
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ const createZip = (filePath, dest) => {
1919

2020
const start = async () => {
2121
copyAppZip()
22-
const appPath = './out/Genshin Gacha Export-win32-x64/resources/app/'
22+
const appPath = './build/win-unpacked/resources/app'
2323
const name = 'app.zip'
24-
const outputPath = path.resolve('./update/update/')
24+
const outputPath = path.resolve('./build/update/update/')
2525
const zipPath = path.resolve(outputPath, name)
2626
await fs.ensureDir(outputPath)
2727
await fs.emptyDir(outputPath)
28-
await fs.outputFile('./update/CNAME', 'genshin-gacha-export.danmu9.com')
28+
await fs.outputFile('./build/update/CNAME', 'genshin-gacha-export.danmu9.com')
2929
createZip(appPath, zipPath)
3030
const buffer = await fs.readFile(zipPath)
3131
const sha256 = hash(buffer)
@@ -43,8 +43,8 @@ const start = async () => {
4343

4444
const copyAppZip = () => {
4545
try {
46-
const dir = path.resolve('./out/make/zip/win32/x64/')
47-
const filePath = path.resolve(dir, `Genshin Gacha Export-win32-x64-${version}.zip`)
46+
const dir = path.resolve('./build')
47+
const filePath = path.resolve(dir, `Genshin Gacha Export-${version}-win.zip`)
4848
fs.copySync(filePath, path.join(dir, 'app.zip'))
4949
} catch (e) {}
5050
}

0 commit comments

Comments
 (0)