@electron-forge/plugin-vite 8.0.0-alpha.7 → 8.0.0-alpha.9
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/dist/Config.d.ts +1 -1
- package/dist/ViteConfig.d.ts +1 -1
- package/dist/ViteConfig.d.ts.map +1 -1
- package/dist/ViteConfig.js +1 -1
- package/dist/VitePlugin.d.ts +2 -3
- package/dist/VitePlugin.d.ts.map +1 -1
- package/dist/VitePlugin.js +90 -129
- package/dist/config/vite.base.config.d.ts +2 -1
- package/dist/config/vite.base.config.d.ts.map +1 -1
- package/dist/config/vite.base.config.js +3 -3
- package/dist/config/vite.main.config.d.ts +1 -1
- package/dist/config/vite.main.config.js +1 -1
- package/dist/config/vite.preload.config.d.ts +1 -1
- package/dist/config/vite.preload.config.js +3 -3
- package/dist/config/vite.renderer.config.d.ts +1 -1
- package/dist/config/vite.renderer.config.js +1 -1
- package/dist/subprocess-worker.d.ts +1 -1
- package/dist/subprocess-worker.js +94 -8
- package/package.json +5 -6
- package/src/VitePlugin.ts +120 -150
- package/src/config/vite.base.config.ts +2 -2
- package/src/config/vite.preload.config.ts +2 -2
- package/src/subprocess-worker.ts +109 -7
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import { styleText } from 'node:util';
|
|
1
2
|
import { build } from 'vite';
|
|
3
|
+
import { viteDevServerUrls } from './config/vite.base.config.js';
|
|
2
4
|
import ViteConfigGenerator from './ViteConfig.js';
|
|
3
5
|
const projectDir = process.env.FORGE_VITE_PROJECT_DIR;
|
|
4
6
|
const kind = process.env.FORGE_VITE_KIND;
|
|
5
7
|
const index = Number(process.env.FORGE_VITE_INDEX);
|
|
6
8
|
const rawConfig = process.env.FORGE_VITE_CONFIG;
|
|
9
|
+
const watch = process.env.FORGE_VITE_WATCH === '1';
|
|
10
|
+
const rawDevServerUrls = process.env.FORGE_VITE_DEV_SERVER_URLS;
|
|
7
11
|
if (!projectDir || !kind || !rawConfig || !Number.isInteger(index)) {
|
|
8
12
|
console.error('subprocess-worker: missing one of FORGE_VITE_PROJECT_DIR, FORGE_VITE_KIND, FORGE_VITE_INDEX, FORGE_VITE_CONFIG');
|
|
9
13
|
process.exit(1);
|
|
@@ -12,7 +16,7 @@ if (!projectDir || !kind || !rawConfig || !Number.isInteger(index)) {
|
|
|
12
16
|
// getBuildDefine() reads forgeConfig.renderer to generate ${NAME}_VITE_NAME
|
|
13
17
|
// defines when building main targets.
|
|
14
18
|
const pluginConfig = JSON.parse(rawConfig);
|
|
15
|
-
const generator = new ViteConfigGenerator(pluginConfig, projectDir,
|
|
19
|
+
const generator = new ViteConfigGenerator(pluginConfig, projectDir, !watch);
|
|
16
20
|
let spec;
|
|
17
21
|
let target;
|
|
18
22
|
if (kind === 'build') {
|
|
@@ -23,11 +27,93 @@ else {
|
|
|
23
27
|
spec = pluginConfig.renderer[index];
|
|
24
28
|
target = 'renderer';
|
|
25
29
|
}
|
|
30
|
+
// Seed the module-level URL map so getBuildDefine() produces the same
|
|
31
|
+
// *_VITE_DEV_SERVER_URL defines the in-process path would have.
|
|
32
|
+
if (rawDevServerUrls) {
|
|
33
|
+
Object.assign(viteDevServerUrls, JSON.parse(rawDevServerUrls));
|
|
34
|
+
}
|
|
26
35
|
const resolved = await generator.resolveConfig(spec, target);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
if (!watch) {
|
|
37
|
+
await build({
|
|
38
|
+
configFile: false,
|
|
39
|
+
logLevel: 'error',
|
|
40
|
+
...resolved,
|
|
41
|
+
clearScreen: false,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Matches the format of the default Vite logger
|
|
46
|
+
const timeFormatter = new Intl.DateTimeFormat(undefined, {
|
|
47
|
+
hour: 'numeric',
|
|
48
|
+
minute: 'numeric',
|
|
49
|
+
second: 'numeric',
|
|
50
|
+
});
|
|
51
|
+
// Rollup's `input` can be a string, an array of strings, or an object.
|
|
52
|
+
// https://rollupjs.org/configuration-options/#input
|
|
53
|
+
const input = resolved.build?.rollupOptions?.input ??
|
|
54
|
+
(typeof resolved.build?.lib !== 'boolean'
|
|
55
|
+
? resolved.build?.lib?.entry
|
|
56
|
+
: undefined);
|
|
57
|
+
const targetDisplay = !input
|
|
58
|
+
? ''
|
|
59
|
+
: typeof input === 'string'
|
|
60
|
+
? input
|
|
61
|
+
: Array.isArray(input)
|
|
62
|
+
? input.join(' ')
|
|
63
|
+
: Object.keys(input).join(' ');
|
|
64
|
+
let firstBuildSent = false;
|
|
65
|
+
const sendOnce = (msg) => {
|
|
66
|
+
if (firstBuildSent)
|
|
67
|
+
return;
|
|
68
|
+
firstBuildSent = true;
|
|
69
|
+
process.send?.(msg);
|
|
70
|
+
};
|
|
71
|
+
const result = await build({
|
|
72
|
+
// Avoid recursive builds caused by users configuring @electron-forge/plugin-vite in Vite config file.
|
|
73
|
+
configFile: false,
|
|
74
|
+
// We suppress Vite output and instead log lines using RollupWatcher events
|
|
75
|
+
logLevel: 'silent',
|
|
76
|
+
...resolved,
|
|
77
|
+
plugins: [
|
|
78
|
+
// `buildEnd` and `closeBundle` are Rollup output generation hooks.
|
|
79
|
+
// https://rollupjs.org/plugin-development/#output-generation-hooks
|
|
80
|
+
{
|
|
81
|
+
name: '@electron-forge/plugin-vite:build-done',
|
|
82
|
+
buildEnd(err) {
|
|
83
|
+
if (err instanceof Error) {
|
|
84
|
+
sendOnce({ type: 'first-build-error', message: err.message });
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
closeBundle() {
|
|
88
|
+
sendOnce({ type: 'first-build-done' });
|
|
89
|
+
if (target === 'preload') {
|
|
90
|
+
// pluginHotRestart('reload') is a no-op here because viteDevServers
|
|
91
|
+
// lives in the parent; ask the parent to fan out the ws full-reload.
|
|
92
|
+
process.send?.({ type: 'reload-renderers' });
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
...(resolved.plugins ?? []),
|
|
97
|
+
],
|
|
98
|
+
clearScreen: false,
|
|
99
|
+
});
|
|
100
|
+
const isRollupWatcher = (x) => !!x &&
|
|
101
|
+
typeof x === 'object' &&
|
|
102
|
+
'on' in x &&
|
|
103
|
+
typeof x.on === 'function' &&
|
|
104
|
+
'close' in x &&
|
|
105
|
+
typeof x.close === 'function';
|
|
106
|
+
if (isRollupWatcher(result)) {
|
|
107
|
+
// The Rollup watcher emits events for subsequent builds.
|
|
108
|
+
result.on('event', (event) => {
|
|
109
|
+
if (event.code === 'ERROR' && resolved.logLevel !== 'silent') {
|
|
110
|
+
console.error(`\n${styleText('dim', timeFormatter.format(new Date()))} ${event.error.message}`);
|
|
111
|
+
}
|
|
112
|
+
else if (event.code === 'BUNDLE_END' &&
|
|
113
|
+
(!resolved.logLevel || resolved.logLevel === 'info')) {
|
|
114
|
+
console.log(`${styleText('dim', timeFormatter.format(new Date()))} ${styleText(['cyan', 'bold'], '[@electron-forge/plugin-vite]')} ${styleText('green', 'target built')} ${styleText('dim', targetDisplay)}`);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VicHJvY2Vzcy13b3JrZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvc3VicHJvY2Vzcy13b3JrZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUV0QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTdCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ2pFLE9BQU8sbUJBQW1CLE1BQU0saUJBQWlCLENBQUM7QUFTbEQsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQztBQUN0RCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQXVDLENBQUM7QUFDakUsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztBQUNuRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDO0FBQ2hELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEtBQUssR0FBRyxDQUFDO0FBQ25ELE1BQU0sZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsQ0FBQztBQUVoRSxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO0lBQ25FLE9BQU8sQ0FBQyxLQUFLLENBQ1gsZ0hBQWdILENBQ2pILENBQUM7SUFDRixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2xCLENBQUM7QUFFRCx5RUFBeUU7QUFDekUsNEVBQTRFO0FBQzVFLHNDQUFzQztBQUN0QyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxD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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@electron-forge/plugin-vite",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vite plugin for Electron Forge, lets you use Vite directly in your tooling",
|
|
6
6
|
"repository": {
|
|
@@ -18,15 +18,14 @@
|
|
|
18
18
|
"./forge-vite-env": "./forge-vite-env.d.ts"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@electron-forge/plugin-base": "8.0.0-alpha.
|
|
22
|
-
"@electron-forge/shared-types": "8.0.0-alpha.
|
|
23
|
-
"chalk": "^4.0.0",
|
|
21
|
+
"@electron-forge/plugin-base": "8.0.0-alpha.9",
|
|
22
|
+
"@electron-forge/shared-types": "8.0.0-alpha.9",
|
|
24
23
|
"debug": "^4.3.1",
|
|
25
24
|
"fs-extra": "^10.0.0",
|
|
26
25
|
"listr2": "^7.0.2"
|
|
27
26
|
},
|
|
28
27
|
"devDependencies": {
|
|
29
|
-
"@electron/packager": "^
|
|
28
|
+
"@electron/packager": "^20.0.0",
|
|
30
29
|
"@types/node": "^22.10.7",
|
|
31
30
|
"vite": "^8.0.0",
|
|
32
31
|
"vitest": "catalog:",
|
|
@@ -43,5 +42,5 @@
|
|
|
43
42
|
"src",
|
|
44
43
|
"forge-vite-env.d.ts"
|
|
45
44
|
],
|
|
46
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "8d048358c5e5f0b5a09e03740687aa7f0c63d027"
|
|
47
46
|
}
|
package/src/VitePlugin.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { styleText } from 'node:util';
|
|
3
4
|
|
|
4
5
|
import { namedHookWithTaskFn, PluginBase } from '@electron-forge/plugin-base';
|
|
5
|
-
import chalk from 'chalk';
|
|
6
6
|
import debug from 'debug';
|
|
7
7
|
import fs from 'fs-extra';
|
|
8
8
|
import { Listr, PRESET_TIMER } from 'listr2';
|
|
9
9
|
import * as vite from 'vite';
|
|
10
10
|
|
|
11
|
+
import { viteDevServerUrls } from './config/vite.base.config.js';
|
|
11
12
|
import ViteConfigGenerator from './ViteConfig.js';
|
|
12
13
|
|
|
13
14
|
import type { VitePluginConfig } from './Config.js';
|
|
@@ -16,6 +17,7 @@ import type {
|
|
|
16
17
|
ForgeMultiHookMap,
|
|
17
18
|
ResolvedForgeConfig,
|
|
18
19
|
} from '@electron-forge/shared-types';
|
|
20
|
+
import type { ChildProcess } from 'node:child_process';
|
|
19
21
|
import type { AddressInfo } from 'node:net';
|
|
20
22
|
import type { LibraryOptions } from 'vite';
|
|
21
23
|
|
|
@@ -76,6 +78,72 @@ function spawnViteBuild(
|
|
|
76
78
|
});
|
|
77
79
|
}
|
|
78
80
|
|
|
81
|
+
function spawnViteBuildWatch(
|
|
82
|
+
pluginConfig: Pick<VitePluginConfig, 'build' | 'renderer'>,
|
|
83
|
+
index: number,
|
|
84
|
+
projectDir: string,
|
|
85
|
+
devServerUrls: Record<string, string>,
|
|
86
|
+
onReloadRenderers: () => void,
|
|
87
|
+
): { child: ChildProcess; firstBuild: Promise<void> } {
|
|
88
|
+
const child = spawn(process.execPath, [subprocessWorkerPath], {
|
|
89
|
+
cwd: projectDir,
|
|
90
|
+
env: {
|
|
91
|
+
...process.env,
|
|
92
|
+
FORGE_VITE_PROJECT_DIR: projectDir,
|
|
93
|
+
FORGE_VITE_KIND: 'build',
|
|
94
|
+
FORGE_VITE_INDEX: String(index),
|
|
95
|
+
FORGE_VITE_CONFIG: JSON.stringify(pluginConfig),
|
|
96
|
+
FORGE_VITE_WATCH: '1',
|
|
97
|
+
FORGE_VITE_DEV_SERVER_URLS: JSON.stringify(devServerUrls),
|
|
98
|
+
},
|
|
99
|
+
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
let settled = false;
|
|
103
|
+
let stderr = '';
|
|
104
|
+
child.stderr!.setEncoding('utf8');
|
|
105
|
+
child.stderr!.on('data', (chunk) => {
|
|
106
|
+
if (!settled) stderr += chunk;
|
|
107
|
+
process.stderr.write(chunk);
|
|
108
|
+
});
|
|
109
|
+
child.stdout!.setEncoding('utf8');
|
|
110
|
+
child.stdout!.on('data', (chunk) => process.stdout.write(chunk));
|
|
111
|
+
|
|
112
|
+
const firstBuild = new Promise<void>((resolve, reject) => {
|
|
113
|
+
const settle = (fn: () => void) => {
|
|
114
|
+
if (settled) return;
|
|
115
|
+
settled = true;
|
|
116
|
+
stderr = '';
|
|
117
|
+
fn();
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
child.on('message', (msg: { type: string; message?: string }) => {
|
|
121
|
+
if (msg.type === 'first-build-done') {
|
|
122
|
+
settle(resolve);
|
|
123
|
+
} else if (msg.type === 'first-build-error') {
|
|
124
|
+
settle(() => reject(new Error(msg.message)));
|
|
125
|
+
} else if (msg.type === 'reload-renderers') {
|
|
126
|
+
onReloadRenderers();
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
child.on('error', (err) => settle(() => reject(err)));
|
|
130
|
+
child.on('close', (code, signal) => {
|
|
131
|
+
const reason = signal
|
|
132
|
+
? `killed by signal ${signal}`
|
|
133
|
+
: `exited with code ${code}`;
|
|
134
|
+
settle(() =>
|
|
135
|
+
reject(
|
|
136
|
+
new Error(
|
|
137
|
+
`Vite watch subprocess ${reason} before first build completed${stderr ? `:\n${stderr}` : ''}`,
|
|
138
|
+
),
|
|
139
|
+
),
|
|
140
|
+
);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
return { child, firstBuild };
|
|
145
|
+
}
|
|
146
|
+
|
|
79
147
|
function entryToDisplay(entry: LibraryOptions['entry']): string {
|
|
80
148
|
if (typeof entry === 'string') return entry;
|
|
81
149
|
if (Array.isArray(entry)) return entry.join(' ');
|
|
@@ -101,17 +169,10 @@ export default class VitePlugin extends PluginBase<VitePluginConfig> {
|
|
|
101
169
|
|
|
102
170
|
private configGeneratorCache!: ViteConfigGenerator;
|
|
103
171
|
|
|
104
|
-
private
|
|
172
|
+
private watchChildren: ChildProcess[] = [];
|
|
105
173
|
|
|
106
174
|
private servers: vite.ViteDevServer[] = [];
|
|
107
175
|
|
|
108
|
-
// Matches the format of the default Vite logger
|
|
109
|
-
private timeFormatter = new Intl.DateTimeFormat(undefined, {
|
|
110
|
-
hour: 'numeric',
|
|
111
|
-
minute: 'numeric',
|
|
112
|
-
second: 'numeric',
|
|
113
|
-
});
|
|
114
|
-
|
|
115
176
|
init = (dir: string): void => {
|
|
116
177
|
this.setDirectories(dir);
|
|
117
178
|
|
|
@@ -227,9 +288,12 @@ export default class VitePlugin extends PluginBase<VitePluginConfig> {
|
|
|
227
288
|
if (forgeConfig.packagerConfig.ignore) {
|
|
228
289
|
if (typeof forgeConfig.packagerConfig.ignore !== 'function') {
|
|
229
290
|
console.error(
|
|
230
|
-
|
|
291
|
+
styleText(
|
|
292
|
+
'yellow',
|
|
293
|
+
`You have set packagerConfig.ignore, the Electron Forge Vite plugin normally sets this automatically.
|
|
231
294
|
|
|
232
|
-
Your packaged app may be larger than expected if you dont ignore everything other than the '.vite' folder
|
|
295
|
+
Your packaged app may be larger than expected if you dont ignore everything other than the '.vite' folder`,
|
|
296
|
+
),
|
|
233
297
|
);
|
|
234
298
|
}
|
|
235
299
|
return forgeConfig;
|
|
@@ -285,13 +349,14 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}.`);
|
|
|
285
349
|
|
|
286
350
|
// Main process, Preload scripts and Worker process, etc.
|
|
287
351
|
build = async (task?: ForgeListrTask<null>): Promise<Listr | void> => {
|
|
352
|
+
const targets = this.config.build
|
|
353
|
+
.map((spec, index) => ({ spec, index }))
|
|
354
|
+
.filter(({ spec }) => spec.config);
|
|
355
|
+
|
|
288
356
|
if (this.isProd) {
|
|
289
|
-
const targets = this.config.build
|
|
290
|
-
.map((spec, index) => ({ spec, index }))
|
|
291
|
-
.filter(({ spec }) => spec.config);
|
|
292
357
|
return task?.newListr(
|
|
293
358
|
targets.map(({ spec, index }) => ({
|
|
294
|
-
title: `Building ${
|
|
359
|
+
title: `Building ${styleText('green', entryToDisplay(spec.entry))}`,
|
|
295
360
|
task: async (_ctx, subtask) => {
|
|
296
361
|
await spawnViteBuild(
|
|
297
362
|
this.serializableConfig,
|
|
@@ -299,7 +364,7 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}.`);
|
|
|
299
364
|
index,
|
|
300
365
|
this.projectDir,
|
|
301
366
|
);
|
|
302
|
-
subtask.title = `Built target ${
|
|
367
|
+
subtask.title = `Built target ${styleText('dim', entryToDisplay(spec.entry))}`;
|
|
303
368
|
},
|
|
304
369
|
})),
|
|
305
370
|
{
|
|
@@ -309,129 +374,28 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}.`);
|
|
|
309
374
|
);
|
|
310
375
|
}
|
|
311
376
|
|
|
312
|
-
const configs = await this.configGenerator.getBuildConfigs();
|
|
313
|
-
/**
|
|
314
|
-
* Checks if the result of the Vite build is a Rollup watcher.
|
|
315
|
-
* This should happen iff we're running `electron-forge start`.
|
|
316
|
-
*/
|
|
317
|
-
const isRollupWatcher = (
|
|
318
|
-
x:
|
|
319
|
-
| vite.Rollup.RollupWatcher
|
|
320
|
-
| vite.Rollup.RollupOutput
|
|
321
|
-
| vite.Rollup.RollupOutput[],
|
|
322
|
-
): x is vite.Rollup.RollupWatcher =>
|
|
323
|
-
x &&
|
|
324
|
-
typeof x === 'object' &&
|
|
325
|
-
'on' in x &&
|
|
326
|
-
typeof x.on === 'function' &&
|
|
327
|
-
'close' in x &&
|
|
328
|
-
typeof x.close === 'function';
|
|
329
|
-
|
|
330
|
-
/**
|
|
331
|
-
* Rollup's `input` can be a string, an array of strings, or an object.
|
|
332
|
-
* This function converts the input to a string for the Forge CLI to consume.
|
|
333
|
-
*
|
|
334
|
-
* @see https://rollupjs.org/configuration-options/#input
|
|
335
|
-
*/
|
|
336
|
-
const parseInputOptionToString = (input: vite.Rollup.InputOption) => {
|
|
337
|
-
if (typeof input === 'string') {
|
|
338
|
-
return input;
|
|
339
|
-
} else if (Array.isArray(input)) {
|
|
340
|
-
return input.join(' ');
|
|
341
|
-
} else {
|
|
342
|
-
return Object.keys(input).join(' ');
|
|
343
|
-
}
|
|
344
|
-
};
|
|
345
|
-
|
|
346
377
|
return task?.newListr(
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
await new Promise<void>((resolve, reject) => {
|
|
366
|
-
vite
|
|
367
|
-
.build({
|
|
368
|
-
// Avoid recursive builds caused by users configuring @electron-forge/plugin-vite in Vite config file.
|
|
369
|
-
configFile: false,
|
|
370
|
-
// We suppress Vite output and instead log lines using RollupWatcher events
|
|
371
|
-
logLevel: 'silent',
|
|
372
|
-
...userConfig,
|
|
373
|
-
plugins: [
|
|
374
|
-
// This plugin controls the output of the first-time Vite build that happens.
|
|
375
|
-
// `buildEnd` and `closeBundle` are Rollup output generation hooks.
|
|
376
|
-
// See https://rollupjs.org/plugin-development/#output-generation-hooks
|
|
377
|
-
{
|
|
378
|
-
name: '@electron-forge/plugin-vite:build-done',
|
|
379
|
-
buildEnd(err) {
|
|
380
|
-
if (err instanceof Error) {
|
|
381
|
-
d(
|
|
382
|
-
'buildEnd rollup hook called with error so build failed',
|
|
383
|
-
);
|
|
384
|
-
reject(err);
|
|
385
|
-
}
|
|
386
|
-
},
|
|
387
|
-
closeBundle() {
|
|
388
|
-
d(
|
|
389
|
-
'no error in buildEnd and reached closeBundle so build succeeded',
|
|
390
|
-
);
|
|
391
|
-
resolve();
|
|
392
|
-
},
|
|
393
|
-
},
|
|
394
|
-
...(userConfig.plugins ?? []),
|
|
395
|
-
],
|
|
396
|
-
clearScreen: false,
|
|
397
|
-
})
|
|
398
|
-
.then((result) => {
|
|
399
|
-
// When running `start` and enabling watch mode in Vite, the Rollup watcher
|
|
400
|
-
// emits events for subsequent builds.
|
|
401
|
-
if (isRollupWatcher(result)) {
|
|
402
|
-
result.on('event', (event) => {
|
|
403
|
-
if (
|
|
404
|
-
event.code === 'ERROR' &&
|
|
405
|
-
userConfig.logLevel !== 'silent'
|
|
406
|
-
) {
|
|
407
|
-
console.error(
|
|
408
|
-
`\n${chalk.dim(this.timeFormatter.format(new Date()))} ${event.error.message}`,
|
|
409
|
-
);
|
|
410
|
-
} else if (
|
|
411
|
-
event.code === 'BUNDLE_END' &&
|
|
412
|
-
(!userConfig.logLevel || userConfig.logLevel === 'info')
|
|
413
|
-
) {
|
|
414
|
-
console.log(
|
|
415
|
-
`${chalk.dim(this.timeFormatter.format(new Date()))} ${chalk.cyan.bold('[@electron-forge/plugin-vite]')} ${chalk.green(
|
|
416
|
-
'target built',
|
|
417
|
-
)} ${chalk.dim(target)}`,
|
|
418
|
-
);
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
this.watchers.push(result);
|
|
422
|
-
} else {
|
|
423
|
-
subtask.title = `Built target ${chalk.dim(target)}`;
|
|
424
|
-
}
|
|
425
|
-
return result;
|
|
426
|
-
})
|
|
427
|
-
.catch(reject);
|
|
428
|
-
});
|
|
429
|
-
},
|
|
430
|
-
};
|
|
431
|
-
}),
|
|
378
|
+
targets.map(({ spec, index }) => ({
|
|
379
|
+
title: `Building ${styleText('green', entryToDisplay(spec.entry))} target`,
|
|
380
|
+
task: async () => {
|
|
381
|
+
const { child, firstBuild } = spawnViteBuildWatch(
|
|
382
|
+
this.serializableConfig,
|
|
383
|
+
index,
|
|
384
|
+
this.projectDir,
|
|
385
|
+
viteDevServerUrls,
|
|
386
|
+
() => {
|
|
387
|
+
for (const server of this.servers) {
|
|
388
|
+
server.ws.send({ type: 'full-reload' });
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
);
|
|
392
|
+
this.watchChildren.push(child);
|
|
393
|
+
await firstBuild;
|
|
394
|
+
},
|
|
395
|
+
})),
|
|
432
396
|
{
|
|
433
397
|
concurrent: this.config.concurrent ?? true,
|
|
434
|
-
exitOnError:
|
|
398
|
+
exitOnError: false,
|
|
435
399
|
},
|
|
436
400
|
);
|
|
437
401
|
};
|
|
@@ -444,7 +408,7 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}.`);
|
|
|
444
408
|
.filter(({ spec }) => spec.config);
|
|
445
409
|
return task?.newListr(
|
|
446
410
|
targets.map(({ spec, index }) => ({
|
|
447
|
-
title: `Building ${
|
|
411
|
+
title: `Building ${styleText('green', spec.name)}`,
|
|
448
412
|
task: async (_ctx, subtask) => {
|
|
449
413
|
await spawnViteBuild(
|
|
450
414
|
this.serializableConfig,
|
|
@@ -452,7 +416,7 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}.`);
|
|
|
452
416
|
index,
|
|
453
417
|
this.projectDir,
|
|
454
418
|
);
|
|
455
|
-
subtask.title = `Built target ${
|
|
419
|
+
subtask.title = `Built target ${styleText('dim', spec.name)}`;
|
|
456
420
|
},
|
|
457
421
|
})),
|
|
458
422
|
{
|
|
@@ -471,7 +435,7 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}.`);
|
|
|
471
435
|
logLevel: 'error',
|
|
472
436
|
...userConfig,
|
|
473
437
|
});
|
|
474
|
-
subtask.title = `Built target ${
|
|
438
|
+
subtask.title = `Built target ${styleText('dim', path.basename(userConfig.build?.outDir ?? ''))}`;
|
|
475
439
|
},
|
|
476
440
|
})),
|
|
477
441
|
{
|
|
@@ -484,7 +448,7 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}.`);
|
|
|
484
448
|
const rendererConfigs = await this.configGenerator.getRendererConfig();
|
|
485
449
|
return task?.newListr(
|
|
486
450
|
rendererConfigs.map((userConfig) => ({
|
|
487
|
-
title: `Target ${
|
|
451
|
+
title: `Target ${styleText('cyan', path.basename(userConfig.build?.outDir ?? ''))}`,
|
|
488
452
|
task: async (_ctx, subtask) => {
|
|
489
453
|
const viteDevServer = await vite.createServer({
|
|
490
454
|
configFile: false,
|
|
@@ -524,11 +488,11 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}.`);
|
|
|
524
488
|
): void => {
|
|
525
489
|
d('handling process exit with:', options);
|
|
526
490
|
if (options.cleanup) {
|
|
527
|
-
for (const
|
|
528
|
-
d('
|
|
529
|
-
|
|
491
|
+
for (const child of this.watchChildren) {
|
|
492
|
+
d('killing vite watch subprocess');
|
|
493
|
+
child.kill();
|
|
530
494
|
}
|
|
531
|
-
this.
|
|
495
|
+
this.watchChildren = [];
|
|
532
496
|
|
|
533
497
|
for (const server of this.servers) {
|
|
534
498
|
d('cleaning http server');
|
|
@@ -549,18 +513,24 @@ the generated files). Instead, it is ${JSON.stringify(pj.main)}.`);
|
|
|
549
513
|
function getServerURLs(urls: vite.ResolvedServerUrls) {
|
|
550
514
|
let output = '';
|
|
551
515
|
const colorUrl = (url: string) =>
|
|
552
|
-
|
|
516
|
+
styleText(
|
|
517
|
+
'cyan',
|
|
518
|
+
url.replace(/:(\d+)\//, (_, port) => `:${styleText('bold', port)}/`),
|
|
519
|
+
);
|
|
553
520
|
for (const url of urls.local) {
|
|
554
|
-
output += ` ${
|
|
521
|
+
output += ` ${styleText('green', '➜')} ${styleText('bold', 'Local')}: ${colorUrl(url)}`;
|
|
555
522
|
}
|
|
556
523
|
for (const url of urls.network) {
|
|
557
|
-
output += ` \n${
|
|
524
|
+
output += ` \n${styleText('green', '➜')} ${styleText('bold', 'Network')}: ${colorUrl(url)}`;
|
|
558
525
|
}
|
|
559
526
|
if (urls.network.length === 0) {
|
|
560
527
|
output +=
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
528
|
+
styleText(
|
|
529
|
+
'dim',
|
|
530
|
+
` \n${styleText('green', '➜')} ${styleText('bold', 'Network')}: use `,
|
|
531
|
+
) +
|
|
532
|
+
styleText('bold', '--host') +
|
|
533
|
+
styleText('dim', ' to expose');
|
|
564
534
|
}
|
|
565
535
|
|
|
566
536
|
return output;
|
|
@@ -11,7 +11,7 @@ export const external = [
|
|
|
11
11
|
|
|
12
12
|
// Used for hot reload after preload scripts.
|
|
13
13
|
const viteDevServers: Record<string, ViteDevServer> = {};
|
|
14
|
-
const viteDevServerUrls: Record<string, string> = {};
|
|
14
|
+
export const viteDevServerUrls: Record<string, string> = {};
|
|
15
15
|
|
|
16
16
|
export function getBuildConfig(env: ConfigEnv<'build'>): UserConfig {
|
|
17
17
|
const { root, mode, command } = env;
|
|
@@ -24,7 +24,7 @@ export function getBuildConfig(env: ConfigEnv<'build'>): UserConfig {
|
|
|
24
24
|
emptyOutDir: false,
|
|
25
25
|
// 🚧 Multiple builds may conflict.
|
|
26
26
|
outDir: '.vite/build',
|
|
27
|
-
watch: command === 'serve' ? {} : null,
|
|
27
|
+
watch: command === 'serve' ? { exclude: '**/.git/**' } : null,
|
|
28
28
|
minify: command === 'build',
|
|
29
29
|
},
|
|
30
30
|
clearScreen: false,
|
|
@@ -20,8 +20,8 @@ export function getConfig(
|
|
|
20
20
|
input: forgeConfigSelf.entry,
|
|
21
21
|
output: {
|
|
22
22
|
format: 'cjs',
|
|
23
|
-
//
|
|
24
|
-
|
|
23
|
+
// Preload scripts require a single entrypoint.
|
|
24
|
+
codeSplitting: false,
|
|
25
25
|
entryFileNames: '[name].js',
|
|
26
26
|
chunkFileNames: '[name].js',
|
|
27
27
|
assetFileNames: '[name].[ext]',
|