refactor: build based vite alternative rollup
This commit is contained in:
parent
27a059e5dd
commit
2273453449
|
@ -0,0 +1,40 @@
|
|||
process.env.NODE_ENV = 'production'
|
||||
|
||||
import { build as viteBuild } from 'vite'
|
||||
import { build as electronBuild2 } from 'electron-builder'
|
||||
import { config as builderConfig } from './electron-builder.config.mjs'
|
||||
import chalk from 'chalk'
|
||||
|
||||
const TAG = chalk.bgBlue('[build.mjs]')
|
||||
|
||||
const viteConfigs = {
|
||||
main: 'src/main/vite.config.ts',
|
||||
preload: 'src/preload/vite.config.ts',
|
||||
reactTs: 'src/react-ts/vite.config.ts',
|
||||
}
|
||||
|
||||
async function buildElectron() {
|
||||
for (const [name, configPath] of Object.entries(viteConfigs)) {
|
||||
console.group(TAG, name)
|
||||
await viteBuild({ configFile: configPath, mode: process.env.NODE_ENV })
|
||||
console.groupEnd()
|
||||
console.log() // for beautiful log.
|
||||
}
|
||||
}
|
||||
|
||||
async function packElectron() {
|
||||
return electronBuild2({ config: builderConfig })
|
||||
.then(result => {
|
||||
console.log(TAG, chalk.green(`electron-builder.build result - ${result}`))
|
||||
})
|
||||
}
|
||||
|
||||
; (async () => {
|
||||
try {
|
||||
await buildElectron()
|
||||
await packElectron()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
process.exit(1)
|
||||
}
|
||||
})()
|
|
@ -1,76 +0,0 @@
|
|||
process.env.NODE_ENV = 'production'
|
||||
|
||||
import { join, relative } from 'path'
|
||||
import { build as viteBuild2 } from 'vite'
|
||||
import { build as electronBuild2 } from 'electron-builder'
|
||||
import { rollup, RollupOptions, OutputOptions, RollupOutput } from 'rollup'
|
||||
import { config as builderConfig } from './electron-builder.config'
|
||||
import chalk from 'chalk'
|
||||
import {
|
||||
mainOptions,
|
||||
preloadOptions,
|
||||
BuildResult,
|
||||
} from './utils'
|
||||
|
||||
const TAG = chalk.bgGray('[build.ts]')
|
||||
|
||||
// build main、preload
|
||||
async function rollupBuild(options: RollupOptions): Promise<BuildResult> {
|
||||
try {
|
||||
const build = await rollup(options)
|
||||
const optOutput = (options.output || {}) as OutputOptions
|
||||
const output = await build.write(optOutput)
|
||||
|
||||
output.output.forEach(out => {
|
||||
const relativePath = relative(__dirname, optOutput.dir as string)
|
||||
console.log(TAG, chalk.green(`Build successful - ${join(relativePath, out.fileName)}`))
|
||||
})
|
||||
|
||||
return [null, output]
|
||||
} catch (error: any) {
|
||||
console.error(TAG, chalk.red('Build failed:\n'), error)
|
||||
return [error, null]
|
||||
}
|
||||
}
|
||||
|
||||
// build react-ts
|
||||
async function buildReactTs(): Promise<BuildResult> {
|
||||
try {
|
||||
const output = await viteBuild2({
|
||||
root: join(__dirname, '../react-ts'),
|
||||
configFile: join(__dirname, '../react-ts/vite.config.ts'),
|
||||
}) as RollupOutput
|
||||
|
||||
return [null, output]
|
||||
} catch (error: any) {
|
||||
return [error, null]
|
||||
}
|
||||
}
|
||||
|
||||
// build electron
|
||||
async function electronBuild() {
|
||||
try {
|
||||
const result = await electronBuild2({ config: builderConfig })
|
||||
|
||||
console.log(TAG, chalk.green(`electron-builder.build result - ${result}`))
|
||||
return [null, result]
|
||||
} catch (error) {
|
||||
return [error, null]
|
||||
}
|
||||
}
|
||||
|
||||
; (async () => {
|
||||
console.log(TAG, chalk.blue('Build with rollup.'))
|
||||
try {
|
||||
await Promise.all([
|
||||
// Avoid logs cleaned by vite
|
||||
rollupBuild(mainOptions()),
|
||||
rollupBuild(preloadOptions()),
|
||||
])
|
||||
await buildReactTs()
|
||||
await electronBuild()
|
||||
} catch (error) {
|
||||
console.error(TAG, chalk.red(error))
|
||||
process.exit(1)
|
||||
}
|
||||
})();
|
|
@ -1,80 +0,0 @@
|
|||
process.env.NODE_ENV = 'development'
|
||||
|
||||
import { join } from 'path'
|
||||
import electron from 'electron'
|
||||
import { spawn, ChildProcess } from 'child_process'
|
||||
import { createServer as createViteServer } from 'vite'
|
||||
import { RollupWatcher, RollupWatcherEvent, watch } from 'rollup'
|
||||
import WebSocket from 'ws'
|
||||
import chalk from 'chalk'
|
||||
import pkg from '../package.json'
|
||||
import {
|
||||
mainOptions,
|
||||
preloadOptions,
|
||||
} from './utils'
|
||||
import { createWsServer, formatWsSendData } from './ws'
|
||||
|
||||
const TAG = chalk.bgGray('[dev.ts]')
|
||||
|
||||
function eventHandle(ev: RollupWatcherEvent) {
|
||||
if (ev.code === 'ERROR') {
|
||||
console.error(TAG, chalk.red(ev.error))
|
||||
} else if (ev.code === 'BUNDLE_START') {
|
||||
console.log(TAG, chalk.blue(`Rebuild - ${ev.output}`))
|
||||
}
|
||||
}
|
||||
|
||||
function watchMain(): RollupWatcher {
|
||||
let electronProcess: ChildProcess | null = null
|
||||
|
||||
return watch(mainOptions())
|
||||
.on('event', ev => {
|
||||
if (ev.code === 'END') {
|
||||
electronProcess && electronProcess.kill()
|
||||
electronProcess = spawn(
|
||||
electron as unknown as string,
|
||||
[join(__dirname, '..', pkg.main)],
|
||||
{ stdio: 'inherit', env: Object.assign(process.env, pkg.env) },
|
||||
)
|
||||
} else if (ev.code === 'ERROR') {
|
||||
electronProcess && electronProcess.kill()
|
||||
electronProcess = null
|
||||
}
|
||||
|
||||
eventHandle(ev)
|
||||
})
|
||||
}
|
||||
|
||||
function watchPreload(): RollupWatcher {
|
||||
const wssObj = createWsServer({ TAG })
|
||||
|
||||
return watch(preloadOptions())
|
||||
.on('event', ev => {
|
||||
if (ev.code === 'END') {
|
||||
// Hot reload renderer process !!!
|
||||
if (wssObj.instance?.readyState === WebSocket.OPEN) {
|
||||
console.log(TAG, chalk.yellow('Hot reload renderer process'))
|
||||
wssObj.instance.send(formatWsSendData({ cmd: 'reload', data: Date.now() }))
|
||||
}
|
||||
}
|
||||
|
||||
eventHandle(ev)
|
||||
})
|
||||
}
|
||||
|
||||
; (async () => {
|
||||
try {
|
||||
const server = await (await createViteServer({
|
||||
root: join(__dirname, '../react-ts'),
|
||||
configFile: join(__dirname, '../react-ts/vite.config.ts'),
|
||||
})).listen()
|
||||
const { host = '127.0.0.1', port = 3000 } = server.config.server
|
||||
|
||||
console.log(TAG, chalk.yellow(`Server run at - http://${host}:${port}`))
|
||||
|
||||
watchPreload()
|
||||
watchMain()
|
||||
} catch (error) {
|
||||
console.error(TAG, chalk.red(error))
|
||||
}
|
||||
})();
|
|
@ -1,14 +1,16 @@
|
|||
import { Configuration } from 'electron-builder'
|
||||
|
||||
const config: Configuration = {
|
||||
/**
|
||||
* @type {import('electron-builder').Configuration}
|
||||
*/
|
||||
const config = {
|
||||
appId: "308487730@qq.com",
|
||||
asar: true,
|
||||
directories: {
|
||||
output: "release/${version}"
|
||||
},
|
||||
files: [
|
||||
"!node_modules",
|
||||
"dist/**"
|
||||
"dist",
|
||||
"package.json"
|
||||
],
|
||||
mac: {
|
||||
artifactName: "${productName}_${version}.${ext}",
|
|
@ -1,41 +0,0 @@
|
|||
import { builtinModules } from 'module'
|
||||
import { RollupOptions } from 'rollup'
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve'
|
||||
import typescript from '@rollup/plugin-typescript'
|
||||
import commonjs from '@rollup/plugin-commonjs'
|
||||
import replace from '@rollup/plugin-replace'
|
||||
// import swc from 'rollup-plugin-swc'
|
||||
|
||||
function optionsFactory(options: RollupOptions): RollupOptions {
|
||||
return {
|
||||
input: options.input,
|
||||
output: {
|
||||
name: '[name].js',
|
||||
format: 'cjs',
|
||||
...options.output,
|
||||
},
|
||||
plugins: [
|
||||
commonjs(),
|
||||
nodeResolve({
|
||||
extensions: ['.ts', '.js', 'json'],
|
||||
}),
|
||||
typescript(),
|
||||
// swc(), Error: Cannot find module 'regenerator-runtime',
|
||||
replace({
|
||||
...Object
|
||||
.entries({ NODE_ENV: process.env.NODE_ENV })
|
||||
.reduce(
|
||||
(acc, [k, v]) => Object.assign(acc, { [`process.env.${k}`]: JSON.stringify(v) }),
|
||||
{},
|
||||
),
|
||||
preventAssignment: true,
|
||||
}),
|
||||
],
|
||||
external: [
|
||||
'electron',
|
||||
...builtinModules,
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
export { optionsFactory }
|
|
@ -1,33 +0,0 @@
|
|||
import { join } from 'path'
|
||||
import { readdirSync } from 'fs'
|
||||
import { OutputOptions, rollup, RollupOptions, RollupOutput, RollupError } from 'rollup'
|
||||
import { optionsFactory } from './rollup.config'
|
||||
|
||||
export type BuildResult = [RollupError | null, RollupOutput | null]
|
||||
|
||||
function mainOptions(): RollupOptions {
|
||||
return optionsFactory({
|
||||
input: join(__dirname, '../main/index.ts'),
|
||||
output: {
|
||||
dir: 'dist/main',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function preloadOptions(): RollupOptions {
|
||||
const dirs = readdirSync(join(__dirname, '../preload'))
|
||||
const inputs = dirs.filter(name => /^index\..+\.ts$/.test(name))
|
||||
|
||||
return optionsFactory({
|
||||
input: inputs.map(input => join(__dirname, '../preload', input)),
|
||||
output: {
|
||||
dir: 'dist/preload',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
mainOptions,
|
||||
preloadOptions,
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
process.env.NODE_ENV = 'production'
|
||||
|
||||
import { readFileSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
import electron from 'electron'
|
||||
import { spawn } from 'child_process'
|
||||
import { createServer, build as viteBuild } from 'vite'
|
||||
import chalk from 'chalk'
|
||||
|
||||
const TAG = chalk.bgGreen('[dev.mjs]')
|
||||
const pkg = JSON.parse(readFileSync(join(process.cwd(), 'package.json'), 'utf8'))
|
||||
|
||||
/**
|
||||
* @param {{ name: string; configFile: string; writeBundle: import('rollup').OutputPlugin['writeBundle'] }} param0
|
||||
* @returns {import('rollup').RollupWatcher}
|
||||
*/
|
||||
function getWatcher({ name, configFile, writeBundle }) {
|
||||
return viteBuild({
|
||||
// Options here precedence over configFile
|
||||
build: {
|
||||
watch: {},
|
||||
},
|
||||
configFile,
|
||||
plugins: [
|
||||
{ name, writeBundle },
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<import('rollup').RollupWatcher>}
|
||||
*/
|
||||
async function watchMain() {
|
||||
/**
|
||||
* @type {import('child_process').ChildProcessWithoutNullStreams | null}
|
||||
*/
|
||||
let electronProcess = null
|
||||
|
||||
/**
|
||||
* @type {import('rollup').RollupWatcher}
|
||||
*/
|
||||
const watcher = await getWatcher({
|
||||
name: 'electron-main-watcher',
|
||||
configFile: 'src/main/vite.config.ts',
|
||||
writeBundle() {
|
||||
electronProcess && electronProcess.kill()
|
||||
electronProcess = spawn(electron, ['.'], {
|
||||
stdio: 'inherit',
|
||||
env: Object.assign(process.env, pkg.env), // Why don't work?
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
return watcher
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('vite').ViteDevServer} viteDevServer
|
||||
* @returns {Promise<import('rollup').RollupWatcher>}
|
||||
*/
|
||||
async function watchPreload(viteDevServer) {
|
||||
return getWatcher({
|
||||
name: 'electron-preload-watcher',
|
||||
configFile: 'src/preload/vite.config.ts',
|
||||
writeBundle() {
|
||||
viteDevServer.ws.send({
|
||||
type: 'full-reload',
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
; (async () => {
|
||||
const viteDevServer = await createServer({ configFile: 'src/react-ts/vite.config.ts' })
|
||||
|
||||
await viteDevServer.listen()
|
||||
|
||||
await watchPreload(viteDevServer)
|
||||
await watchMain()
|
||||
})()
|
|
@ -1,43 +0,0 @@
|
|||
/**
|
||||
* Hot reload from preload script during development
|
||||
*/
|
||||
import WebSocket from 'ws'
|
||||
import chalk from 'chalk'
|
||||
import pkg from '../package.json'
|
||||
|
||||
export interface CreateWsServerOptions {
|
||||
TAG: string
|
||||
}
|
||||
|
||||
export function createWsServer(options: CreateWsServerOptions) {
|
||||
const { TAG } = options
|
||||
const port = pkg.env.PORT_WS
|
||||
const host = pkg.env.HOST || '127.0.0.1'
|
||||
const wss = new WebSocket.Server({ host, port })
|
||||
const wssObj: { wss: WebSocket.Server; instance: WebSocket | null } = { wss, instance: null }
|
||||
|
||||
console.log(TAG, 'Wss run at - ' + chalk.yellow(`ws://${host}:${port}`))
|
||||
|
||||
wss.on('connection', ws => {
|
||||
console.log(TAG, chalk.yellow(`wss.on('connection')`))
|
||||
|
||||
wssObj.instance = ws
|
||||
ws.on('message', message => {
|
||||
console.log(TAG, `ws.on('message'):`, message.toString())
|
||||
})
|
||||
|
||||
ws.send(formatWsSendData({ cmd: 'message', data: 'connected.' }))
|
||||
})
|
||||
|
||||
wss.on('close', () => {
|
||||
console.log(TAG, chalk.gray(`wss.on('close')`))
|
||||
|
||||
wssObj.instance = null
|
||||
})
|
||||
|
||||
return wssObj
|
||||
}
|
||||
|
||||
export function formatWsSendData(json: { cmd: string, data?: any }) {
|
||||
return JSON.stringify(json)
|
||||
}
|
Loading…
Reference in New Issue