Skip to content

Commit bf215e9

Browse files
authored
Merge pull request #203 from electron-vite/v0.28.1
V0.28.1
2 parents 45f28bb + 50a9573 commit bf215e9

File tree

5 files changed

+82
-33
lines changed

5 files changed

+82
-33
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
## 0.28.1 (2024-02-06)
2+
3+
- efc5826 fix: correct `calcEntryCount()` for startup
4+
- cf0e91f feat: startup support `SpawnOptions` #194
5+
- 512a1c5 Merge pull request #204 from SanGongHappy/tree-kill-sync
6+
- edf4bf6 refactor: better `treeKillSync` implemented
7+
- 82cd32f Merge branch 'electron-vite:main' into tree-kill-sync
8+
- 6e122a7 feat: polyfill `process.env` by default
9+
- 45f28bb (github/main, main) chore: update CHANGELOG
10+
- f9b81e4 chore(simple): update comments
11+
- b5376a9 docs: add `Built format`
12+
- e334366 copy tree-kill
13+
114
## 0.28.0 (2024-01-07)
215

316
- 20170a5 refactor: preload built `format` use `esm` by default

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,17 @@ export interface ElectronOptions {
137137
vite?: import('vite').InlineConfig
138138
/**
139139
* Triggered when Vite is built every time -- `vite serve` command only.
140-
*
141-
* If this `onstart` is passed, Electron App will not start automatically.
142-
* However, you can start Electroo App via `startup` function.
140+
*
141+
* If this `onstart` is passed, Electron App will not start automatically.
142+
* However, you can start Electroo App via `startup` function.
143143
*/
144144
onstart?: (args: {
145145
/**
146-
* Electron App startup function.
147-
* It will mount the Electron App child-process to `process.electronApp`.
146+
* Electron App startup function.
147+
* It will mount the Electron App child-process to `process.electronApp`.
148148
* @param argv default value `['.', '--no-sandbox']`
149149
*/
150-
startup: (argv?: string[]) => Promise<void>
150+
startup: (argv?: string[], options?: import('node:child_process').SpawnOptions) => Promise<void>
151151
/** Reload Electron-Renderer */
152152
reload: () => void
153153
}) => void | Promise<void>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vite-plugin-electron",
3-
"version": "0.28.0",
3+
"version": "0.28.1",
44
"description": "Electron 🔗 Vite",
55
"main": "./dist/index.js",
66
"types": "./dist/index.d.ts",

src/index.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
resolveServerUrl,
77
resolveViteConfig,
88
withExternalBuiltins,
9-
calcEntryCount,
9+
treeKillSync,
1010
} from './utils'
1111

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

60-
const entryCount = calcEntryCount(optionsArray)
60+
const entryCount = optionsArray.length
6161
let closeBundleCount = 0
6262

6363
for (const options of optionsArray) {
@@ -119,7 +119,10 @@ export default function electron(options: ElectronOptions | ElectronOptions[]):
119119
* It will mount the Electron App child-process to `process.electronApp`.
120120
* @param argv default value `['.', '--no-sandbox']`
121121
*/
122-
export async function startup(argv = ['.', '--no-sandbox']) {
122+
export async function startup(
123+
argv = ['.', '--no-sandbox'],
124+
options?: import('node:child_process').SpawnOptions,
125+
) {
123126
const { spawn } = await import('node:child_process')
124127
// @ts-ignore
125128
const electron = await import('electron')
@@ -128,7 +131,7 @@ export async function startup(argv = ['.', '--no-sandbox']) {
128131
await startup.exit()
129132

130133
// Start Electron.app
131-
process.electronApp = spawn(electronPath, argv, { stdio: 'inherit' })
134+
process.electronApp = spawn(electronPath, argv, { stdio: 'inherit', ...options })
132135

133136
// Exit command after Electron.app exits
134137
process.electronApp.once('exit', process.exit)
@@ -138,7 +141,8 @@ export async function startup(argv = ['.', '--no-sandbox']) {
138141
process.once('exit', () => {
139142
startup.exit()
140143
// When the process exits, `tree-kill` does not have enough time to complete execution, so `electronApp` needs to be killed immediately.
141-
process.electronApp.kill()
144+
// process.electronApp.kill()
145+
treeKillSync(process.electronApp.pid!);
142146
})
143147
}
144148
}

src/utils.ts

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import fs from 'node:fs'
22
import path from 'node:path'
3+
import cp from 'node:child_process'
34
import type { AddressInfo } from 'node:net'
45
import { builtinModules } from 'node:module'
56
import {
@@ -9,6 +10,12 @@ import {
910
} from 'vite'
1011
import type { ElectronOptions } from '.'
1112

13+
export interface PidTree {
14+
pid: number
15+
ppid: number
16+
children?: PidTree[]
17+
}
18+
1219
/** Resolve the default Vite's `InlineConfig` for build Electron-Main */
1320
export function resolveViteConfig(options: ElectronOptions): InlineConfig {
1421
const packageJson = resolvePackageJson() ?? {}
@@ -36,6 +43,10 @@ export function resolveViteConfig(options: ElectronOptions): InlineConfig {
3643
// It corrupts bundling packages like `ws` and `isomorphic-ws`, for example.
3744
mainFields: ['module', 'jsnext:main', 'jsnext'],
3845
},
46+
define: {
47+
// @see - https://github.com/vitejs/vite/blob/v5.0.11/packages/vite/src/node/plugins/define.ts#L20
48+
'process.env': 'process.env',
49+
},
3950
}
4051

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

113-
export function calcEntryCount(optionsArray: ElectronOptions[]) {
114-
return optionsArray.reduce((count, options) => {
115-
const input = options.vite?.build?.rollupOptions?.input
116-
117-
// `input` option have higher priority.
118-
// https://github.com/vitejs/vite/blob/v4.4.9/packages/vite/src/node/build.ts#L494
119-
if (input) {
120-
count += typeof input === 'string'
121-
? 1
122-
: Object.keys(input).length
123-
} else if (options.entry) {
124-
count += typeof options.entry === 'string'
125-
? 1
126-
: Object.keys(options.entry).length
127-
}
128-
129-
return count
130-
}, 0)
131-
}
132-
133124
export function resolvePackageJson(root = process.cwd()): {
134125
type?: 'module' | 'commonjs'
135126
[key: string]: any
@@ -142,3 +133,44 @@ export function resolvePackageJson(root = process.cwd()): {
142133
return null
143134
}
144135
}
136+
137+
/**
138+
* Inspired `tree-kill`, implemented based on sync-api. #168
139+
* @see https://github.com/pkrumins/node-tree-kill/blob/v1.2.2/index.js
140+
*/
141+
export function treeKillSync(pid: number) {
142+
if (process.platform === 'win32') {
143+
cp.execSync(`taskkill /pid ${pid} /T /F`)
144+
} else {
145+
killTree(pidTree())
146+
}
147+
}
148+
149+
function pidTree(tree: PidTree = { pid: process.pid, ppid: process.ppid }) {
150+
const command = process.platform === 'darwin'
151+
? `pgrep -P ${tree.pid}` // Mac
152+
: `ps -o pid --no-headers --ppid ${tree.ppid}` // Linux
153+
154+
try {
155+
const childs = cp
156+
.execSync(command, { encoding: 'utf8' })
157+
.match(/\d+/g)
158+
?.map(id => +id)
159+
160+
if (childs) {
161+
tree.children = childs.map(cid => pidTree({ pid: cid, ppid: tree.pid }))
162+
}
163+
} catch { }
164+
165+
return tree
166+
}
167+
168+
function killTree(tree: PidTree) {
169+
if (tree.children) {
170+
for (const child of tree.children) {
171+
killTree(child)
172+
}
173+
}
174+
175+
process.kill(tree.pid)
176+
}

0 commit comments

Comments
 (0)