diff --git a/package.json b/package.json index cb3d9e86..845a2612 100644 --- a/package.json +++ b/package.json @@ -32,4 +32,4 @@ "simple-git-hooks": { "pre-commit": "npx lint-staged" } -} \ No newline at end of file +} diff --git a/packages/builder/node/log.ts b/packages/builder/node/log.ts index 26ee52ad..b2f1cb9c 100644 --- a/packages/builder/node/log.ts +++ b/packages/builder/node/log.ts @@ -1,3 +1,4 @@ +// Borrowed from https://github.com/egoist/tsup/blob/main/src/log.ts import * as colors from 'colorette' type LOG_TYPE = 'info' | 'success' | 'error' | 'warn' diff --git a/packages/builder/node/main.ts b/packages/builder/node/main.ts index 615bade3..963f3688 100644 --- a/packages/builder/node/main.ts +++ b/packages/builder/node/main.ts @@ -4,11 +4,10 @@ import type { ChildProcess } from 'child_process' import { spawn } from 'child_process' import fs from 'fs' import { bgCyan, bgCyanBright, bgGreen, cyan, greenBright } from 'colorette' -import { build as electronBuilder } from 'electron-builder' import { build as tsupBuild } from 'tsup' -import electron from 'electron' import type { Options as TsupOptions } from 'tsup' import waitOn from 'wait-on' +import { checkPackageExists } from 'check-package-exists' import { TAG } from './constants' import { resolveConfig } from './config' import type { AppType } from './config' @@ -44,12 +43,12 @@ function exitMainProcess() { process.exit(0) } -function runMainProcess(mainFile: string, isElectron: boolean) { +function runMainProcess(mainFile: string, electron: any) { if (!fs.existsSync(mainFile)) throw new Error(`Main file not found: ${mainFile}`) logger.success(TAG, `⚡ Run main file: ${greenBright(mainFile)}`) - return spawn(isElectron ? electron as any : 'node', [mainFile], { stdio: 'inherit' }).on('exit', exitMainProcess) + return spawn(electron ?? 'node', [mainFile], { stdio: 'inherit' }).on('exit', exitMainProcess) } /** @@ -79,6 +78,13 @@ function doTsupBuild(opts: TsupOptions) { }) } +function electronEnvCheck() { + if (!checkPackageExists('electron')) + throw new Error('"Application type: electron" is powered by "electron", please installed it via `npm i electron -D`') + + return true +} + export async function build(type: AppType) { const isElectron = type === 'electron' const startTime = performance.now() @@ -86,6 +92,8 @@ export async function build(type: AppType) { logger.info(TAG, `Mode: ${bgCyanBright('Production')}`) logger.info(TAG, `Application type: ${isElectron ? bgCyan(' electron ') : bgGreen(' node ')}`) + isElectron && electronEnvCheck() + const config = await resolveConfig() getMainFileAndCheck(config.cwd, config.main) @@ -98,6 +106,11 @@ export async function build(type: AppType) { const { electron: electronConfig } = config if (isElectron && electronConfig.build && electronConfig.build.disabled !== true) { + if (!checkPackageExists('electron-builder')) + throw new Error('"electronConfig.build" is powered by "electron-builder", please installed it via `npm i electron-builder -D`') + + const { build: electronBuilder } = await import('electron-builder') + logger.info(TAG, 'Start electron build...\n') await electronBuilder({ @@ -117,6 +130,10 @@ export async function dev(type: AppType) { logger.info(TAG, `Mode: ${bgCyanBright('Development')}`) logger.info(TAG, `Application type: ${isElectron ? bgCyan(' electron ') : bgGreen(' node ')}`) + let electron: any | undefined + if (isElectron && electronEnvCheck()) + electron = await import('electron') + const config = await resolveConfig() let child: ChildProcess @@ -132,7 +149,7 @@ export async function dev(type: AppType) { userOnRebuild = options.watch.onRebuild options.watch = { - onRebuild(error, result) { + onRebuild: async (error, result) => { userOnRebuild?.(error, result) if (error) { @@ -145,7 +162,7 @@ export async function dev(type: AppType) { child.kill() } - child = runMainProcess(mainFile!, isElectron) + child = runMainProcess(mainFile!, electron) } }, } @@ -167,6 +184,5 @@ export async function dev(type: AppType) { } } - child = runMainProcess(mainFile, isElectron) + child = runMainProcess(mainFile, electron) } - diff --git a/packages/runner/node/log.ts b/packages/runner/node/log.ts index 26ee52ad..b2f1cb9c 100644 --- a/packages/runner/node/log.ts +++ b/packages/runner/node/log.ts @@ -1,3 +1,4 @@ +// Borrowed from https://github.com/egoist/tsup/blob/main/src/log.ts import * as colors from 'colorette' type LOG_TYPE = 'info' | 'success' | 'error' | 'warn' diff --git a/packages/runner/node/run.ts b/packages/runner/node/run.ts index 4965ed9a..935685d7 100644 --- a/packages/runner/node/run.ts +++ b/packages/runner/node/run.ts @@ -2,8 +2,8 @@ import path from 'path' import { performance } from 'perf_hooks' import type { ConcurrentlyCommandInput } from 'concurrently' import concurrently from 'concurrently' -import { build as electronBuilder } from 'electron-builder' import { yellow } from 'colorette' +import { checkPackageExists } from 'check-package-exists' import type { ElectronBuildConfig } from './config' import { resolveConfig } from './config' import { createLogger } from './log' @@ -73,6 +73,8 @@ export async function run(command: string) { logger.success(TAG, 'All commands finished successfully') }, () => { logger.warn(TAG, 'Some commands exit') + }).catch((e) => { + logger.error(TAG, e) }).finally(() => { logger.info(TAG, 'Exiting...') process.exit(0) @@ -80,11 +82,16 @@ export async function run(command: string) { } async function doElectronBuild(buildConfig: ElectronBuildConfig | undefined) { + if (!checkPackageExists('electron-builder')) + throw new Error('"electronBuild" config is powered by "electron-builder", please installed it via `npm i electron-builder -D`') + + const { build } = await import('electron-builder') + const logger = createLogger() const startTime = performance.now() try { logger.info(`\n[${TAG}] electron-builder`, 'Start electron build...\n') - await electronBuilder({ + await build({ projectDir: buildConfig?.projectDir || process.cwd(), config: buildConfig?.config, }) diff --git a/packages/runner/package.json b/packages/runner/package.json index 6020f01d..f5159c7f 100644 --- a/packages/runner/package.json +++ b/packages/runner/package.json @@ -26,6 +26,7 @@ "dependencies": { "bundle-require": "^3.0.4", "cac": "^6.7.12", + "check-package-exists": "^1.0.0", "colorette": "^2.0.16", "concurrently": "^7.2.1", "esbuild": "^0.14.42", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cbdff024..b5546763 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -91,6 +91,7 @@ importers: specifiers: bundle-require: ^3.0.4 cac: ^6.7.12 + check-package-exists: ^1.0.0 colorette: ^2.0.16 concurrently: ^7.2.1 electron-builder: ^23.0.3 @@ -100,6 +101,7 @@ importers: dependencies: bundle-require: 3.0.4_esbuild@0.14.42 cac: 6.7.12 + check-package-exists: 1.0.0 colorette: 2.0.16 concurrently: 7.2.1 esbuild: 0.14.42 @@ -1351,6 +1353,15 @@ packages: resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} dev: true + /check-package-exists/1.0.0: + resolution: {integrity: sha512-bJLrYkwYJ4bGJDO2ND2RepunuqA6VbasujFgkS0sCBna6V+A6FdHpdfXlGWKmmYVrOMOch1nM+0tjywq20stqQ==} + engines: {node: '>=14'} + dependencies: + execa: 5.1.1 + global-dirs: 3.0.0 + resolve: 1.22.0 + dev: false + /chokidar/3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -2681,7 +2692,6 @@ packages: /function-bind/1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - dev: true /function.prototype.name/1.1.5: resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} @@ -2792,7 +2802,6 @@ packages: engines: {node: '>=10'} dependencies: ini: 2.0.0 - dev: true /global-tunnel-ng/2.7.1: resolution: {integrity: sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==} @@ -2900,7 +2909,6 @@ packages: engines: {node: '>= 0.4.0'} dependencies: function-bind: 1.1.1 - dev: true /hosted-git-info/2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -3018,7 +3026,6 @@ packages: /ini/2.0.0: resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} engines: {node: '>=10'} - dev: true /internal-slot/1.0.3: resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} @@ -3094,7 +3101,6 @@ packages: resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==} dependencies: has: 1.0.3 - dev: true /is-date-object/1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} @@ -3873,7 +3879,6 @@ packages: /path-parse/1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true /path-to-regexp/3.2.0: resolution: {integrity: sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==} @@ -4123,7 +4128,6 @@ packages: is-core-module: 2.9.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - dev: true /resolve/2.0.0-next.3: resolution: {integrity: sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==} @@ -4532,7 +4536,6 @@ packages: /supports-preserve-symlinks-flag/1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - dev: true /temp-file/3.4.0: resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==}