@tomjs/vite-plugin-electron 1.3.8 → 1.3.9-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
@@ -16,6 +16,7 @@ Many thanks to [caoxiemeihao](https://github.com/caoxiemeihao)'s [vite-plugin-el
16
16
  - Support `preload`'s `Hot Reload`
17
17
  - Support `esm` and `cjs`, you can use `esm` in [electron v28+](https://www.electronjs.org/blog/electron-28-0)
18
18
  - Support `vue` and `react` and other [frameworks](https://vitejs.dev/guide/#trying-vite-online) supported by `vite`
19
+ - Optional [electron-builder](https://www.electron.build/) Simple configuration
19
20
 
20
21
  ## Install
21
22
 
@@ -218,6 +219,63 @@ Based on [Options](https://paka.dev/npm/tsup) of [tsup](https://tsup.egoist.dev/
218
219
  | outDir | `string` | "dist-electron/preload" | The output directory for the preload process files |
219
220
  | onSuccess | `() => Promise<void \| undefined \| (() => void \| Promise<void>)>` | `undefined` | A function that will be executed after the build succeeds. |
220
221
 
222
+ # BuilderOptions
223
+
224
+ When `recommended` and `builder.enable` are both `true`, use [electron-builder](https://www.electron.build) to package Electron applications.
225
+
226
+ - In the `build.outDir` directory configured in vite, generate a new package.json based on the configuration and package.json, excluding non-dependencies.
227
+ - Execute `npm install` and then package.
228
+
229
+ _Not suitable for everyone._
230
+
231
+ To use this function, you need to install additional `electron-builder`
232
+
233
+ | Property | Type | Default | Description |
234
+ | --- | --- | --- | --- |
235
+ | enable | `boolean` | `false` | Whether to enable the [electron-builder](https://www.electron.build). |
236
+ | appId | `string` | `"com.electron.${name}"` | The application id. [See More](https://www.electron.build/configuration/configuration#configuration) |
237
+ | productName | `string` | `"com.electron.${name}"` | product name.[See More](https://www.electron.build/configuration/configuration#configuration) |
238
+ | builderConfig | [Configuration](https://www.electron.build/configuration/configuration#configurationF) | `undefined` | [electron-builder](https://www.electron.build)'s [Configuration](https://www.electron.build/configuration/configuration#configuration) |
239
+
240
+ The default configuration is as follows:
241
+
242
+ ```ts
243
+ const config = {
244
+ directories: {
245
+ buildResources: 'electron/build',
246
+ app: path.dirname(resolvedConfig.build.outDir),
247
+ output: 'release/${version}',
248
+ },
249
+ files: ['main', 'preload', 'renderer'],
250
+ artifactName: '${productName}-${version}-${os}-${arch}.${ext}',
251
+ electronDownload: {
252
+ // when npm registry mirror is 'registry.npmmirror.com'
253
+ mirror: 'https://npmmirror.com/mirrors/electron',
254
+ },
255
+ electronLanguages: ['zh-CN', 'en-US'],
256
+ win: {
257
+ target: [
258
+ {
259
+ target: 'nsis',
260
+ arch: ['x64'],
261
+ },
262
+ ],
263
+ },
264
+ mac: {
265
+ target: ['dmg'],
266
+ },
267
+ linux: {
268
+ target: ['zip'],
269
+ },
270
+ nsis: {
271
+ oneClick: false,
272
+ perMachine: false,
273
+ allowToChangeInstallationDirectory: true,
274
+ deleteAppDataOnUninstall: false,
275
+ },
276
+ };
277
+ ```
278
+
221
279
  ### Additional Information
222
280
 
223
281
  - Default values for `main` and `preload` when the relevant parameters are not configured
package/README.zh_CN.md CHANGED
@@ -16,6 +16,7 @@
16
16
  - 支持 `preload` 的 `热重载`
17
17
  - 支持 `esm` 和 `cjs` ,你可以在 [electron v28+](https://www.electronjs.org/zh/blog/electron-28-0) 中使用 `esm`
18
18
  - 支持 `vue` 和 `react` 等其他 `vite` 支持的[框架](https://cn.vitejs.dev/guide/#trying-vite-online)
19
+ - 可选 [electron-builder](https://www.electron.build/) 简单配置打包
19
20
 
20
21
  ## 安装
21
22
 
@@ -217,6 +218,63 @@ export default defineConfig({
217
218
  | outDir | `string` | `"dist-electron/preload"` | preload 输出文件夹 |
218
219
  | onSuccess | `() => Promise<void \| undefined \| (() => void \| Promise<void>)>` | `undefined` | 构建成功后运行的回调函数 |
219
220
 
221
+ ### BuilderOptions
222
+
223
+ 当 `recommended` 和 `builder.enable` 都为 `true` 时,使用 [electron-builder](https://www.electron.build) 打包 Electron 应用程序。
224
+
225
+ - 在vite中配置的`build.outDir`目录中,根据配置和package.json生成新的package.json,排除非依赖项。
226
+ - 执行`npm install`然后打包。
227
+
228
+ _不适合所有人使用。_
229
+
230
+ 使用该功能,需要额外安装 `electron-builder`
231
+
232
+ | 参数名 | 类型 | 默认值 | 说明 |
233
+ | --- | --- | --- | --- |
234
+ | enable | `boolean` | `false` | 是否启用 [electron-builder](https://www.electron.build) |
235
+ | appId | `string` | `"com.electron.${name}"` | 应用程序 ID。[详细](https://www.electron.build/configuration/configuration#configuration) |
236
+ | productName | `string` | `` | 应用程序名称。[详细](https://www.electron.build/configuration/configuration#configuration) |
237
+ | builderConfig | [Configuration](https://www.electron.build/configuration/configuration#configurationF) | `undefined` | [electron-builder](https://www.electron.build) 的 [Configuration](https://www.electron.build/configuration/configuration#configuration) |
238
+
239
+ 默认配置如下
240
+
241
+ ```ts
242
+ const config = {
243
+ directories: {
244
+ buildResources: 'electron/build',
245
+ app: path.dirname(resolvedConfig.build.outDir),
246
+ output: 'release/${version}',
247
+ },
248
+ files: ['main', 'preload', 'renderer'],
249
+ artifactName: '${productName}-${version}-${os}-${arch}.${ext}',
250
+ electronDownload: {
251
+ // when npm registry mirror is 'registry.npmmirror.com'
252
+ mirror: 'https://npmmirror.com/mirrors/electron',
253
+ },
254
+ electronLanguages: ['zh-CN', 'en-US'],
255
+ win: {
256
+ target: [
257
+ {
258
+ target: 'nsis',
259
+ arch: ['x64'],
260
+ },
261
+ ],
262
+ },
263
+ mac: {
264
+ target: ['dmg'],
265
+ },
266
+ linux: {
267
+ target: ['zip'],
268
+ },
269
+ nsis: {
270
+ oneClick: false,
271
+ perMachine: false,
272
+ allowToChangeInstallationDirectory: true,
273
+ deleteAppDataOnUninstall: false,
274
+ },
275
+ };
276
+ ```
277
+
220
278
  ### 补充说明
221
279
 
222
280
  - `main` 和 `preload` 未配置相关参数时的默认值
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Plugin } from 'vite';
2
+ import { Configuration } from 'electron-builder';
2
3
  import { Options } from 'tsup';
3
4
 
4
5
  /**
@@ -49,6 +50,34 @@ interface PreloadOptions extends Omit<Options, 'entry' | 'format' | 'outDir' | '
49
50
  */
50
51
  onSuccess?: () => Promise<void | undefined | (() => void | Promise<void>)>;
51
52
  }
53
+ /**
54
+ * When `recommended` and `builder.enable` are both `true`, use [electron-builder](https://www.electron.build) to package Electron applications.
55
+ *
56
+ * * In the `build.outDir` directory configured in vite, generate a new package.json based on the configuration and package.json, excluding non-dependencies.
57
+ * * Execute `npm install` and then package.
58
+ */
59
+ interface BuilderOptions {
60
+ /**
61
+ * Whether to enable the [electron-builder](https://www.electron.build), the default is false.
62
+ * @default false
63
+ */
64
+ enable?: boolean;
65
+ /**
66
+ * The application id. Used as [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for MacOS and as
67
+ * [Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows (NSIS target only, Squirrel.Windows not supported). It is strongly recommended that an explicit ID is set.
68
+ * @default com.electron.${name}
69
+ */
70
+ appId?: string | null;
71
+ /**
72
+ * As [name](#Metadata-name), but allows you to specify a product name for your executable which contains spaces and other special characters not allowed in the [name property](https://docs.npmjs.com/files/package.json#name).
73
+ * If not specified inside of the `build` configuration, `productName` property defined at the top level of `package.json` is used. If not specified at the top level of `package.json`, [name property](https://docs.npmjs.com/files/package.json#name) is used.
74
+ */
75
+ productName?: string | null;
76
+ /**
77
+ * The [electron-builder](https://www.electron.build/configuration/configuration) configuration.
78
+ */
79
+ builderConfig?: Configuration;
80
+ }
52
81
  /**
53
82
  * vite plugin options
54
83
  */
@@ -65,7 +94,7 @@ interface PluginOptions {
65
94
  * Don't bundle these modules, but dependencies and peerDependencies in your package.json are always excluded. [See more](https://tsup.egoist.dev/#excluding-packages)
66
95
  * @see https://tsup.egoist.dev/#excluding-packages
67
96
  */
68
- external?: string[];
97
+ external?: (string | RegExp)[];
69
98
  /**
70
99
  * electron main process options
71
100
  */
@@ -74,6 +103,13 @@ interface PluginOptions {
74
103
  * electron preload process options
75
104
  */
76
105
  preload?: PreloadOptions;
106
+ /**
107
+ * When `recommended` and `builder.enable` are both `true`, use [electron-builder](https://www.electron.build) to package Electron applications.
108
+ *
109
+ * * In the `build.outDir` directory configured in vite, generate a new package.json based on the configuration and package.json, excluding non-dependencies.
110
+ * * Execute `npm install` and then package.
111
+ */
112
+ builder?: BuilderOptions;
77
113
  /**
78
114
  * electron debug mode, don't startup electron. You can also use `process.env.APP_ELECTRON_DEBUG`. Default is false.
79
115
  * @default false
@@ -89,6 +125,10 @@ interface PluginOptions {
89
125
  inspect?: number | boolean;
90
126
  }
91
127
 
92
- declare function vitePluginElectron(options?: PluginOptions): Plugin;
128
+ /**
129
+ * A simple vite plugin for electron
130
+ * @param options
131
+ */
132
+ declare function useElectronPlugin(options?: PluginOptions): Plugin;
93
133
 
94
- export { MainOptions, PluginOptions, PreloadOptions, vitePluginElectron as default, vitePluginElectron };
134
+ export { BuilderOptions, MainOptions, PluginOptions, PreloadOptions, useElectronPlugin as default, useElectronPlugin };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Plugin } from 'vite';
2
+ import { Configuration } from 'electron-builder';
2
3
  import { Options } from 'tsup';
3
4
 
4
5
  /**
@@ -49,6 +50,34 @@ interface PreloadOptions extends Omit<Options, 'entry' | 'format' | 'outDir' | '
49
50
  */
50
51
  onSuccess?: () => Promise<void | undefined | (() => void | Promise<void>)>;
51
52
  }
53
+ /**
54
+ * When `recommended` and `builder.enable` are both `true`, use [electron-builder](https://www.electron.build) to package Electron applications.
55
+ *
56
+ * * In the `build.outDir` directory configured in vite, generate a new package.json based on the configuration and package.json, excluding non-dependencies.
57
+ * * Execute `npm install` and then package.
58
+ */
59
+ interface BuilderOptions {
60
+ /**
61
+ * Whether to enable the [electron-builder](https://www.electron.build), the default is false.
62
+ * @default false
63
+ */
64
+ enable?: boolean;
65
+ /**
66
+ * The application id. Used as [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for MacOS and as
67
+ * [Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows (NSIS target only, Squirrel.Windows not supported). It is strongly recommended that an explicit ID is set.
68
+ * @default com.electron.${name}
69
+ */
70
+ appId?: string | null;
71
+ /**
72
+ * As [name](#Metadata-name), but allows you to specify a product name for your executable which contains spaces and other special characters not allowed in the [name property](https://docs.npmjs.com/files/package.json#name).
73
+ * If not specified inside of the `build` configuration, `productName` property defined at the top level of `package.json` is used. If not specified at the top level of `package.json`, [name property](https://docs.npmjs.com/files/package.json#name) is used.
74
+ */
75
+ productName?: string | null;
76
+ /**
77
+ * The [electron-builder](https://www.electron.build/configuration/configuration) configuration.
78
+ */
79
+ builderConfig?: Configuration;
80
+ }
52
81
  /**
53
82
  * vite plugin options
54
83
  */
@@ -65,7 +94,7 @@ interface PluginOptions {
65
94
  * Don't bundle these modules, but dependencies and peerDependencies in your package.json are always excluded. [See more](https://tsup.egoist.dev/#excluding-packages)
66
95
  * @see https://tsup.egoist.dev/#excluding-packages
67
96
  */
68
- external?: string[];
97
+ external?: (string | RegExp)[];
69
98
  /**
70
99
  * electron main process options
71
100
  */
@@ -74,6 +103,13 @@ interface PluginOptions {
74
103
  * electron preload process options
75
104
  */
76
105
  preload?: PreloadOptions;
106
+ /**
107
+ * When `recommended` and `builder.enable` are both `true`, use [electron-builder](https://www.electron.build) to package Electron applications.
108
+ *
109
+ * * In the `build.outDir` directory configured in vite, generate a new package.json based on the configuration and package.json, excluding non-dependencies.
110
+ * * Execute `npm install` and then package.
111
+ */
112
+ builder?: BuilderOptions;
77
113
  /**
78
114
  * electron debug mode, don't startup electron. You can also use `process.env.APP_ELECTRON_DEBUG`. Default is false.
79
115
  * @default false
@@ -89,6 +125,10 @@ interface PluginOptions {
89
125
  inspect?: number | boolean;
90
126
  }
91
127
 
92
- declare function vitePluginElectron(options?: PluginOptions): Plugin;
128
+ /**
129
+ * A simple vite plugin for electron
130
+ * @param options
131
+ */
132
+ declare function useElectronPlugin(options?: PluginOptions): Plugin;
93
133
 
94
- export { MainOptions, PluginOptions, PreloadOptions, vitePluginElectron as default, vitePluginElectron };
134
+ export { BuilderOptions, MainOptions, PluginOptions, PreloadOptions, useElectronPlugin as default, useElectronPlugin };
package/dist/index.js CHANGED
@@ -1,22 +1,25 @@
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
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } 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
2
2
  var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
3
3
  var _process = require('process');
4
4
  var _lodashclonedeep = require('lodash.clonedeep'); var _lodashclonedeep2 = _interopRequireDefault(_lodashclonedeep);
5
5
  var _lodashmerge = require('lodash.merge'); var _lodashmerge2 = _interopRequireDefault(_lodashmerge);
6
6
  var _path = require('path'); var _path2 = _interopRequireDefault(_path);
7
7
 
8
- // src/constants.ts
9
- var PLUGIN_NAME = "@tomjs:electron";
8
+ // src/builder.ts
9
+ var _os = require('os'); var _os2 = _interopRequireDefault(_os);
10
+
11
+
10
12
 
11
- // src/main.ts
12
- var _child_process = require('child_process');
13
- var _electron = require('electron'); var _electron2 = _interopRequireDefault(_electron);
14
- var _treekill = require('tree-kill'); var _treekill2 = _interopRequireDefault(_treekill);
15
- var _tsup = require('tsup');
16
13
 
17
14
  // src/logger.ts
18
15
  var _dayjs = require('dayjs'); var _dayjs2 = _interopRequireDefault(_dayjs);
19
16
  var _kolorist = require('kolorist');
17
+
18
+ // src/constants.ts
19
+ var PLUGIN_NAME = "@tomjs:electron";
20
+ var PACKAGE_NAME = "@tomjs/vite-plugin-electron";
21
+
22
+ // src/logger.ts
20
23
  var Logger = class {
21
24
  constructor(tag, withTime) {
22
25
  this.tag = PLUGIN_NAME;
@@ -56,8 +59,170 @@ var createLogger = (tag) => {
56
59
  return new Logger(tag || PLUGIN_NAME, true);
57
60
  };
58
61
 
59
- // src/main.ts
62
+ // src/utils.ts
63
+ var _child_process = require('child_process');
64
+
65
+ var _module = require('module');
66
+ function readJson(path3) {
67
+ if (_fs2.default.existsSync(path3)) {
68
+ return JSON.parse(_fs2.default.readFileSync(path3, "utf8"));
69
+ }
70
+ }
71
+ function writeJson(path3, data) {
72
+ _fs2.default.writeFileSync(path3, JSON.stringify(data, null, 2), "utf8");
73
+ }
74
+ function exec(command, args, options) {
75
+ return _child_process.spawnSync.call(void 0, command, args, Object.assign({ encoding: "utf8" }, options));
76
+ }
77
+
78
+ // src/builder.ts
60
79
  var logger = createLogger();
80
+ function getMirror() {
81
+ let mirror = process.env.ELECTRON_MIRROR;
82
+ if (mirror) {
83
+ return mirror;
84
+ }
85
+ const res = exec(_os2.default.platform() === "win32" ? "npm.cmd" : "npm", ["config", "get", "registry"]);
86
+ if (res.status === 0) {
87
+ let registry = res.stdout;
88
+ if (!registry) {
89
+ return;
90
+ }
91
+ registry = registry.trim();
92
+ if (registry && ["registry.npmmirror.com", "registry.npm.taobao.org"].find((s) => registry.includes(s))) {
93
+ mirror = "https://npmmirror.com/mirrors/electron";
94
+ }
95
+ }
96
+ return mirror;
97
+ }
98
+ function getBuilderConfig(options, resolvedConfig) {
99
+ var _a;
100
+ createPkg(options, resolvedConfig);
101
+ const config = {
102
+ directories: {
103
+ buildResources: "electron/build",
104
+ app: _path2.default.dirname(resolvedConfig.build.outDir),
105
+ output: "release/${version}"
106
+ },
107
+ files: ["main", "preload", "renderer"],
108
+ artifactName: "${productName}-${version}-${os}-${arch}.${ext}",
109
+ electronDownload: {
110
+ mirror: getMirror()
111
+ },
112
+ electronLanguages: ["zh-CN", "en-US"],
113
+ win: {
114
+ target: [
115
+ {
116
+ target: "nsis",
117
+ arch: ["x64"]
118
+ }
119
+ ]
120
+ },
121
+ mac: {
122
+ target: ["dmg"]
123
+ },
124
+ linux: {
125
+ target: ["zip"]
126
+ },
127
+ nsis: {
128
+ oneClick: false,
129
+ perMachine: false,
130
+ allowToChangeInstallationDirectory: true,
131
+ deleteAppDataOnUninstall: false
132
+ }
133
+ };
134
+ const { appId, productName } = options.builder || {};
135
+ return _lodashmerge2.default.call(void 0, config, { appId, productName }, (_a = options.builder) == null ? void 0 : _a.builderConfig);
136
+ }
137
+ function createPkg(options, resolvedConfig) {
138
+ var _a, _b;
139
+ const externals = options.external || [];
140
+ const viteExternals = (_a = resolvedConfig.build.rollupOptions) == null ? void 0 : _a.external;
141
+ if (Array.isArray(viteExternals)) {
142
+ externals.push(...viteExternals);
143
+ } else if (typeof viteExternals === "string") {
144
+ externals.push(viteExternals);
145
+ }
146
+ const pkg = readJson(_path2.default.join(process.cwd(), "package.json"));
147
+ if (!pkg) {
148
+ throw new Error(`package.json not found in ${process.cwd()}`);
149
+ }
150
+ const outDir = _path2.default.dirname(resolvedConfig.build.outDir);
151
+ let main = pkg.main;
152
+ if (main) {
153
+ main = main.replace("./", "");
154
+ main = main.substring(main.indexOf(outDir) + outDir.length);
155
+ if (main.startsWith("/")) {
156
+ main = main.substring(1);
157
+ }
158
+ } else {
159
+ main = `main/index.${((_b = options == null ? void 0 : options.main) == null ? void 0 : _b.format) === "esm" ? "" : "m"}js`;
160
+ }
161
+ const newPkg = {
162
+ name: pkg.name,
163
+ version: pkg.version,
164
+ description: pkg.description,
165
+ type: pkg.type || "commonjs",
166
+ author: getAuthor(pkg.author),
167
+ main,
168
+ dependencies: getDeps()
169
+ };
170
+ writeJson(_path2.default.join(outDir, "package.json"), newPkg);
171
+ function getAuthor(author) {
172
+ const uname = _os2.default.userInfo().username;
173
+ if (!author) {
174
+ return uname;
175
+ } else if (typeof author === "string") {
176
+ return author;
177
+ } else if (typeof author === "object") {
178
+ if (!author.name) {
179
+ return uname;
180
+ }
181
+ const email = author.email ? ` <${author.email}>` : "";
182
+ return `${author.name}${email}`;
183
+ }
184
+ return uname;
185
+ }
186
+ function checkDepName(rules, name) {
187
+ return !!rules.find((s) => {
188
+ if (typeof s === "string") {
189
+ return s.includes(name);
190
+ } else {
191
+ return s.test(name);
192
+ }
193
+ });
194
+ }
195
+ function getDeps() {
196
+ const deps = pkg.dependencies || {};
197
+ const newDeps = {};
198
+ Object.keys(deps).forEach((name) => {
199
+ if (checkDepName(externals, name)) {
200
+ newDeps[name] = deps[name];
201
+ }
202
+ });
203
+ return newDeps;
204
+ }
205
+ return newPkg;
206
+ }
207
+ async function runElectronBuilder(options, resolvedConfig) {
208
+ logger.info("building electron app...");
209
+ const DIST_PATH = _path2.default.join(_process.cwd.call(void 0, ), _path2.default.dirname(resolvedConfig.build.outDir));
210
+ logger.info(`create package.json and exec "npm install"`);
211
+ exec(`cd ${DIST_PATH} && npm run build`);
212
+ logger.info(`run electron-builder to package app`);
213
+ const config = getBuilderConfig(options, resolvedConfig);
214
+ const { build } = await Promise.resolve().then(() => _interopRequireWildcard(require("electron-builder")));
215
+ await build({
216
+ config
217
+ });
218
+ }
219
+
220
+ // src/main.ts
221
+
222
+ var _electron = require('electron'); var _electron2 = _interopRequireDefault(_electron);
223
+ var _treekill = require('tree-kill'); var _treekill2 = _interopRequireDefault(_treekill);
224
+ var _tsup = require('tsup');
225
+ var logger2 = createLogger();
61
226
  function getBuildOptions(options) {
62
227
  return ["main", "preload"].filter((s) => options[s] && options[s].entry).map((s) => {
63
228
  options[s].__NAME__ = s;
@@ -108,32 +273,32 @@ startup.exit = async () => {
108
273
  });
109
274
  };
110
275
  async function runServe(options, server) {
111
- options.debug && logger.warn(`debug mode`);
276
+ options.debug && logger2.warn(`debug mode`);
112
277
  const buildOptions = getBuildOptions(options);
113
278
  const buildCounts = [0, buildOptions.length > 1 ? 0 : 1];
114
279
  for (let i = 0; i < buildOptions.length; i++) {
115
280
  const tsOpts = buildOptions[i];
116
281
  const { __NAME__: name, onSuccess: _onSuccess, watch, ...tsupOptions } = tsOpts;
117
- logger.info(`${name} build`);
282
+ logger2.info(`${name} build`);
118
283
  const onSuccess = async () => {
119
284
  if (typeof _onSuccess === "function") {
120
285
  await _onSuccess();
121
286
  }
122
287
  if (buildCounts[i] <= 0) {
123
288
  buildCounts[i]++;
124
- logger.info(`${name} build succeeded`);
289
+ logger2.info(`${name} build succeeded`);
125
290
  if (buildCounts[0] == 1 && buildCounts[1] == 1) {
126
- logger.info("electron startup");
291
+ logger2.info("electron startup");
127
292
  await startup(options);
128
293
  }
129
294
  return;
130
295
  }
131
- logger.success(`${name} rebuild succeeded!`);
296
+ logger2.success(`${name} rebuild succeeded!`);
132
297
  if (name === "main") {
133
- logger.info("electron restart");
298
+ logger2.info("electron restart");
134
299
  await startup(options);
135
300
  } else {
136
- logger.info("page reload");
301
+ logger2.info("page reload");
137
302
  server.ws.send({
138
303
  type: "full-reload"
139
304
  });
@@ -149,15 +314,6 @@ async function runBuild(options) {
149
314
  }
150
315
  }
151
316
 
152
- // src/utils.ts
153
-
154
- var _module = require('module');
155
- function readJson(path2) {
156
- if (_fs2.default.existsSync(path2)) {
157
- return JSON.parse(_fs2.default.readFileSync(path2, "utf8"));
158
- }
159
- }
160
-
161
317
  // src/index.ts
162
318
  var isDev = process.env.NODE_ENV === "development";
163
319
  function getPkg() {
@@ -228,9 +384,10 @@ function geNumberBooleanValue(value) {
228
384
  const v = Number(value);
229
385
  return Number.isNaN(v) ? void 0 : v;
230
386
  }
231
- function vitePluginElectron(options) {
387
+ function useElectronPlugin(options) {
232
388
  const opts = preMergeOptions(options);
233
389
  let isServer = false;
390
+ let resolvedConfig;
234
391
  return {
235
392
  name: PLUGIN_NAME,
236
393
  config(config, env) {
@@ -273,6 +430,7 @@ function vitePluginElectron(options) {
273
430
  configResolved(config) {
274
431
  opts.debug = config.env.APP_ELECTRON_DEBUG ? !!config.env.APP_ELECTRON_DEBUG : opts.debug;
275
432
  opts.inspect = config.env.APP_ELECTRON_INSPECT ? geNumberBooleanValue(config.env.APP_ELECTRON_INSPECT) : opts.inspect;
433
+ resolvedConfig = config;
276
434
  },
277
435
  configureServer(server) {
278
436
  if (!server || !server.httpServer) {
@@ -285,13 +443,7 @@ function vitePluginElectron(options) {
285
443
  const hostname = family === "IPv6" ? `[${address}]` : address;
286
444
  const protocol = server.config.server.https ? "https" : "http";
287
445
  process.env.APP_DEV_SERVER_URL = `${protocol}://${hostname}:${port}`;
288
- const DEBUG_PATH = _path2.default.resolve(
289
- _process.cwd.call(void 0, ),
290
- "node_modules",
291
- "@tomjs",
292
- "vite-plugin-electron",
293
- "debug"
294
- );
446
+ const DEBUG_PATH = _path2.default.resolve(_process.cwd.call(void 0, ), "node_modules", PACKAGE_NAME, "debug");
295
447
  if (!_fs2.default.existsSync(DEBUG_PATH)) {
296
448
  _fs.mkdirSync.call(void 0, DEBUG_PATH, { recursive: true });
297
449
  }
@@ -302,15 +454,19 @@ ${env}`);
302
454
  });
303
455
  },
304
456
  async closeBundle() {
457
+ var _a;
305
458
  if (isServer) {
306
459
  return;
307
460
  }
308
461
  await runBuild(opts);
462
+ if (opts.recommended && ((_a = opts.builder) == null ? void 0 : _a.enable)) {
463
+ await runElectronBuilder(opts, resolvedConfig);
464
+ }
309
465
  }
310
466
  };
311
467
  }
312
- var src_default = vitePluginElectron;
468
+ var src_default = useElectronPlugin;
313
469
 
314
470
 
315
471
 
316
- exports.default = src_default; exports.vitePluginElectron = vitePluginElectron;
472
+ exports.default = src_default; exports.useElectronPlugin = useElectronPlugin;
package/dist/index.mjs CHANGED
@@ -1,22 +1,25 @@
1
1
  // src/index.ts
2
2
  import fs2, { mkdirSync, writeFileSync } from "fs";
3
- import { cwd } from "process";
3
+ import { cwd as cwd2 } from "process";
4
4
  import cloneDeep from "lodash.clonedeep";
5
- import merge from "lodash.merge";
5
+ import merge2 from "lodash.merge";
6
+ import path2 from "path";
7
+
8
+ // src/builder.ts
9
+ import os from "os";
6
10
  import path from "path";
11
+ import { cwd } from "process";
12
+ import merge from "lodash.merge";
13
+
14
+ // src/logger.ts
15
+ import dayjs from "dayjs";
16
+ import { blue, gray, green, red, yellow } from "kolorist";
7
17
 
8
18
  // src/constants.ts
9
19
  var PLUGIN_NAME = "@tomjs:electron";
10
-
11
- // src/main.ts
12
- import { spawn } from "child_process";
13
- import electron from "electron";
14
- import treeKill from "tree-kill";
15
- import { build as tsupBuild } from "tsup";
20
+ var PACKAGE_NAME = "@tomjs/vite-plugin-electron";
16
21
 
17
22
  // src/logger.ts
18
- import dayjs from "dayjs";
19
- import { blue, gray, green, red, yellow } from "kolorist";
20
23
  var Logger = class {
21
24
  constructor(tag, withTime) {
22
25
  this.tag = PLUGIN_NAME;
@@ -56,8 +59,169 @@ var createLogger = (tag) => {
56
59
  return new Logger(tag || PLUGIN_NAME, true);
57
60
  };
58
61
 
59
- // src/main.ts
62
+ // src/utils.ts
63
+ import { spawnSync } from "child_process";
64
+ import fs from "fs";
65
+ function readJson(path3) {
66
+ if (fs.existsSync(path3)) {
67
+ return JSON.parse(fs.readFileSync(path3, "utf8"));
68
+ }
69
+ }
70
+ function writeJson(path3, data) {
71
+ fs.writeFileSync(path3, JSON.stringify(data, null, 2), "utf8");
72
+ }
73
+ function exec(command, args, options) {
74
+ return spawnSync(command, args, Object.assign({ encoding: "utf8" }, options));
75
+ }
76
+
77
+ // src/builder.ts
60
78
  var logger = createLogger();
79
+ function getMirror() {
80
+ let mirror = process.env.ELECTRON_MIRROR;
81
+ if (mirror) {
82
+ return mirror;
83
+ }
84
+ const res = exec(os.platform() === "win32" ? "npm.cmd" : "npm", ["config", "get", "registry"]);
85
+ if (res.status === 0) {
86
+ let registry = res.stdout;
87
+ if (!registry) {
88
+ return;
89
+ }
90
+ registry = registry.trim();
91
+ if (registry && ["registry.npmmirror.com", "registry.npm.taobao.org"].find((s) => registry.includes(s))) {
92
+ mirror = "https://npmmirror.com/mirrors/electron";
93
+ }
94
+ }
95
+ return mirror;
96
+ }
97
+ function getBuilderConfig(options, resolvedConfig) {
98
+ var _a;
99
+ createPkg(options, resolvedConfig);
100
+ const config = {
101
+ directories: {
102
+ buildResources: "electron/build",
103
+ app: path.dirname(resolvedConfig.build.outDir),
104
+ output: "release/${version}"
105
+ },
106
+ files: ["main", "preload", "renderer"],
107
+ artifactName: "${productName}-${version}-${os}-${arch}.${ext}",
108
+ electronDownload: {
109
+ mirror: getMirror()
110
+ },
111
+ electronLanguages: ["zh-CN", "en-US"],
112
+ win: {
113
+ target: [
114
+ {
115
+ target: "nsis",
116
+ arch: ["x64"]
117
+ }
118
+ ]
119
+ },
120
+ mac: {
121
+ target: ["dmg"]
122
+ },
123
+ linux: {
124
+ target: ["zip"]
125
+ },
126
+ nsis: {
127
+ oneClick: false,
128
+ perMachine: false,
129
+ allowToChangeInstallationDirectory: true,
130
+ deleteAppDataOnUninstall: false
131
+ }
132
+ };
133
+ const { appId, productName } = options.builder || {};
134
+ return merge(config, { appId, productName }, (_a = options.builder) == null ? void 0 : _a.builderConfig);
135
+ }
136
+ function createPkg(options, resolvedConfig) {
137
+ var _a, _b;
138
+ const externals = options.external || [];
139
+ const viteExternals = (_a = resolvedConfig.build.rollupOptions) == null ? void 0 : _a.external;
140
+ if (Array.isArray(viteExternals)) {
141
+ externals.push(...viteExternals);
142
+ } else if (typeof viteExternals === "string") {
143
+ externals.push(viteExternals);
144
+ }
145
+ const pkg = readJson(path.join(process.cwd(), "package.json"));
146
+ if (!pkg) {
147
+ throw new Error(`package.json not found in ${process.cwd()}`);
148
+ }
149
+ const outDir = path.dirname(resolvedConfig.build.outDir);
150
+ let main = pkg.main;
151
+ if (main) {
152
+ main = main.replace("./", "");
153
+ main = main.substring(main.indexOf(outDir) + outDir.length);
154
+ if (main.startsWith("/")) {
155
+ main = main.substring(1);
156
+ }
157
+ } else {
158
+ main = `main/index.${((_b = options == null ? void 0 : options.main) == null ? void 0 : _b.format) === "esm" ? "" : "m"}js`;
159
+ }
160
+ const newPkg = {
161
+ name: pkg.name,
162
+ version: pkg.version,
163
+ description: pkg.description,
164
+ type: pkg.type || "commonjs",
165
+ author: getAuthor(pkg.author),
166
+ main,
167
+ dependencies: getDeps()
168
+ };
169
+ writeJson(path.join(outDir, "package.json"), newPkg);
170
+ function getAuthor(author) {
171
+ const uname = os.userInfo().username;
172
+ if (!author) {
173
+ return uname;
174
+ } else if (typeof author === "string") {
175
+ return author;
176
+ } else if (typeof author === "object") {
177
+ if (!author.name) {
178
+ return uname;
179
+ }
180
+ const email = author.email ? ` <${author.email}>` : "";
181
+ return `${author.name}${email}`;
182
+ }
183
+ return uname;
184
+ }
185
+ function checkDepName(rules, name) {
186
+ return !!rules.find((s) => {
187
+ if (typeof s === "string") {
188
+ return s.includes(name);
189
+ } else {
190
+ return s.test(name);
191
+ }
192
+ });
193
+ }
194
+ function getDeps() {
195
+ const deps = pkg.dependencies || {};
196
+ const newDeps = {};
197
+ Object.keys(deps).forEach((name) => {
198
+ if (checkDepName(externals, name)) {
199
+ newDeps[name] = deps[name];
200
+ }
201
+ });
202
+ return newDeps;
203
+ }
204
+ return newPkg;
205
+ }
206
+ async function runElectronBuilder(options, resolvedConfig) {
207
+ logger.info("building electron app...");
208
+ const DIST_PATH = path.join(cwd(), path.dirname(resolvedConfig.build.outDir));
209
+ logger.info(`create package.json and exec "npm install"`);
210
+ exec(`cd ${DIST_PATH} && npm run build`);
211
+ logger.info(`run electron-builder to package app`);
212
+ const config = getBuilderConfig(options, resolvedConfig);
213
+ const { build } = await import("electron-builder");
214
+ await build({
215
+ config
216
+ });
217
+ }
218
+
219
+ // src/main.ts
220
+ import { spawn } from "child_process";
221
+ import electron from "electron";
222
+ import treeKill from "tree-kill";
223
+ import { build as tsupBuild } from "tsup";
224
+ var logger2 = createLogger();
61
225
  function getBuildOptions(options) {
62
226
  return ["main", "preload"].filter((s) => options[s] && options[s].entry).map((s) => {
63
227
  options[s].__NAME__ = s;
@@ -108,32 +272,32 @@ startup.exit = async () => {
108
272
  });
109
273
  };
110
274
  async function runServe(options, server) {
111
- options.debug && logger.warn(`debug mode`);
275
+ options.debug && logger2.warn(`debug mode`);
112
276
  const buildOptions = getBuildOptions(options);
113
277
  const buildCounts = [0, buildOptions.length > 1 ? 0 : 1];
114
278
  for (let i = 0; i < buildOptions.length; i++) {
115
279
  const tsOpts = buildOptions[i];
116
280
  const { __NAME__: name, onSuccess: _onSuccess, watch, ...tsupOptions } = tsOpts;
117
- logger.info(`${name} build`);
281
+ logger2.info(`${name} build`);
118
282
  const onSuccess = async () => {
119
283
  if (typeof _onSuccess === "function") {
120
284
  await _onSuccess();
121
285
  }
122
286
  if (buildCounts[i] <= 0) {
123
287
  buildCounts[i]++;
124
- logger.info(`${name} build succeeded`);
288
+ logger2.info(`${name} build succeeded`);
125
289
  if (buildCounts[0] == 1 && buildCounts[1] == 1) {
126
- logger.info("electron startup");
290
+ logger2.info("electron startup");
127
291
  await startup(options);
128
292
  }
129
293
  return;
130
294
  }
131
- logger.success(`${name} rebuild succeeded!`);
295
+ logger2.success(`${name} rebuild succeeded!`);
132
296
  if (name === "main") {
133
- logger.info("electron restart");
297
+ logger2.info("electron restart");
134
298
  await startup(options);
135
299
  } else {
136
- logger.info("page reload");
300
+ logger2.info("page reload");
137
301
  server.ws.send({
138
302
  type: "full-reload"
139
303
  });
@@ -149,18 +313,10 @@ async function runBuild(options) {
149
313
  }
150
314
  }
151
315
 
152
- // src/utils.ts
153
- import fs from "fs";
154
- function readJson(path2) {
155
- if (fs.existsSync(path2)) {
156
- return JSON.parse(fs.readFileSync(path2, "utf8"));
157
- }
158
- }
159
-
160
316
  // src/index.ts
161
317
  var isDev = process.env.NODE_ENV === "development";
162
318
  function getPkg() {
163
- const pkgFile = path.resolve(process.cwd(), "package.json");
319
+ const pkgFile = path2.resolve(process.cwd(), "package.json");
164
320
  if (!fs2.existsSync(pkgFile)) {
165
321
  throw new Error("Main file is not specified, and no package.json found");
166
322
  }
@@ -185,7 +341,7 @@ function preMergeOptions(options) {
185
341
  };
186
342
  }
187
343
  };
188
- const opts = merge(
344
+ const opts = merge2(
189
345
  {
190
346
  recommended: true,
191
347
  debug: false,
@@ -206,7 +362,7 @@ function preMergeOptions(options) {
206
362
  const entry = opt.entry;
207
363
  if (entry == void 0) {
208
364
  const filePath = `electron/${prop}/index.ts`;
209
- if (fs2.existsSync(path.join(process.cwd(), filePath))) {
365
+ if (fs2.existsSync(path2.join(process.cwd(), filePath))) {
210
366
  opt.entry = [filePath];
211
367
  }
212
368
  } else if (typeof entry === "string") {
@@ -227,9 +383,10 @@ function geNumberBooleanValue(value) {
227
383
  const v = Number(value);
228
384
  return Number.isNaN(v) ? void 0 : v;
229
385
  }
230
- function vitePluginElectron(options) {
386
+ function useElectronPlugin(options) {
231
387
  const opts = preMergeOptions(options);
232
388
  let isServer = false;
389
+ let resolvedConfig;
233
390
  return {
234
391
  name: PLUGIN_NAME,
235
392
  config(config, env) {
@@ -239,12 +396,12 @@ function vitePluginElectron(options) {
239
396
  opts.main ||= {};
240
397
  opts.preload ||= {};
241
398
  if (opts.recommended) {
242
- opts.main.outDir = path.join(outDir, "main");
243
- opts.preload.outDir = path.join(outDir, "preload");
244
- outDir = path.join(outDir, "renderer");
399
+ opts.main.outDir = path2.join(outDir, "main");
400
+ opts.preload.outDir = path2.join(outDir, "preload");
401
+ outDir = path2.join(outDir, "renderer");
245
402
  } else {
246
- opts.main.outDir ||= path.join("dist-electron", "main");
247
- opts.preload.outDir ||= path.join("dist-electron", "preload");
403
+ opts.main.outDir ||= path2.join("dist-electron", "main");
404
+ opts.preload.outDir ||= path2.join("dist-electron", "preload");
248
405
  }
249
406
  if (isDev) {
250
407
  opts.main.sourcemap ??= true;
@@ -272,6 +429,7 @@ function vitePluginElectron(options) {
272
429
  configResolved(config) {
273
430
  opts.debug = config.env.APP_ELECTRON_DEBUG ? !!config.env.APP_ELECTRON_DEBUG : opts.debug;
274
431
  opts.inspect = config.env.APP_ELECTRON_INSPECT ? geNumberBooleanValue(config.env.APP_ELECTRON_INSPECT) : opts.inspect;
432
+ resolvedConfig = config;
275
433
  },
276
434
  configureServer(server) {
277
435
  if (!server || !server.httpServer) {
@@ -284,32 +442,30 @@ function vitePluginElectron(options) {
284
442
  const hostname = family === "IPv6" ? `[${address}]` : address;
285
443
  const protocol = server.config.server.https ? "https" : "http";
286
444
  process.env.APP_DEV_SERVER_URL = `${protocol}://${hostname}:${port}`;
287
- const DEBUG_PATH = path.resolve(
288
- cwd(),
289
- "node_modules",
290
- "@tomjs",
291
- "vite-plugin-electron",
292
- "debug"
293
- );
445
+ const DEBUG_PATH = path2.resolve(cwd2(), "node_modules", PACKAGE_NAME, "debug");
294
446
  if (!fs2.existsSync(DEBUG_PATH)) {
295
447
  mkdirSync(DEBUG_PATH, { recursive: true });
296
448
  }
297
449
  const env = Object.keys(process.env).filter((s) => s.startsWith("APP_") || s.startsWith("VITE_")).map((s) => `${s}=${process.env[s]}`).join("\n");
298
- writeFileSync(path.join(DEBUG_PATH, ".env"), `NODE_ENV=development
450
+ writeFileSync(path2.join(DEBUG_PATH, ".env"), `NODE_ENV=development
299
451
  ${env}`);
300
452
  await runServe(opts, server);
301
453
  });
302
454
  },
303
455
  async closeBundle() {
456
+ var _a;
304
457
  if (isServer) {
305
458
  return;
306
459
  }
307
460
  await runBuild(opts);
461
+ if (opts.recommended && ((_a = opts.builder) == null ? void 0 : _a.enable)) {
462
+ await runElectronBuilder(opts, resolvedConfig);
463
+ }
308
464
  }
309
465
  };
310
466
  }
311
- var src_default = vitePluginElectron;
467
+ var src_default = useElectronPlugin;
312
468
  export {
313
469
  src_default as default,
314
- vitePluginElectron
470
+ useElectronPlugin
315
471
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tomjs/vite-plugin-electron",
3
- "version": "1.3.8",
3
+ "version": "1.3.9-1",
4
4
  "description": "A simple vite plugin for electron, supports esm/cjs, support esm in electron v28+",
5
5
  "keywords": [
6
6
  "vite",
@@ -40,6 +40,16 @@
40
40
  "type": "git",
41
41
  "url": "git+https://github.com/tomgao365/vite-plugin-electron.git"
42
42
  },
43
+ "scripts": {
44
+ "dev": "tsup --watch",
45
+ "build": "tsup",
46
+ "lint": "run-s lint:eslint lint:stylelint lint:prettier",
47
+ "lint:eslint": "eslint \"{src,examples}/**/*.{js,cjs,ts,tsx,vue}\" *.{js,cjs,ts} --fix --cache",
48
+ "lint:stylelint": "stylelint \"examples/**/*.{css,scss,less,vue,html}\" --fix --cache",
49
+ "lint:prettier": "prettier --write .",
50
+ "prepare": "husky install",
51
+ "prepublishOnly": "npm run build && np --any-branch --no-yarn --yolo --no-publish --message \"chore: release v%s\""
52
+ },
43
53
  "dependencies": {
44
54
  "dayjs": "^1.11.10",
45
55
  "kolorist": "^1.8.0",
@@ -58,7 +68,6 @@
58
68
  "@types/lodash.clonedeep": "^4.5.9",
59
69
  "@types/lodash.merge": "^4.6.9",
60
70
  "@types/node": "^18.19.3",
61
- "electron": "^28.0.0",
62
71
  "eslint": "^8.55.0",
63
72
  "husky": "^8.0.3",
64
73
  "lint-staged": "^15.2.0",
@@ -68,19 +77,16 @@
68
77
  "rimraf": "^5.0.5",
69
78
  "stylelint": "^15.11.0",
70
79
  "tsx": "^4.6.2",
71
- "typescript": "~5.2.2",
72
- "vite": "^5.0.7"
80
+ "typescript": "~5.2.2"
73
81
  },
74
82
  "peerDependencies": {
75
83
  "electron": ">=12.0.0",
76
- "vite": ">=2"
84
+ "electron-builder": ">=24.2.0",
85
+ "vite": ">=2.9.0"
77
86
  },
78
- "scripts": {
79
- "dev": "tsup --watch",
80
- "build": "tsup",
81
- "lint": "run-s lint:eslint lint:stylelint lint:prettier",
82
- "lint:eslint": "eslint \"{src,examples}/**/*.{js,cjs,ts,tsx,vue}\" *.{js,cjs,ts} --fix --cache",
83
- "lint:stylelint": "stylelint \"examples/**/*.{css,scss,less,vue,html}\" --fix --cache",
84
- "lint:prettier": "prettier --write ."
87
+ "peerDependenciesMeta": {
88
+ "electron-builder": {
89
+ "optional": true
90
+ }
85
91
  }
86
- }
92
+ }