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",
|
appId: "308487730@qq.com",
|
||||||
asar: true,
|
asar: true,
|
||||||
directories: {
|
directories: {
|
||||||
output: "release/${version}"
|
output: "release/${version}"
|
||||||
},
|
},
|
||||||
files: [
|
files: [
|
||||||
"!node_modules",
|
"dist",
|
||||||
"dist/**"
|
"package.json"
|
||||||
],
|
],
|
||||||
mac: {
|
mac: {
|
||||||
artifactName: "${productName}_${version}.${ext}",
|
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