From ed8ccf8f2089fe98511ae8ee90044e1bc4342511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8D=89=E9=9E=8B=E6=B2=A1=E5=8F=B7?= <308487730@qq.com> Date: Thu, 9 Sep 2021 09:35:21 +0800 Subject: [PATCH] refactor: build script --- script/build-main.ts | 101 ++++++++++++---------------------------- script/build-preload.ts | 64 +++++++++++-------------- script/rollup.config.ts | 64 +++++++++++++++++++++++++ script/utils.ts | 29 +++++++++++- 4 files changed, 149 insertions(+), 109 deletions(-) create mode 100644 script/rollup.config.ts diff --git a/script/build-main.ts b/script/build-main.ts index 20dd593..a6e4b74 100644 --- a/script/build-main.ts +++ b/script/build-main.ts @@ -1,34 +1,26 @@ -/** - * Electron main process package script - */ -import { join } from 'path' +import path from 'path' +import { watch, rollup, OutputOptions } from 'rollup' import { spawn, ChildProcess } from 'child_process' -import { watch, rollup, RollupOptions, OutputOptions } from 'rollup' -import nodeResolve from '@rollup/plugin-node-resolve' -import commonjs from '@rollup/plugin-commonjs' -import typescript from '@rollup/plugin-typescript' -import alias from '@rollup/plugin-alias' -import json from '@rollup/plugin-json' -import { builtins } from './utils' +import electron from 'electron' import minimist from 'minimist' import chalk from 'chalk' import ora from 'ora' -import electron from 'electron' -import dotenv from 'dotenv' -import { waitOn } from './utils' +import { waitOn, getEnv } from './utils' +import options from './rollup.config' import { main } from '../package.json' -// Inject some environment variables from ".env" -dotenv.config({ path: join(__dirname, '../.env') }) - +const env = getEnv() const argv = minimist(process.argv.slice(2)) -const opts = configFactory(argv.env) +const opt = options({ proc: 'main', env: argv.env }) const TAG = '[build-main.ts]' -const spinner = ora(`${TAG} Electron build...`) +const spinner = ora(`${TAG} Electron main build...`) -if (argv.watch) { - waitOn({ port: process.env.PORT as string }).then(msg => { - const watcher = watch(opts) +; (async () => { + if (argv.watch) { + // Wait on vite server launched + await waitOn({ port: env.PORT as string }) + + const watcher = watch(opt) let child: ChildProcess watcher.on('change', filename => { const log = chalk.green(`change -- ${filename}`) @@ -38,59 +30,26 @@ if (argv.watch) { if (ev.code === 'END') { if (child) child.kill() child = spawn( - electron as any, - [join(__dirname, `../${main}`)], - { - stdio: 'inherit', - env: Object.assign(process.env, { NODE_ENV: argv.env }), - }) + electron as unknown as string, + [path.join(__dirname, `../${main}`)], + { stdio: 'inherit' }, + ) } else if (ev.code === 'ERROR') { console.log(ev.error) } }) - }) -} else { - spinner.start() - rollup(opts) - .then(build => { - spinner.stop() - console.log(TAG, chalk.green('Electron build successed.')) - build.write(opts.output as OutputOptions) - }) - .catch(error => { - spinner.stop() + } else { + spinner.start() + try { + const build = await rollup(opt) + await build.write(opt.output as OutputOptions) + spinner.succeed() + process.exit() + } catch (error) { console.log(`\n${TAG} ${chalk.red('构建报错')}\n`, error, '\n') - }) -} - -function configFactory(env = 'production') { - const options: RollupOptions = { - input: join(__dirname, '../src/main/index.ts'), - output: { - file: join(__dirname, '../dist/main/index.js'), - format: 'cjs', - name: 'ElectronMainBundle', - sourcemap: true, - }, - plugins: [ - nodeResolve(), - commonjs(), - json(), - typescript(), - alias({ - entries: [ - { find: '@render', replacement: join(__dirname, '../src/render') }, - { find: '@main', replacement: join(__dirname, '../src/main') }, - { find: '@src', replacement: join(__dirname, '../src') }, - { find: '@root', replacement: join(__dirname, '..') }, - ] - }), - ], - external: [ - ...builtins(), - 'electron', - ], + spinner.fail() + process.exit(1) + } } +})(); - return options -} diff --git a/script/build-preload.ts b/script/build-preload.ts index 710d429..fadf0dc 100644 --- a/script/build-preload.ts +++ b/script/build-preload.ts @@ -1,46 +1,36 @@ -/** - * Electron main preload package script - */ -import { join } from 'path' -import { watch, rollup, RollupOptions, OutputOptions } from 'rollup' -import { builtins } from './utils' +import { watch, rollup, OutputOptions } from 'rollup' import minimist from 'minimist' import chalk from 'chalk' +import ora from 'ora' +import options from './rollup.config' const argv = minimist(process.argv.slice(2)) -const opts = configFactory(argv.env) +const opt = options({ proc: 'preload', env: argv.env }) const TAG = '[build-preload.ts]' +const spinner = ora(`${TAG} Electron preload build...`) -if (argv.watch) { - const watcher = watch(opts) - watcher.on('change', filename => { - const log = chalk.yellow(`change -- ${filename}`) - console.log(TAG, log) - }) -} else { - rollup(opts) - .then(build => { - console.log(TAG, chalk.yellow('"preload/index.js" built.')) - build.write(opts.output as OutputOptions) +; (async () => { + if (argv.watch) { + const watcher = watch(opt) + watcher.on('change', filename => { + const log = chalk.yellow(`change -- ${filename}`) + console.log(TAG, log) + + /** + * @todo Hot reload render process !!! + */ }) - .catch(error => { + } else { + spinner.start() + try { + const build = await rollup(opt) + await build.write(opt.output as OutputOptions) + spinner.succeed() + process.exit() + } catch (error) { console.log(`\n${TAG} ${chalk.red('构建报错')}\n`, error, '\n') - }) -} - -function configFactory(env = 'production') { - const options: RollupOptions = { - input: join(__dirname, '../src/preload/index.js'), - output: { - file: join(__dirname, '../dist/preload/index.js'), - format: 'iife', - }, - plugins: [], - external: [ - ...builtins(), - 'electron', - ], + spinner.fail() + process.exit(1) + } } - - return options -} +})(); diff --git a/script/rollup.config.ts b/script/rollup.config.ts new file mode 100644 index 0000000..6c572a6 --- /dev/null +++ b/script/rollup.config.ts @@ -0,0 +1,64 @@ +import path from 'path' +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 alias from '@rollup/plugin-alias' +import json from '@rollup/plugin-json' +import { builtins, getEnv } from './utils' + +export interface ConfigOptions { + env?: typeof process.env.NODE_ENV + proc: 'main' | 'render' | 'preload' +} + +export default function (opts: ConfigOptions) { + const sourcemap = opts.proc === 'render' + const options: RollupOptions = { + input: path.join(__dirname, `../src/${opts.proc}/index.ts`), + output: { + dir: path.join(__dirname, `../dist/${opts.proc}`), + format: 'cjs', + sourcemap, + }, + plugins: [ + nodeResolve({ + extensions: ['.ts', '.js', 'json'], + }), + commonjs(), + json(), + typescript({ + sourceMap: sourcemap, + noEmitOnError: true, + }), + alias({ + entries: { + '@root': path.join(__dirname, '..'), + '@': path.join(__dirname, '../src'), + }, + }), + replace({ + ...Object + .entries({ ...getEnv(), NODE_ENV: opts.env }) + .reduce( + (acc, [k, v]) => Object.assign(acc, { [`process.env.${k}`]: JSON.stringify(v) }), + {}, + ), + preventAssignment: true, + }), + ], + external: [ + ...builtins(), + 'electron', + ], + onwarn: warning => { + // https://github.com/rollup/rollup/issues/1089#issuecomment-365395213 + if (warning.code !== 'CIRCULAR_DEPENDENCY') { + console.error(`(!) ${warning.message}`) + } + }, + } + + return options +} diff --git a/script/utils.ts b/script/utils.ts index c838158..c946e48 100644 --- a/script/utils.ts +++ b/script/utils.ts @@ -1,10 +1,14 @@ +import fs from 'fs' +import path from 'path' import { builtinModules } from 'module' import { get } from 'http' import { green } from 'chalk' +import { Plugin } from 'rollup' +import { parse as parseEnv } from 'dotenv' /** 轮询监听 vite 启动 */ export function waitOn(arg0: { port: string | number; interval?: number; }) { - return new Promise(resolve => { + return new Promise(resolve => { const { port, interval = 149 } = arg0 const url = `http://localhost:${port}` let counter = 0 @@ -22,3 +26,26 @@ export function waitOn(arg0: { port: string | number; interval?: number; }) { /** node.js builtins module */ export const builtins = () => builtinModules.filter(x => !/^_|^(internal|v8|node-inspect)\/|\//.test(x)) + +/** + * @todo + * typescript with esbuild + */ +export function typescript(): Plugin { + return { + name: 'cxmh:rollup-typescript-esbuild', + } +} + +export function getEnv(): Record { + try { + if (getEnv.env) { + return getEnv.env + } + const env = parseEnv(fs.readFileSync(path.join(process.cwd(), '.env'))) + return getEnv.env = env + } catch (error) { + return {} + } +} +getEnv.env = undefined as (Record | undefined) // Just fix ts check