@tomjs/vite-plugin-electron 1.1.2 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,8 @@
6
6
 
7
7
  > A Simple [vite](https://vitejs.dev/) plugin for [electron](https://www.electronjs.org), supports `esm` and `cjs`.
8
8
 
9
+ I learned [caoxiemeihao](https://github.com/caoxiemeihao)'s [vite-plugin-electron](https://github.com/electron-vite/vite-plugin-electron) and [Doubleshotjs](https://github.com/Doubleshotjs)'s [doubleshot](https://github.com/Doubleshotjs/doubleshot) These two excellent works, combined with some of my own ideas, developed this plugin. I hope that using it can simplify the development configuration and only focus on business development.
10
+
9
11
  ## Features
10
12
 
11
13
  - Fast build `main` and `preload` with [tsup](https://github.com/egoist/tsup)
@@ -37,9 +39,11 @@ npm i @tomjs/vite-plugin-electron --save-dev
37
39
 
38
40
  ## Usage
39
41
 
40
- ### Project structure
42
+ ### Recommended Agreement
43
+
44
+ #### Directory Structure
41
45
 
42
- - Recommended `electron` front-end code directory structure
46
+ - Recommend `electron` and page `src` code directory structure
43
47
 
44
48
  ```
45
49
  |--electron
@@ -52,7 +56,7 @@ npm i @tomjs/vite-plugin-electron --save-dev
52
56
  | |--main.ts
53
57
  ```
54
58
 
55
- - Use the default dist output directory of the plugin
59
+ - Zero configuration, default dist output directory
56
60
 
57
61
  ```
58
62
  |--dist
@@ -66,6 +70,10 @@ npm i @tomjs/vite-plugin-electron --save-dev
66
70
  | | |--index.html
67
71
  ```
68
72
 
73
+ #### Default configuration and behavior
74
+
75
+ See [PluginOptions](#pluginoptions) and `recommended` parameter descriptions in detail
76
+
69
77
  ### electron
70
78
 
71
79
  `electron/main/index.ts`
@@ -105,10 +113,12 @@ app.whenReady().then(createWindow);
105
113
 
106
114
  ### vue
107
115
 
108
- Support `ES modules`
116
+ Take using `esm` as an example, but it requires Electron>=28
109
117
 
110
118
  - `package.json`
111
119
 
120
+ Electron preload must use the `mjs` suffix, otherwise an error will be reported. So `esm` also uses the `mjs` suffix for output by default.
121
+
112
122
  ```json
113
123
  {
114
124
  "type": "module",
@@ -126,14 +136,17 @@ import vue from '@vitejs/plugin-vue';
126
136
  export default defineConfig({
127
137
  plugins: [
128
138
  vue(),
129
- electron({
130
- main: {
131
- entry: 'electron/main/index.ts',
132
- },
133
- preload: {
134
- entry: 'electron/preload/index.ts',
135
- },
136
- }),
139
+ // If you use the agreed directory structure, no configuration is required
140
+ electron(),
141
+ // If the directory structure is customized, the value must be assigned according to the actual situation
142
+ // electron({
143
+ // main: {
144
+ // entry: 'electron/main/index.ts',
145
+ // },
146
+ // preload: {
147
+ // entry: 'electron/preload/index.ts',
148
+ // },
149
+ // }),
137
150
  // renderer(),
138
151
  ],
139
152
  });
@@ -141,7 +154,7 @@ export default defineConfig({
141
154
 
142
155
  ### react
143
156
 
144
- Support `CommonJS`
157
+ Take using `cjs` as an example
145
158
 
146
159
  - `package.json`
147
160
 
@@ -156,23 +169,11 @@ Support `CommonJS`
156
169
 
157
170
  ```ts
158
171
  import { defineConfig } from 'vite';
159
- // import renderer from 'vite-plugin-electron-renderer'; // Enable nodeIntegration
160
172
  import electron from '@tomjs/vite-plugin-electron';
161
173
  import react from '@vitejs/plugin-react-swc';
162
174
 
163
175
  export default defineConfig({
164
- plugins: [
165
- react(),
166
- electron({
167
- main: {
168
- entry: 'electron/main/index.ts',
169
- },
170
- preload: {
171
- entry: 'electron/preload/index.ts',
172
- },
173
- }),
174
- // renderer(),
175
- ],
176
+ plugins: [react(), electron()],
176
177
  });
177
178
  ```
178
179
 
@@ -193,6 +194,14 @@ export default defineConfig({
193
194
  | preload | [PreloadOptions](#PreloadOptions) | | Configuration options for the electron preload process. |
194
195
  | inspect | `boolean` | true | If set to true, electron will start with the `--inspect` flag. |
195
196
 
197
+ **Notice**
198
+
199
+ The `recommended` option is used to set the default configuration and behavior, which can be used with almost zero configuration. The default is `true`. If you want to customize the configuration, set it to `false`. The following default prerequisites are to use the recommended [project structure](#directory-structure).
200
+
201
+ - Check whether `electron/main/index.ts` and `electron/main/index.ts` exist, and if so, assign values to `main.entry` and `preload.entry` respectively. If it does not exist, `main.entry` must be actively assigned, and an error will be reported.
202
+ - The output directory is based on the `build.outDir` parameter of `vite`, and outputs `electron/main`, `electron/preload` and `src` to `dist/main`, `dist/preload` and `dist/renderer` respectively.
203
+ - Other behaviors to be implemented
204
+
196
205
  ### MainOptions
197
206
 
198
207
  Based on [Options](https://paka.dev/npm/tsup) of [tsup](https://tsup.egoist.dev/), some default values are added for ease of use.
package/README.zh_CN.md CHANGED
@@ -6,6 +6,8 @@
6
6
 
7
7
  > 一个简单的 [electron](https://www.electronjs.org/zh/) [vite](https://cn.vitejs.dev/) 插件,支持 `esm` 和 `cjs`
8
8
 
9
+ 学习了 [caoxiemeihao](https://github.com/caoxiemeihao) 的 [vite-plugin-electron](https://github.com/electron-vite/vite-plugin-electron) 和 [Doubleshotjs](https://github.com/Doubleshotjs) 的 [doubleshot](https://github.com/Doubleshotjs/doubleshot) 这两个优秀的作品,结合自己的一些想法,开发了该插件。希望使用它能简化开发配置,只关注业务开发。
10
+
9
11
  ## 特性
10
12
 
11
13
  - 使用 [tsup](https://github.com/egoist/tsup) 快速构建 `main` 和 `preload`
@@ -37,9 +39,11 @@ npm i @tomjs/vite-plugin-electron --save-dev
37
39
 
38
40
  ## 使用说明
39
41
 
40
- ### 项目结构
42
+ ### 推荐约定
43
+
44
+ #### 目录结构
41
45
 
42
- - 推荐 `electron` 前端代码目录结构
46
+ - 推荐 `electron` 页面 `src` 代码目录结构
43
47
 
44
48
  ```
45
49
  |--electron
@@ -52,7 +56,7 @@ npm i @tomjs/vite-plugin-electron --save-dev
52
56
  | |--main.ts
53
57
  ```
54
58
 
55
- - 使用插件默认 dist 输出目录
59
+ - 零配置,默认 dist 输出目录
56
60
 
57
61
  ```
58
62
  |--dist
@@ -66,6 +70,10 @@ npm i @tomjs/vite-plugin-electron --save-dev
66
70
  | | |--index.html
67
71
  ```
68
72
 
73
+ #### 默认配置和行为
74
+
75
+ 详细查看 [PluginOptions](#pluginoptions) 和 `recommended` 参数说明
76
+
69
77
  ### electron
70
78
 
71
79
  `electron/main/index.ts`
@@ -105,10 +113,12 @@ app.whenReady().then(createWindow);
105
113
 
106
114
  ### vue
107
115
 
108
- 支持 `ES modules`
116
+ 以使用 `esm` 为例,不过要求 `Electron>=28`
109
117
 
110
118
  - `package.json`
111
119
 
120
+ Electron preload 必须使用 `mjs` 后缀,否则报错。所以 `esm` 也默认输出使用 `mjs` 后缀。
121
+
112
122
  ```json
113
123
  {
114
124
  "type": "module",
@@ -127,14 +137,17 @@ import vue from '@vitejs/plugin-vue';
127
137
  export default defineConfig({
128
138
  plugins: [
129
139
  vue(),
130
- electron({
131
- main: {
132
- entry: 'electron/main/index.ts',
133
- },
134
- preload: {
135
- entry: 'electron/preload/index.ts',
136
- },
137
- }),
140
+ // 如使用约定的目录结构,则不需要配置
141
+ electron(),
142
+ // 如果自定义了目录结构,则必须根据实际情况赋值
143
+ // electron({
144
+ // main: {
145
+ // entry: 'electron/main/index.ts',
146
+ // },
147
+ // preload: {
148
+ // entry: 'electron/preload/index.ts',
149
+ // },
150
+ // }),
138
151
  // renderer(),
139
152
  ],
140
153
  });
@@ -142,7 +155,7 @@ export default defineConfig({
142
155
 
143
156
  ### react
144
157
 
145
- 支持 `CommonJS`
158
+ 以使用 `cjs` 为例
146
159
 
147
160
  - `package.json`
148
161
 
@@ -157,23 +170,11 @@ export default defineConfig({
157
170
 
158
171
  ```ts
159
172
  import { defineConfig } from 'vite';
160
- // import renderer from 'vite-plugin-electron-renderer'; // 启用 nodeIntegration
161
173
  import electron from '@tomjs/vite-plugin-electron';
162
174
  import react from '@vitejs/plugin-react-swc';
163
175
 
164
176
  export default defineConfig({
165
- plugins: [
166
- react(),
167
- electron({
168
- main: {
169
- entry: 'electron/main/index.ts',
170
- },
171
- preload: {
172
- entry: 'electron/preload/index.ts',
173
- },
174
- }),
175
- // renderer(),
176
- ],
177
+ plugins: [react(), electron()],
177
178
  });
178
179
  ```
179
180
 
@@ -190,10 +191,16 @@ export default defineConfig({
190
191
  | --- | --- | --- | --- |
191
192
  | recommended | `boolean` | `true` | 推荐开关,如果为true,将具有以下默认行为:将main/preload/renderer的outDir更改为并行的outDir;例如,如果vite build.outDir为'dist',将main/preload/render更改为'dist/main'、'dist/preload'和'dist/renderer' |
192
193
  | external | `string[]` | | 不打包这些模块 |
193
- | **main** | [MainOptions](#MainOptions) | | electron main 进程选项 |
194
+ | main | [MainOptions](#MainOptions) | | electron main 进程选项 |
194
195
  | preload | [PreloadOptions](#PreloadOptions) | | electron preload 进程选项 |
195
196
  | inspect | `boolean` | `true` | electron启动时使用`--inspect`参数 |
196
197
 
198
+ `recommended` 选项用于设置默认配置和行为,几乎可以达到零配置使用,默认为 `true` 。如果你要自定义配置,请设置它为`false`。以下默认的前提条件是使用推荐的 [项目结构](#目录结构)。
199
+
200
+ - 检查是否存在 `electron/main/index.ts` 和 `electron/main/index.ts`,如果有则分别给 `main.entry` 和 `preload.entry` 赋值。如果不存在,`main.entry` 必须主动赋值,负责会报错
201
+ - 输出目录根据 `vite` 的 `build.outDir` 参数, 将 `electron/main`、`electron/preload`、`src` 分别输出到 `dist/main`、`dist/preload`、`dist/renderer`
202
+ - 其他待实现的行为
203
+
197
204
  ### MainOptions
198
205
 
199
206
  继承自 [tsup](https://tsup.egoist.dev/) 的 [Options](https://paka.dev/npm/tsup),添加了一些默认值,方便使用。
package/dist/index.d.mts CHANGED
@@ -2,18 +2,15 @@ import { Plugin } from 'vite';
2
2
  import { Options } from 'tsup';
3
3
 
4
4
  /**
5
- * Electron main process options
5
+ * Electron main process options.
6
+ * @see https://paka.dev/npm/tsup
7
+ * @see https://unpkg.com/browse/tsup/dist/index.d.ts
6
8
  */
7
- interface MainOptions extends Omit<Options, 'name' | 'entry' | 'format' | 'outDir' | 'watch' | 'onSuccess'> {
8
- /**
9
- * The name of the electron main process.
10
- * @default "main"
11
- */
12
- name?: string;
9
+ interface MainOptions extends Omit<Options, 'entry' | 'format' | 'outDir' | 'watch' | 'onSuccess'> {
13
10
  /**
14
11
  * The main process entry file.
15
12
  */
16
- entry: string;
13
+ entry?: string;
17
14
  /**
18
15
  * The bundle format. If not specified, it will use the "type" field from package.json.
19
16
  */
@@ -29,14 +26,11 @@ interface MainOptions extends Omit<Options, 'name' | 'entry' | 'format' | 'outDi
29
26
  onSuccess?: () => Promise<void | undefined | (() => void | Promise<void>)>;
30
27
  }
31
28
  /**
32
- * Electron preload process options
29
+ * Electron preload process options.
30
+ * @see https://paka.dev/npm/tsup
31
+ * @see https://unpkg.com/browse/tsup/dist/index.d.ts
33
32
  */
34
- interface PreloadOptions extends Omit<Options, 'name' | 'entry' | 'format' | 'outDir' | 'watch' | 'onSuccess'> {
35
- /**
36
- * The name of the electron preload process.
37
- * @default "preload"
38
- */
39
- name?: string;
33
+ interface PreloadOptions extends Omit<Options, 'entry' | 'format' | 'outDir' | 'watch' | 'onSuccess'> {
40
34
  /**
41
35
  * The preload process entry file
42
36
  */
@@ -46,7 +40,7 @@ interface PreloadOptions extends Omit<Options, 'name' | 'entry' | 'format' | 'ou
46
40
  */
47
41
  format?: 'cjs' | 'esm';
48
42
  /**
49
- * The output directory for the preload process files. Defaults to `"dist-electron/preload"`.
43
+ * The output directory for the preload process files. Defaults is `"dist-electron/preload"`.
50
44
  * @default "dist-electron/preload"
51
45
  */
52
46
  outDir?: string;
@@ -60,7 +54,8 @@ interface PreloadOptions extends Omit<Options, 'name' | 'entry' | 'format' | 'ou
60
54
  */
61
55
  interface PluginOptions {
62
56
  /**
63
- * Recommended switch, if true, will have the following default behavior
57
+ * Recommended switch. Default is true.
58
+ * if true, will have the following default behavior:
64
59
  * * will change the main/preload/renderer outDir to be parallel outDir;
65
60
  * eg. if vite build.outDir is 'dist', will change main/preload/render to 'dist/main' and 'dist/preload' and 'dist/renderer'
66
61
  * @default true
@@ -73,7 +68,7 @@ interface PluginOptions {
73
68
  /**
74
69
  * electron main process options
75
70
  */
76
- main: MainOptions;
71
+ main?: MainOptions;
77
72
  /**
78
73
  * electron preload process options
79
74
  */
@@ -84,28 +79,7 @@ interface PluginOptions {
84
79
  */
85
80
  inspect?: boolean;
86
81
  }
87
- /**
88
- * Only used internally
89
- */
90
- interface InnerOptions {
91
- /**
92
- * whether is vite server
93
- */
94
- isServer?: boolean;
95
- /**
96
- * vite server url, will be passed to electron
97
- */
98
- serverUrl?: string;
99
- /**
100
- * renderer outDir
101
- */
102
- rendererOutDir?: string;
103
- /**
104
- * electron main entry file
105
- */
106
- mainFile?: string;
107
- }
108
82
 
109
83
  declare function vitePluginElectron(options?: PluginOptions): Plugin;
110
84
 
111
- export { InnerOptions, MainOptions, PluginOptions, PreloadOptions, vitePluginElectron as default, vitePluginElectron };
85
+ export { MainOptions, PluginOptions, PreloadOptions, vitePluginElectron as default, vitePluginElectron };
package/dist/index.d.ts CHANGED
@@ -2,18 +2,15 @@ import { Plugin } from 'vite';
2
2
  import { Options } from 'tsup';
3
3
 
4
4
  /**
5
- * Electron main process options
5
+ * Electron main process options.
6
+ * @see https://paka.dev/npm/tsup
7
+ * @see https://unpkg.com/browse/tsup/dist/index.d.ts
6
8
  */
7
- interface MainOptions extends Omit<Options, 'name' | 'entry' | 'format' | 'outDir' | 'watch' | 'onSuccess'> {
8
- /**
9
- * The name of the electron main process.
10
- * @default "main"
11
- */
12
- name?: string;
9
+ interface MainOptions extends Omit<Options, 'entry' | 'format' | 'outDir' | 'watch' | 'onSuccess'> {
13
10
  /**
14
11
  * The main process entry file.
15
12
  */
16
- entry: string;
13
+ entry?: string;
17
14
  /**
18
15
  * The bundle format. If not specified, it will use the "type" field from package.json.
19
16
  */
@@ -29,14 +26,11 @@ interface MainOptions extends Omit<Options, 'name' | 'entry' | 'format' | 'outDi
29
26
  onSuccess?: () => Promise<void | undefined | (() => void | Promise<void>)>;
30
27
  }
31
28
  /**
32
- * Electron preload process options
29
+ * Electron preload process options.
30
+ * @see https://paka.dev/npm/tsup
31
+ * @see https://unpkg.com/browse/tsup/dist/index.d.ts
33
32
  */
34
- interface PreloadOptions extends Omit<Options, 'name' | 'entry' | 'format' | 'outDir' | 'watch' | 'onSuccess'> {
35
- /**
36
- * The name of the electron preload process.
37
- * @default "preload"
38
- */
39
- name?: string;
33
+ interface PreloadOptions extends Omit<Options, 'entry' | 'format' | 'outDir' | 'watch' | 'onSuccess'> {
40
34
  /**
41
35
  * The preload process entry file
42
36
  */
@@ -46,7 +40,7 @@ interface PreloadOptions extends Omit<Options, 'name' | 'entry' | 'format' | 'ou
46
40
  */
47
41
  format?: 'cjs' | 'esm';
48
42
  /**
49
- * The output directory for the preload process files. Defaults to `"dist-electron/preload"`.
43
+ * The output directory for the preload process files. Defaults is `"dist-electron/preload"`.
50
44
  * @default "dist-electron/preload"
51
45
  */
52
46
  outDir?: string;
@@ -60,7 +54,8 @@ interface PreloadOptions extends Omit<Options, 'name' | 'entry' | 'format' | 'ou
60
54
  */
61
55
  interface PluginOptions {
62
56
  /**
63
- * Recommended switch, if true, will have the following default behavior
57
+ * Recommended switch. Default is true.
58
+ * if true, will have the following default behavior:
64
59
  * * will change the main/preload/renderer outDir to be parallel outDir;
65
60
  * eg. if vite build.outDir is 'dist', will change main/preload/render to 'dist/main' and 'dist/preload' and 'dist/renderer'
66
61
  * @default true
@@ -73,7 +68,7 @@ interface PluginOptions {
73
68
  /**
74
69
  * electron main process options
75
70
  */
76
- main: MainOptions;
71
+ main?: MainOptions;
77
72
  /**
78
73
  * electron preload process options
79
74
  */
@@ -84,28 +79,7 @@ interface PluginOptions {
84
79
  */
85
80
  inspect?: boolean;
86
81
  }
87
- /**
88
- * Only used internally
89
- */
90
- interface InnerOptions {
91
- /**
92
- * whether is vite server
93
- */
94
- isServer?: boolean;
95
- /**
96
- * vite server url, will be passed to electron
97
- */
98
- serverUrl?: string;
99
- /**
100
- * renderer outDir
101
- */
102
- rendererOutDir?: string;
103
- /**
104
- * electron main entry file
105
- */
106
- mainFile?: string;
107
- }
108
82
 
109
83
  declare function vitePluginElectron(options?: PluginOptions): Plugin;
110
84
 
111
- export { InnerOptions, MainOptions, PluginOptions, PreloadOptions, vitePluginElectron as default, vitePluginElectron };
85
+ export { MainOptions, PluginOptions, PreloadOptions, vitePluginElectron as default, vitePluginElectron };
package/dist/index.js CHANGED
@@ -1,11 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
7
-
8
- // src/index.ts
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/index.ts
9
2
  var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
10
3
  var _lodashclonedeep = require('lodash.clonedeep'); var _lodashclonedeep2 = _interopRequireDefault(_lodashclonedeep);
11
4
  var _lodashmerge = require('lodash.merge'); var _lodashmerge2 = _interopRequireDefault(_lodashmerge);
@@ -17,16 +10,16 @@ var PLUGIN_NAME = "@tomjs:electron";
17
10
  // src/main.ts
18
11
  var _child_process = require('child_process');
19
12
  var _electron = require('electron'); var _electron2 = _interopRequireDefault(_electron);
20
- var _kolorist = require('kolorist');
13
+ var _treekill = require('tree-kill'); var _treekill2 = _interopRequireDefault(_treekill);
21
14
  var _tsup = require('tsup');
22
15
 
23
16
  // src/logger.ts
24
17
  var _dayjs = require('dayjs'); var _dayjs2 = _interopRequireDefault(_dayjs);
25
-
18
+ var _kolorist = require('kolorist');
26
19
  var Logger = class {
27
20
  constructor(tag, withTime) {
28
- __publicField(this, "tag", PLUGIN_NAME);
29
- __publicField(this, "withTime", true);
21
+ this.tag = PLUGIN_NAME;
22
+ this.withTime = true;
30
23
  this.tag = `[${tag}]`;
31
24
  this.withTime = _nullishCoalesce(withTime, () => ( true));
32
25
  }
@@ -64,50 +57,47 @@ var createLogger = (tag) => {
64
57
 
65
58
  // src/main.ts
66
59
  var logger = createLogger();
67
- function getBuildOptions(options, innerOpts) {
68
- const env = {
69
- APP_DEV_SERVER_URL: innerOpts == null ? void 0 : innerOpts.serverUrl
70
- };
71
- Object.keys(env).forEach((key) => {
72
- if (env[key] === void 0) {
73
- delete env[key];
74
- }
75
- });
60
+ function getBuildOptions(options) {
76
61
  return ["main", "preload"].filter((s) => options[s] && options[s].entry).map((s) => {
77
62
  options[s].__NAME__ = s;
78
63
  return options[s];
79
64
  }).map((cfg) => {
80
65
  return {
81
66
  ...cfg,
82
- env,
83
67
  silent: true
84
68
  };
85
69
  });
86
70
  }
87
- function exitMainProcess() {
88
- logger.info("exit main process");
89
- process.exit(0);
90
- }
91
- function runMainProcess(options, innerOpts) {
92
- const mainFile = innerOpts.mainFile;
93
- logger.info(`run main file: ${_kolorist.lightGreen.call(void 0, mainFile)}`);
94
- const args = options.inspect ? ["--inspect"] : [];
95
- return _child_process.spawn.call(void 0, _electron2.default, [...args, mainFile], {
71
+ async function startup(options) {
72
+ await startup.exit();
73
+ const args = [];
74
+ options.inspect && args.push("--inspect");
75
+ process.electronApp = _child_process.spawn.call(void 0, _electron2.default, [".", ...args], {
96
76
  stdio: "inherit"
97
- }).on("exit", exitMainProcess);
77
+ });
78
+ process.electronApp.once("exit", process.exit);
79
+ process.once("exit", () => {
80
+ startup.exit();
81
+ process.electronApp.kill();
82
+ });
98
83
  }
99
- async function runServe(options, innerOpts, server) {
100
- let mainProcess;
101
- const killProcess = () => {
102
- if (mainProcess) {
103
- mainProcess.off("exit", exitMainProcess);
104
- mainProcess.kill();
105
- }
106
- };
107
- process.on("exit", () => {
108
- killProcess();
84
+ startup.exit = async () => {
85
+ if (!process.electronApp) {
86
+ return;
87
+ }
88
+ process.electronApp.removeAllListeners();
89
+ return new Promise((resolve, reject) => {
90
+ _treekill2.default.call(void 0, process.electronApp.pid, (err) => {
91
+ if (err) {
92
+ reject(err);
93
+ } else {
94
+ resolve(true);
95
+ }
96
+ });
109
97
  });
110
- const buildOptions = getBuildOptions(options, innerOpts);
98
+ };
99
+ async function runServe(options, server) {
100
+ const buildOptions = getBuildOptions(options);
111
101
  for (let i = 0; i < buildOptions.length; i++) {
112
102
  let isFirstBuild = true;
113
103
  const tsOpts = buildOptions[i];
@@ -124,8 +114,8 @@ async function runServe(options, innerOpts, server) {
124
114
  }
125
115
  logger.success(`${name} rebuild succeeded!`);
126
116
  if (name === "main") {
127
- killProcess();
128
- mainProcess = runMainProcess(options, innerOpts);
117
+ console.log("main process exit");
118
+ await startup(options);
129
119
  } else {
130
120
  server.ws.send({
131
121
  type: "full-reload"
@@ -134,13 +124,10 @@ async function runServe(options, innerOpts, server) {
134
124
  };
135
125
  await _tsup.build.call(void 0, { onSuccess, watch: true, ...tsupOptions });
136
126
  }
137
- mainProcess = runMainProcess(options, innerOpts);
138
- return {
139
- kill: killProcess
140
- };
127
+ await startup(options);
141
128
  }
142
- async function runBuild(options, innerOpts) {
143
- const buildOptions = getBuildOptions(options, innerOpts);
129
+ async function runBuild(options) {
130
+ const buildOptions = getBuildOptions(options);
144
131
  for (let i = 0; i < buildOptions.length; i++) {
145
132
  await _tsup.build.call(void 0, buildOptions[i]);
146
133
  }
@@ -185,11 +172,9 @@ function preMergeOptions(options) {
185
172
  recommended: true,
186
173
  external: ["electron"],
187
174
  main: {
188
- name: "main",
189
175
  ...electron2
190
176
  },
191
177
  preload: {
192
- name: "payload",
193
178
  ...electron2
194
179
  }
195
180
  },
@@ -200,41 +185,45 @@ function preMergeOptions(options) {
200
185
  const fmt = opt.format;
201
186
  opt.format = ["cjs", "esm"].includes(fmt) ? [fmt] : [format];
202
187
  const entry = opt.entry;
203
- if (typeof entry === "string") {
188
+ if (entry == void 0) {
189
+ const filePath = `electron/${prop}/index.ts`;
190
+ if (_fs2.default.existsSync(_path2.default.join(process.cwd(), filePath))) {
191
+ opt.entry = [filePath];
192
+ }
193
+ } else if (typeof entry === "string") {
204
194
  opt.entry = [entry];
205
195
  }
206
196
  const external = opt.external || opts.external || ["electron"];
207
197
  opt.external = [...new Set(["electron"].concat(external))];
208
198
  });
209
- const innerOpts = {
210
- mainFile: pkg.main
211
- };
212
- return { opts, innerOpts };
199
+ return opts;
213
200
  }
214
201
  function vitePluginElectron(options) {
215
- const { opts, innerOpts } = preMergeOptions(options);
202
+ const opts = preMergeOptions(options);
216
203
  const isDev = process.env.NODE_ENV === "development";
204
+ let isServer = false;
217
205
  return {
218
206
  name: PLUGIN_NAME,
219
207
  config(config, env) {
220
208
  var _a;
221
- innerOpts.isServer = env.mode === "serve";
209
+ isServer = env.command === "serve";
222
210
  let outDir = ((_a = config == null ? void 0 : config.build) == null ? void 0 : _a.outDir) || "dist";
223
- opts.preload = opts.preload || {};
211
+ opts.main ||= {};
212
+ opts.preload ||= {};
224
213
  if (opts.recommended) {
225
214
  opts.main.outDir = _path2.default.join(outDir, "main");
226
215
  opts.preload.outDir = _path2.default.join(outDir, "preload");
227
216
  outDir = _path2.default.join(outDir, "renderer");
228
217
  } else {
229
- opts.main.outDir = opts.main.outDir || _path2.default.join("dist-electron", "main");
230
- opts.preload.outDir = opts.preload.outDir || _path2.default.join("dist-electron", "preload");
218
+ opts.main.outDir ||= _path2.default.join("dist-electron", "main");
219
+ opts.preload.outDir ||= _path2.default.join("dist-electron", "preload");
231
220
  }
232
221
  if (isDev) {
233
- opts.main.sourcemap = _nullishCoalesce(opts.main.sourcemap, () => ( true));
234
- opts.preload.sourcemap = _nullishCoalesce(opts.main.sourcemap, () => ( true));
222
+ opts.main.sourcemap ??= true;
223
+ opts.preload.sourcemap ??= true;
235
224
  } else {
236
- opts.main.minify = _nullishCoalesce(opts.main.minify, () => ( true));
237
- opts.preload.minify = _nullishCoalesce(opts.preload.minify, () => ( true));
225
+ opts.main.minify ??= true;
226
+ opts.preload.minify ??= true;
238
227
  }
239
228
  return {
240
229
  build: {
@@ -247,25 +236,23 @@ function vitePluginElectron(options) {
247
236
  return;
248
237
  }
249
238
  server.httpServer.on("listening", async () => {
250
- var _a;
251
239
  if (server.httpServer) {
252
240
  const serve = server.httpServer.address();
253
241
  const { address, port, family } = serve;
254
242
  if (family === "IPv6") {
255
- innerOpts.serverUrl = `http://[${address}]:${port}`;
243
+ process.env.APP_DEV_SERVER_URL = `http://[${address}]:${port}`;
256
244
  } else {
257
- innerOpts.serverUrl = `http://${address}:${port}`;
245
+ process.env.APP_DEV_SERVER_URL = `http://${address}:${port}`;
258
246
  }
259
247
  }
260
- (_a = process.__tomjs_electron_serve__) == null ? void 0 : _a.kill();
261
- process.__tomjs_electron_serve__ = await runServe(opts, innerOpts, server);
248
+ await runServe(opts, server);
262
249
  });
263
250
  },
264
251
  async closeBundle() {
265
- if (innerOpts.isServer) {
252
+ if (isServer) {
266
253
  return;
267
254
  }
268
- await runBuild(opts, innerOpts);
255
+ await runBuild(opts);
269
256
  }
270
257
  };
271
258
  }
package/dist/index.mjs CHANGED
@@ -1,10 +1,3 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
7
-
8
1
  // src/index.ts
9
2
  import fs2 from "fs";
10
3
  import cloneDeep from "lodash.clonedeep";
@@ -17,7 +10,7 @@ var PLUGIN_NAME = "@tomjs:electron";
17
10
  // src/main.ts
18
11
  import { spawn } from "child_process";
19
12
  import electron from "electron";
20
- import { lightGreen } from "kolorist";
13
+ import treeKill from "tree-kill";
21
14
  import { build as tsupBuild } from "tsup";
22
15
 
23
16
  // src/logger.ts
@@ -25,8 +18,8 @@ import dayjs from "dayjs";
25
18
  import { blue, gray, green, red, yellow } from "kolorist";
26
19
  var Logger = class {
27
20
  constructor(tag, withTime) {
28
- __publicField(this, "tag", PLUGIN_NAME);
29
- __publicField(this, "withTime", true);
21
+ this.tag = PLUGIN_NAME;
22
+ this.withTime = true;
30
23
  this.tag = `[${tag}]`;
31
24
  this.withTime = withTime ?? true;
32
25
  }
@@ -64,50 +57,47 @@ var createLogger = (tag) => {
64
57
 
65
58
  // src/main.ts
66
59
  var logger = createLogger();
67
- function getBuildOptions(options, innerOpts) {
68
- const env = {
69
- APP_DEV_SERVER_URL: innerOpts == null ? void 0 : innerOpts.serverUrl
70
- };
71
- Object.keys(env).forEach((key) => {
72
- if (env[key] === void 0) {
73
- delete env[key];
74
- }
75
- });
60
+ function getBuildOptions(options) {
76
61
  return ["main", "preload"].filter((s) => options[s] && options[s].entry).map((s) => {
77
62
  options[s].__NAME__ = s;
78
63
  return options[s];
79
64
  }).map((cfg) => {
80
65
  return {
81
66
  ...cfg,
82
- env,
83
67
  silent: true
84
68
  };
85
69
  });
86
70
  }
87
- function exitMainProcess() {
88
- logger.info("exit main process");
89
- process.exit(0);
90
- }
91
- function runMainProcess(options, innerOpts) {
92
- const mainFile = innerOpts.mainFile;
93
- logger.info(`run main file: ${lightGreen(mainFile)}`);
94
- const args = options.inspect ? ["--inspect"] : [];
95
- return spawn(electron, [...args, mainFile], {
71
+ async function startup(options) {
72
+ await startup.exit();
73
+ const args = [];
74
+ options.inspect && args.push("--inspect");
75
+ process.electronApp = spawn(electron, [".", ...args], {
96
76
  stdio: "inherit"
97
- }).on("exit", exitMainProcess);
77
+ });
78
+ process.electronApp.once("exit", process.exit);
79
+ process.once("exit", () => {
80
+ startup.exit();
81
+ process.electronApp.kill();
82
+ });
98
83
  }
99
- async function runServe(options, innerOpts, server) {
100
- let mainProcess;
101
- const killProcess = () => {
102
- if (mainProcess) {
103
- mainProcess.off("exit", exitMainProcess);
104
- mainProcess.kill();
105
- }
106
- };
107
- process.on("exit", () => {
108
- killProcess();
84
+ startup.exit = async () => {
85
+ if (!process.electronApp) {
86
+ return;
87
+ }
88
+ process.electronApp.removeAllListeners();
89
+ return new Promise((resolve, reject) => {
90
+ treeKill(process.electronApp.pid, (err) => {
91
+ if (err) {
92
+ reject(err);
93
+ } else {
94
+ resolve(true);
95
+ }
96
+ });
109
97
  });
110
- const buildOptions = getBuildOptions(options, innerOpts);
98
+ };
99
+ async function runServe(options, server) {
100
+ const buildOptions = getBuildOptions(options);
111
101
  for (let i = 0; i < buildOptions.length; i++) {
112
102
  let isFirstBuild = true;
113
103
  const tsOpts = buildOptions[i];
@@ -124,8 +114,8 @@ async function runServe(options, innerOpts, server) {
124
114
  }
125
115
  logger.success(`${name} rebuild succeeded!`);
126
116
  if (name === "main") {
127
- killProcess();
128
- mainProcess = runMainProcess(options, innerOpts);
117
+ console.log("main process exit");
118
+ await startup(options);
129
119
  } else {
130
120
  server.ws.send({
131
121
  type: "full-reload"
@@ -134,13 +124,10 @@ async function runServe(options, innerOpts, server) {
134
124
  };
135
125
  await tsupBuild({ onSuccess, watch: true, ...tsupOptions });
136
126
  }
137
- mainProcess = runMainProcess(options, innerOpts);
138
- return {
139
- kill: killProcess
140
- };
127
+ await startup(options);
141
128
  }
142
- async function runBuild(options, innerOpts) {
143
- const buildOptions = getBuildOptions(options, innerOpts);
129
+ async function runBuild(options) {
130
+ const buildOptions = getBuildOptions(options);
144
131
  for (let i = 0; i < buildOptions.length; i++) {
145
132
  await tsupBuild(buildOptions[i]);
146
133
  }
@@ -184,11 +171,9 @@ function preMergeOptions(options) {
184
171
  recommended: true,
185
172
  external: ["electron"],
186
173
  main: {
187
- name: "main",
188
174
  ...electron2
189
175
  },
190
176
  preload: {
191
- name: "payload",
192
177
  ...electron2
193
178
  }
194
179
  },
@@ -199,41 +184,45 @@ function preMergeOptions(options) {
199
184
  const fmt = opt.format;
200
185
  opt.format = ["cjs", "esm"].includes(fmt) ? [fmt] : [format];
201
186
  const entry = opt.entry;
202
- if (typeof entry === "string") {
187
+ if (entry == void 0) {
188
+ const filePath = `electron/${prop}/index.ts`;
189
+ if (fs2.existsSync(path.join(process.cwd(), filePath))) {
190
+ opt.entry = [filePath];
191
+ }
192
+ } else if (typeof entry === "string") {
203
193
  opt.entry = [entry];
204
194
  }
205
195
  const external = opt.external || opts.external || ["electron"];
206
196
  opt.external = [...new Set(["electron"].concat(external))];
207
197
  });
208
- const innerOpts = {
209
- mainFile: pkg.main
210
- };
211
- return { opts, innerOpts };
198
+ return opts;
212
199
  }
213
200
  function vitePluginElectron(options) {
214
- const { opts, innerOpts } = preMergeOptions(options);
201
+ const opts = preMergeOptions(options);
215
202
  const isDev = process.env.NODE_ENV === "development";
203
+ let isServer = false;
216
204
  return {
217
205
  name: PLUGIN_NAME,
218
206
  config(config, env) {
219
207
  var _a;
220
- innerOpts.isServer = env.mode === "serve";
208
+ isServer = env.command === "serve";
221
209
  let outDir = ((_a = config == null ? void 0 : config.build) == null ? void 0 : _a.outDir) || "dist";
222
- opts.preload = opts.preload || {};
210
+ opts.main ||= {};
211
+ opts.preload ||= {};
223
212
  if (opts.recommended) {
224
213
  opts.main.outDir = path.join(outDir, "main");
225
214
  opts.preload.outDir = path.join(outDir, "preload");
226
215
  outDir = path.join(outDir, "renderer");
227
216
  } else {
228
- opts.main.outDir = opts.main.outDir || path.join("dist-electron", "main");
229
- opts.preload.outDir = opts.preload.outDir || path.join("dist-electron", "preload");
217
+ opts.main.outDir ||= path.join("dist-electron", "main");
218
+ opts.preload.outDir ||= path.join("dist-electron", "preload");
230
219
  }
231
220
  if (isDev) {
232
- opts.main.sourcemap = opts.main.sourcemap ?? true;
233
- opts.preload.sourcemap = opts.main.sourcemap ?? true;
221
+ opts.main.sourcemap ??= true;
222
+ opts.preload.sourcemap ??= true;
234
223
  } else {
235
- opts.main.minify = opts.main.minify ?? true;
236
- opts.preload.minify = opts.preload.minify ?? true;
224
+ opts.main.minify ??= true;
225
+ opts.preload.minify ??= true;
237
226
  }
238
227
  return {
239
228
  build: {
@@ -246,25 +235,23 @@ function vitePluginElectron(options) {
246
235
  return;
247
236
  }
248
237
  server.httpServer.on("listening", async () => {
249
- var _a;
250
238
  if (server.httpServer) {
251
239
  const serve = server.httpServer.address();
252
240
  const { address, port, family } = serve;
253
241
  if (family === "IPv6") {
254
- innerOpts.serverUrl = `http://[${address}]:${port}`;
242
+ process.env.APP_DEV_SERVER_URL = `http://[${address}]:${port}`;
255
243
  } else {
256
- innerOpts.serverUrl = `http://${address}:${port}`;
244
+ process.env.APP_DEV_SERVER_URL = `http://${address}:${port}`;
257
245
  }
258
246
  }
259
- (_a = process.__tomjs_electron_serve__) == null ? void 0 : _a.kill();
260
- process.__tomjs_electron_serve__ = await runServe(opts, innerOpts, server);
247
+ await runServe(opts, server);
261
248
  });
262
249
  },
263
250
  async closeBundle() {
264
- if (innerOpts.isServer) {
251
+ if (isServer) {
265
252
  return;
266
253
  }
267
- await runBuild(opts, innerOpts);
254
+ await runBuild(opts);
268
255
  }
269
256
  };
270
257
  }
package/env.d.ts CHANGED
@@ -12,6 +12,6 @@ declare namespace NodeJS {
12
12
  /**
13
13
  * The url of the dev server.
14
14
  */
15
- readonly APP_DEV_SERVER_URL: string;
15
+ APP_DEV_SERVER_URL?: string;
16
16
  }
17
17
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomjs/vite-plugin-electron",
3
- "version": "1.1.2",
3
+ "version": "1.2.1",
4
4
  "description": "A simple vite plugin for electron, supports esm/cjs.",
5
5
  "keywords": [
6
6
  "vite",
@@ -44,6 +44,7 @@
44
44
  "lodash.clonedeep": "^4.5.0",
45
45
  "lodash.merge": "^4.6.2",
46
46
  "shelljs": "^0.8.5",
47
+ "tree-kill": "^1.2.2",
47
48
  "tsup": "7.2.0"
48
49
  },
49
50
  "devDependencies": {
@@ -51,8 +52,8 @@
51
52
  "@tomjs/commitlint": "^2.0.5",
52
53
  "@tomjs/eslint": "^1.1.1",
53
54
  "@tomjs/prettier": "^1.0.6",
54
- "@tomjs/stylelint": "^1.1.0",
55
- "@tomjs/tsconfig": "^1.0.8",
55
+ "@tomjs/stylelint": "^1.1.1",
56
+ "@tomjs/tsconfig": "^1.1.2",
56
57
  "@types/lodash.clonedeep": "^4.5.9",
57
58
  "@types/lodash.merge": "^4.6.9",
58
59
  "@types/node": "^18.19.3",
@@ -60,7 +61,7 @@
60
61
  "eslint": "^8.55.0",
61
62
  "husky": "^8.0.3",
62
63
  "lint-staged": "^15.2.0",
63
- "np": "^9.1.0",
64
+ "np": "^9.2.0",
64
65
  "npm-run-all": "^4.1.5",
65
66
  "prettier": "^3.1.0",
66
67
  "rimraf": "^5.0.5",