Skip to content

Commit

Permalink
Merge pull request #203 from electron-vite/v0.28.1
Browse files Browse the repository at this point in the history
V0.28.1
  • Loading branch information
caoxiemeihao authored Feb 6, 2024
2 parents 45f28bb + 50a9573 commit bf215e9
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 33 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
## 0.28.1 (2024-02-06)

- efc5826 fix: correct `calcEntryCount()` for startup
- cf0e91f feat: startup support `SpawnOptions` #194
- 512a1c5 Merge pull request #204 from SanGongHappy/tree-kill-sync
- edf4bf6 refactor: better `treeKillSync` implemented
- 82cd32f Merge branch 'electron-vite:main' into tree-kill-sync
- 6e122a7 feat: polyfill `process.env` by default
- 45f28bb (github/main, main) chore: update CHANGELOG
- f9b81e4 chore(simple): update comments
- b5376a9 docs: add `Built format`
- e334366 copy tree-kill

## 0.28.0 (2024-01-07)

- 20170a5 refactor: preload built `format` use `esm` by default
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,17 +137,17 @@ export interface ElectronOptions {
vite?: import('vite').InlineConfig
/**
* Triggered when Vite is built every time -- `vite serve` command only.
*
* If this `onstart` is passed, Electron App will not start automatically.
* However, you can start Electroo App via `startup` function.
*
* If this `onstart` is passed, Electron App will not start automatically.
* However, you can start Electroo App via `startup` function.
*/
onstart?: (args: {
/**
* Electron App startup function.
* It will mount the Electron App child-process to `process.electronApp`.
* Electron App startup function.
* It will mount the Electron App child-process to `process.electronApp`.
* @param argv default value `['.', '--no-sandbox']`
*/
startup: (argv?: string[]) => Promise<void>
startup: (argv?: string[], options?: import('node:child_process').SpawnOptions) => Promise<void>
/** Reload Electron-Renderer */
reload: () => void
}) => void | Promise<void>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vite-plugin-electron",
"version": "0.28.0",
"version": "0.28.1",
"description": "Electron 🔗 Vite",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down
16 changes: 10 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
resolveServerUrl,
resolveViteConfig,
withExternalBuiltins,
calcEntryCount,
treeKillSync,
} from './utils'

// public utils
Expand All @@ -33,7 +33,7 @@ export interface ElectronOptions {
* It will mount the Electron App child-process to `process.electronApp`.
* @param argv default value `['.', '--no-sandbox']`
*/
startup: (argv?: string[]) => Promise<void>
startup: (argv?: string[], options?: import('node:child_process').SpawnOptions) => Promise<void>
/** Reload Electron-Renderer */
reload: () => void
}) => void | Promise<void>
Expand All @@ -57,7 +57,7 @@ export default function electron(options: ElectronOptions | ElectronOptions[]):
VITE_DEV_SERVER_URL: resolveServerUrl(server),
})

const entryCount = calcEntryCount(optionsArray)
const entryCount = optionsArray.length
let closeBundleCount = 0

for (const options of optionsArray) {
Expand Down Expand Up @@ -119,7 +119,10 @@ export default function electron(options: ElectronOptions | ElectronOptions[]):
* It will mount the Electron App child-process to `process.electronApp`.
* @param argv default value `['.', '--no-sandbox']`
*/
export async function startup(argv = ['.', '--no-sandbox']) {
export async function startup(
argv = ['.', '--no-sandbox'],
options?: import('node:child_process').SpawnOptions,
) {
const { spawn } = await import('node:child_process')
// @ts-ignore
const electron = await import('electron')
Expand All @@ -128,7 +131,7 @@ export async function startup(argv = ['.', '--no-sandbox']) {
await startup.exit()

// Start Electron.app
process.electronApp = spawn(electronPath, argv, { stdio: 'inherit' })
process.electronApp = spawn(electronPath, argv, { stdio: 'inherit', ...options })

// Exit command after Electron.app exits
process.electronApp.once('exit', process.exit)
Expand All @@ -138,7 +141,8 @@ export async function startup(argv = ['.', '--no-sandbox']) {
process.once('exit', () => {
startup.exit()
// When the process exits, `tree-kill` does not have enough time to complete execution, so `electronApp` needs to be killed immediately.
process.electronApp.kill()
// process.electronApp.kill()
treeKillSync(process.electronApp.pid!);
})
}
}
Expand Down
72 changes: 52 additions & 20 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import fs from 'node:fs'
import path from 'node:path'
import cp from 'node:child_process'
import type { AddressInfo } from 'node:net'
import { builtinModules } from 'node:module'
import {
Expand All @@ -9,6 +10,12 @@ import {
} from 'vite'
import type { ElectronOptions } from '.'

export interface PidTree {
pid: number
ppid: number
children?: PidTree[]
}

/** Resolve the default Vite's `InlineConfig` for build Electron-Main */
export function resolveViteConfig(options: ElectronOptions): InlineConfig {
const packageJson = resolvePackageJson() ?? {}
Expand Down Expand Up @@ -36,6 +43,10 @@ export function resolveViteConfig(options: ElectronOptions): InlineConfig {
// It corrupts bundling packages like `ws` and `isomorphic-ws`, for example.
mainFields: ['module', 'jsnext:main', 'jsnext'],
},
define: {
// @see - https://github.com/vitejs/vite/blob/v5.0.11/packages/vite/src/node/plugins/define.ts#L20
'process.env': 'process.env',
},
}

return mergeConfig(defaultConfig, options?.vite || {})
Expand Down Expand Up @@ -110,26 +121,6 @@ export function resolveServerUrl(server: ViteDevServer): string | void {
}
}

export function calcEntryCount(optionsArray: ElectronOptions[]) {
return optionsArray.reduce((count, options) => {
const input = options.vite?.build?.rollupOptions?.input

// `input` option have higher priority.
// https://github.com/vitejs/vite/blob/v4.4.9/packages/vite/src/node/build.ts#L494
if (input) {
count += typeof input === 'string'
? 1
: Object.keys(input).length
} else if (options.entry) {
count += typeof options.entry === 'string'
? 1
: Object.keys(options.entry).length
}

return count
}, 0)
}

export function resolvePackageJson(root = process.cwd()): {
type?: 'module' | 'commonjs'
[key: string]: any
Expand All @@ -142,3 +133,44 @@ export function resolvePackageJson(root = process.cwd()): {
return null
}
}

/**
* Inspired `tree-kill`, implemented based on sync-api. #168
* @see https://github.com/pkrumins/node-tree-kill/blob/v1.2.2/index.js
*/
export function treeKillSync(pid: number) {
if (process.platform === 'win32') {
cp.execSync(`taskkill /pid ${pid} /T /F`)
} else {
killTree(pidTree())
}
}

function pidTree(tree: PidTree = { pid: process.pid, ppid: process.ppid }) {
const command = process.platform === 'darwin'
? `pgrep -P ${tree.pid}` // Mac
: `ps -o pid --no-headers --ppid ${tree.ppid}` // Linux

try {
const childs = cp
.execSync(command, { encoding: 'utf8' })
.match(/\d+/g)
?.map(id => +id)

if (childs) {
tree.children = childs.map(cid => pidTree({ pid: cid, ppid: tree.pid }))
}
} catch { }

return tree
}

function killTree(tree: PidTree) {
if (tree.children) {
for (const child of tree.children) {
killTree(child)
}
}

process.kill(tree.pid)
}

0 comments on commit bf215e9

Please sign in to comment.