@dromon/electron-vite 5.0.0

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.
@@ -0,0 +1,1751 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import colors from 'picocolors';
4
+ import { loadEnv as loadEnv$1, mergeConfig, normalizePath, build, loadConfigFromFile as loadConfigFromFile$1, createLogger } from 'vite';
5
+ import { createRequire, builtinModules } from 'node:module';
6
+ import { spawn } from 'node:child_process';
7
+ import { createHash } from 'node:crypto';
8
+ import fs$1 from 'node:fs/promises';
9
+ import MagicString from 'magic-string';
10
+ import * as babel from '@babel/core';
11
+
12
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-function-type */
13
+ function isObject(value) {
14
+ return Object.prototype.toString.call(value) === '[object Object]';
15
+ }
16
+ const wildcardHosts = new Set(['0.0.0.0', '::', '0000:0000:0000:0000:0000:0000:0000:0000']);
17
+ function resolveHostname(optionsHost) {
18
+ return typeof optionsHost === 'string' && !wildcardHosts.has(optionsHost) ? optionsHost : 'localhost';
19
+ }
20
+ const queryRE = /\?.*$/s;
21
+ const hashRE = /#.*$/s;
22
+ const cleanUrl = (url) => url.replace(hashRE, '').replace(queryRE, '');
23
+ function getHash(text) {
24
+ return createHash('sha256')
25
+ .update(text)
26
+ .digest('hex')
27
+ .substring(0, 8);
28
+ }
29
+ function toRelativePath(filename, importer) {
30
+ const relPath = path.posix.relative(path.dirname(importer), filename);
31
+ return relPath.startsWith('.') ? relPath : `./${relPath}`;
32
+ }
33
+ /**
34
+ * Load `.env` files within the `envDir` (default: `process.cwd()`) .
35
+ * By default, only env variables prefixed with `VITE_`, `MAIN_VITE_`, `PRELOAD_VITE_` and
36
+ * `RENDERER_VITE_` are loaded, unless `prefixes` is changed.
37
+ */
38
+ function loadEnv(mode, envDir = process.cwd(), prefixes = ['VITE_', 'MAIN_VITE_', 'PRELOAD_VITE_', 'RENDERER_VITE_']) {
39
+ return loadEnv$1(mode, envDir, prefixes);
40
+ }
41
+ let packageCached = null;
42
+ function loadPackageData(root = process.cwd()) {
43
+ if (packageCached)
44
+ return packageCached;
45
+ const pkg = path.join(root, 'package.json');
46
+ if (fs.existsSync(pkg)) {
47
+ const _require = createRequire(import.meta.url);
48
+ const data = _require(pkg);
49
+ packageCached = {
50
+ main: data.main,
51
+ type: data.type,
52
+ dependencies: data.dependencies
53
+ };
54
+ return packageCached;
55
+ }
56
+ return null;
57
+ }
58
+ function deepClone(value) {
59
+ if (Array.isArray(value)) {
60
+ return value.map(v => deepClone(v));
61
+ }
62
+ if (isObject(value)) {
63
+ const cloned = {};
64
+ for (const key in value) {
65
+ cloned[key] = deepClone(value[key]);
66
+ }
67
+ return cloned;
68
+ }
69
+ if (typeof value === 'function') {
70
+ return value;
71
+ }
72
+ if (value instanceof RegExp) {
73
+ return new RegExp(value);
74
+ }
75
+ if (typeof value === 'object' && value != null) {
76
+ throw new Error('Cannot deep clone non-plain object');
77
+ }
78
+ return value;
79
+ }
80
+ async function asyncFlatten(arr) {
81
+ do {
82
+ arr = (await Promise.all(arr)).flat(Infinity);
83
+ } while (arr.some((v) => v?.then));
84
+ return arr;
85
+ }
86
+
87
+ const _require$1 = createRequire(import.meta.url);
88
+ const ensureElectronEntryFile = (root = process.cwd()) => {
89
+ if (process.env.ELECTRON_ENTRY)
90
+ return;
91
+ const pkg = loadPackageData();
92
+ if (pkg) {
93
+ if (!pkg.main) {
94
+ throw new Error('No entry point found for electron app, please add a "main" field to package.json');
95
+ }
96
+ else {
97
+ const entryPath = path.resolve(root, pkg.main);
98
+ if (!fs.existsSync(entryPath)) {
99
+ throw new Error(`No electron app entry file found: ${entryPath}`);
100
+ }
101
+ }
102
+ }
103
+ else {
104
+ throw new Error('Not found: package.json');
105
+ }
106
+ };
107
+ const getElectronMajorVer = () => {
108
+ let majorVer = process.env.ELECTRON_MAJOR_VER || '';
109
+ if (!majorVer) {
110
+ const pkg = _require$1.resolve('electron/package.json');
111
+ if (fs.existsSync(pkg)) {
112
+ const version = _require$1(pkg).version;
113
+ majorVer = version.split('.')[0];
114
+ process.env.ELECTRON_MAJOR_VER = majorVer;
115
+ }
116
+ }
117
+ return majorVer;
118
+ };
119
+ function supportESM() {
120
+ const majorVer = getElectronMajorVer();
121
+ return parseInt(majorVer) >= 28;
122
+ }
123
+ function supportImportMetaPaths() {
124
+ const majorVer = getElectronMajorVer();
125
+ return parseInt(majorVer) >= 30;
126
+ }
127
+ function getElectronPath() {
128
+ let electronExecPath = process.env.ELECTRON_EXEC_PATH || '';
129
+ if (!electronExecPath) {
130
+ const electronModulePath = path.dirname(_require$1.resolve('electron'));
131
+ const pathFile = path.join(electronModulePath, 'path.txt');
132
+ let executablePath;
133
+ if (fs.existsSync(pathFile)) {
134
+ executablePath = fs.readFileSync(pathFile, 'utf-8');
135
+ }
136
+ if (executablePath) {
137
+ electronExecPath = path.join(electronModulePath, 'dist', executablePath);
138
+ process.env.ELECTRON_EXEC_PATH = electronExecPath;
139
+ }
140
+ else {
141
+ throw new Error('Electron uninstall');
142
+ }
143
+ }
144
+ return electronExecPath;
145
+ }
146
+ function getElectronNodeTarget() {
147
+ const electronVer = getElectronMajorVer();
148
+ const nodeVer = {
149
+ '41': '24.14',
150
+ '40': '24.14',
151
+ '39': '22.20',
152
+ '38': '22.19',
153
+ '37': '22.16',
154
+ '36': '22.14',
155
+ '35': '22.14',
156
+ '34': '20.18',
157
+ '33': '20.18',
158
+ '32': '20.16',
159
+ '31': '20.14',
160
+ '30': '20.11',
161
+ '29': '20.9',
162
+ '28': '18.18',
163
+ '27': '18.17',
164
+ '26': '18.16',
165
+ '25': '18.15',
166
+ '24': '18.14',
167
+ '23': '18.12',
168
+ '22': '16.17'
169
+ };
170
+ if (electronVer && parseInt(electronVer) > 10) {
171
+ let target = nodeVer[electronVer];
172
+ if (!target)
173
+ target = Object.values(nodeVer).reverse()[0];
174
+ return 'node' + target;
175
+ }
176
+ return '';
177
+ }
178
+ function getElectronChromeTarget() {
179
+ const electronVer = getElectronMajorVer();
180
+ const chromeVer = {
181
+ '41': '146',
182
+ '40': '144',
183
+ '39': '142',
184
+ '38': '140',
185
+ '37': '138',
186
+ '36': '136',
187
+ '35': '134',
188
+ '34': '132',
189
+ '33': '130',
190
+ '32': '128',
191
+ '31': '126',
192
+ '30': '124',
193
+ '29': '122',
194
+ '28': '120',
195
+ '27': '118',
196
+ '26': '116',
197
+ '25': '114',
198
+ '24': '112',
199
+ '23': '110',
200
+ '22': '108'
201
+ };
202
+ if (electronVer && parseInt(electronVer) > 10) {
203
+ let target = chromeVer[electronVer];
204
+ if (!target)
205
+ target = Object.values(chromeVer).reverse()[0];
206
+ return 'chrome' + target;
207
+ }
208
+ return '';
209
+ }
210
+ function startElectron(root) {
211
+ ensureElectronEntryFile(root);
212
+ const electronPath = getElectronPath();
213
+ const isDev = process.env.NODE_ENV_ELECTRON_VITE === 'development';
214
+ const args = process.env.ELECTRON_CLI_ARGS ? JSON.parse(process.env.ELECTRON_CLI_ARGS) : [];
215
+ if (!!process.env.REMOTE_DEBUGGING_PORT && isDev) {
216
+ args.push(`--remote-debugging-port=${process.env.REMOTE_DEBUGGING_PORT}`);
217
+ }
218
+ if (!!process.env.V8_INSPECTOR_PORT && isDev) {
219
+ args.push(`--inspect=${process.env.V8_INSPECTOR_PORT}`);
220
+ }
221
+ if (!!process.env.V8_INSPECTOR_BRK_PORT && isDev) {
222
+ args.push(`--inspect-brk=${process.env.V8_INSPECTOR_BRK_PORT}`);
223
+ }
224
+ if (process.env.NO_SANDBOX === '1') {
225
+ args.push('--no-sandbox');
226
+ }
227
+ const entry = process.env.ELECTRON_ENTRY || '.';
228
+ const ps = spawn(electronPath, [entry].concat(args), { stdio: 'inherit' });
229
+ ps.on('close', process.exit);
230
+ return ps;
231
+ }
232
+
233
+ /* eslint-disable @typescript-eslint/no-explicit-any */
234
+ function findLibEntry(root, scope) {
235
+ for (const name of ['index', scope]) {
236
+ for (const ext of ['js', 'ts', 'mjs', 'cjs']) {
237
+ const entryFile = path.resolve(root, 'src', scope, `${name}.${ext}`);
238
+ if (fs.existsSync(entryFile)) {
239
+ return entryFile;
240
+ }
241
+ }
242
+ }
243
+ return undefined;
244
+ }
245
+ function findInput(root, scope = 'renderer') {
246
+ const rendererDir = path.resolve(root, 'src', scope, 'index.html');
247
+ if (fs.existsSync(rendererDir)) {
248
+ return rendererDir;
249
+ }
250
+ return '';
251
+ }
252
+ function processEnvDefine() {
253
+ return {
254
+ 'process.env': `process.env`,
255
+ 'global.process.env': `global.process.env`,
256
+ 'globalThis.process.env': `globalThis.process.env`
257
+ };
258
+ }
259
+ function resolveBuildOutputs$1(outputs, libOptions) {
260
+ if (libOptions && !Array.isArray(outputs)) {
261
+ const libFormats = libOptions.formats || [];
262
+ return libFormats.map(format => ({ ...outputs, format }));
263
+ }
264
+ return outputs;
265
+ }
266
+ function electronMainConfigPresetPlugin(options) {
267
+ return {
268
+ name: 'vite:electron-main-config-preset',
269
+ apply: 'build',
270
+ enforce: 'pre',
271
+ config(config) {
272
+ const root = options?.root || process.cwd();
273
+ const nodeTarget = getElectronNodeTarget();
274
+ const pkg = loadPackageData() || { type: 'commonjs' };
275
+ const format = pkg.type && pkg.type === 'module' && supportESM() ? 'es' : 'cjs';
276
+ const defaultConfig = {
277
+ resolve: {
278
+ browserField: false,
279
+ mainFields: ['module', 'jsnext:main', 'jsnext'],
280
+ conditions: ['node']
281
+ },
282
+ build: {
283
+ outDir: path.resolve(root, 'out', 'main'),
284
+ target: nodeTarget,
285
+ assetsDir: 'chunks',
286
+ rollupOptions: {
287
+ external: ['electron', /^electron\/.+/, ...builtinModules.flatMap(m => [m, `node:${m}`])],
288
+ output: {}
289
+ },
290
+ reportCompressedSize: false,
291
+ minify: false
292
+ }
293
+ };
294
+ const build = config.build || {};
295
+ const rollupOptions = build.rollupOptions || {};
296
+ if (!rollupOptions.input) {
297
+ const libOptions = build.lib;
298
+ const outputOptions = rollupOptions.output;
299
+ defaultConfig.build['lib'] = {
300
+ entry: findLibEntry(root, 'main'),
301
+ formats: libOptions && libOptions.formats && libOptions.formats.length > 0
302
+ ? []
303
+ : [outputOptions && !Array.isArray(outputOptions) && outputOptions.format ? outputOptions.format : format]
304
+ };
305
+ }
306
+ else {
307
+ defaultConfig.build.rollupOptions.output['format'] = format;
308
+ }
309
+ defaultConfig.build.rollupOptions.output['assetFileNames'] = path.posix.join(build.assetsDir || defaultConfig.build.assetsDir, '[name]-[hash].[ext]');
310
+ const buildConfig = mergeConfig(defaultConfig.build, build);
311
+ if (buildConfig.rollupOptions && !buildConfig.rolldownOptions) {
312
+ buildConfig.rolldownOptions = buildConfig.rollupOptions;
313
+ }
314
+ else if (buildConfig.rollupOptions && buildConfig.rolldownOptions) {
315
+ Object.assign(buildConfig.rolldownOptions, buildConfig.rollupOptions);
316
+ }
317
+ config.build = buildConfig;
318
+ const resolvedOutputs = resolveBuildOutputs$1(config.build.rollupOptions.output, config.build.lib || false);
319
+ if (resolvedOutputs) {
320
+ const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs];
321
+ outputs.forEach(output => {
322
+ if (output.format === 'es') {
323
+ output['entryFileNames'] = '[name].mjs';
324
+ output['chunkFileNames'] = '[name]-[hash].mjs';
325
+ }
326
+ else if (output.format === 'cjs') {
327
+ output['entryFileNames'] = '[name].js';
328
+ output['chunkFileNames'] = '[name]-[hash].js';
329
+ }
330
+ });
331
+ if (Array.isArray(config.build.rollupOptions.output)) ;
332
+ else {
333
+ if (outputs[0].format === 'es' || outputs[0].format === 'cjs') {
334
+ config.build.rollupOptions.output['entryFileNames'] = outputs[0]['entryFileNames'];
335
+ config.build.rollupOptions.output['chunkFileNames'] = outputs[0]['chunkFileNames'];
336
+ }
337
+ }
338
+ }
339
+ config.resolve = mergeConfig(defaultConfig.resolve, config.resolve || {});
340
+ config.define = config.define || {};
341
+ config.define = { ...processEnvDefine(), ...config.define };
342
+ config.envPrefix = config.envPrefix || ['MAIN_VITE_', 'VITE_'];
343
+ config.publicDir = config.publicDir || 'resources';
344
+ // do not copy public dir
345
+ config.build.copyPublicDir = false;
346
+ // module preload polyfill does not apply to nodejs (main process)
347
+ config.build.modulePreload = false;
348
+ // enable ssr build
349
+ config.build.ssr = true;
350
+ config.build.ssrEmitAssets = true;
351
+ config.ssr = { ...config.ssr, ...{ noExternal: /^(?!(electron|electron\/.+)).*/ } };
352
+ }
353
+ };
354
+ }
355
+ function electronMainConfigValidatorPlugin() {
356
+ return {
357
+ name: 'vite:electron-main-config-validator',
358
+ apply: 'build',
359
+ enforce: 'post',
360
+ configResolved(config) {
361
+ const build = config.build;
362
+ if (!build.target) {
363
+ throw new Error('build.target option is required in the electron vite main config.');
364
+ }
365
+ else {
366
+ const targets = Array.isArray(build.target) ? build.target : [build.target];
367
+ if (targets.some(t => !t.startsWith('node'))) {
368
+ throw new Error('The electron vite main config build.target option must be "node?".');
369
+ }
370
+ }
371
+ const libOptions = build.lib;
372
+ const rollupOptions = build.rollupOptions;
373
+ if (!(libOptions && libOptions.entry) && !rollupOptions?.input) {
374
+ throw new Error('An entry point is required in the electron vite main config, ' +
375
+ 'which can be specified using "build.lib.entry" or "build.rollupOptions.input".');
376
+ }
377
+ const resolvedOutputs = resolveBuildOutputs$1(rollupOptions.output, libOptions);
378
+ if (resolvedOutputs) {
379
+ const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs];
380
+ if (outputs.length > 1) {
381
+ throw new Error('The electron vite main config does not support multiple outputs.');
382
+ }
383
+ else {
384
+ const outpout = outputs[0];
385
+ if (['es', 'cjs'].includes(outpout.format || '')) {
386
+ if (outpout.format === 'es' && !supportESM()) {
387
+ throw new Error('The electron vite main config output format does not support "es", ' +
388
+ 'you can upgrade electron to the latest version or switch to "cjs" format.');
389
+ }
390
+ }
391
+ else {
392
+ throw new Error(`The electron vite main config output format must be "cjs"${supportESM() ? ' or "es"' : ''}.`);
393
+ }
394
+ }
395
+ }
396
+ }
397
+ };
398
+ }
399
+ function electronPreloadConfigPresetPlugin(options) {
400
+ return {
401
+ name: 'vite:electron-preload-config-preset',
402
+ apply: 'build',
403
+ enforce: 'pre',
404
+ config(config) {
405
+ const root = options?.root || process.cwd();
406
+ const nodeTarget = getElectronNodeTarget();
407
+ const pkg = loadPackageData() || { type: 'commonjs' };
408
+ const format = pkg.type && pkg.type === 'module' && supportESM() ? 'es' : 'cjs';
409
+ const defaultConfig = {
410
+ ssr: {
411
+ resolve: {
412
+ conditions: ['module', 'browser', 'development|production'],
413
+ mainFields: ['browser', 'module', 'jsnext:main', 'jsnext']
414
+ }
415
+ },
416
+ build: {
417
+ outDir: path.resolve(root, 'out', 'preload'),
418
+ target: nodeTarget,
419
+ assetsDir: 'chunks',
420
+ rollupOptions: {
421
+ external: ['electron', /^electron\/.+/, ...builtinModules.flatMap(m => [m, `node:${m}`])],
422
+ output: {}
423
+ },
424
+ reportCompressedSize: false,
425
+ minify: false
426
+ }
427
+ };
428
+ const build = config.build || {};
429
+ const rollupOptions = build.rollupOptions || {};
430
+ if (!rollupOptions.input) {
431
+ const libOptions = build.lib;
432
+ const outputOptions = rollupOptions.output;
433
+ defaultConfig.build['lib'] = {
434
+ entry: findLibEntry(root, 'preload'),
435
+ formats: libOptions && libOptions.formats && libOptions.formats.length > 0
436
+ ? []
437
+ : [outputOptions && !Array.isArray(outputOptions) && outputOptions.format ? outputOptions.format : format]
438
+ };
439
+ }
440
+ else {
441
+ defaultConfig.build.rollupOptions.output['format'] = format;
442
+ }
443
+ defaultConfig.build.rollupOptions.output['assetFileNames'] = path.posix.join(build.assetsDir || defaultConfig.build.assetsDir, '[name]-[hash].[ext]');
444
+ const buildConfig = mergeConfig(defaultConfig.build, build);
445
+ if (buildConfig.rollupOptions && !buildConfig.rolldownOptions) {
446
+ buildConfig.rolldownOptions = buildConfig.rollupOptions;
447
+ }
448
+ else if (buildConfig.rollupOptions && buildConfig.rolldownOptions) {
449
+ Object.assign(buildConfig.rolldownOptions, buildConfig.rollupOptions);
450
+ }
451
+ config.build = buildConfig;
452
+ const resolvedOutputs = resolveBuildOutputs$1(config.build.rollupOptions.output, config.build.lib || false);
453
+ if (resolvedOutputs) {
454
+ const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs];
455
+ outputs.forEach(output => {
456
+ if (output.format === 'es') {
457
+ output['entryFileNames'] = '[name].mjs';
458
+ output['chunkFileNames'] = '[name]-[hash].mjs';
459
+ }
460
+ else if (output.format === 'cjs') {
461
+ output['entryFileNames'] = '[name].js';
462
+ output['chunkFileNames'] = '[name]-[hash].js';
463
+ }
464
+ });
465
+ if (Array.isArray(config.build.rollupOptions.output)) ;
466
+ else {
467
+ if (outputs[0].format === 'es' || outputs[0].format === 'cjs') {
468
+ config.build.rollupOptions.output['entryFileNames'] = outputs[0]['entryFileNames'];
469
+ config.build.rollupOptions.output['chunkFileNames'] = outputs[0]['chunkFileNames'];
470
+ }
471
+ }
472
+ }
473
+ config.define = config.define || {};
474
+ config.define = { ...processEnvDefine(), ...config.define };
475
+ config.envPrefix = config.envPrefix || ['PRELOAD_VITE_', 'VITE_'];
476
+ config.publicDir = config.publicDir || 'resources';
477
+ // do not copy public dir
478
+ config.build.copyPublicDir = false;
479
+ // module preload polyfill does not apply to nodejs (preload scripts)
480
+ config.build.modulePreload = false;
481
+ // enable ssr build
482
+ config.build.ssr = true;
483
+ config.build.ssrEmitAssets = true;
484
+ config.ssr = mergeConfig(defaultConfig.ssr, config.ssr || {});
485
+ config.ssr.noExternal = /^(?!(electron|electron\/.+)).*/;
486
+ }
487
+ };
488
+ }
489
+ function electronPreloadConfigValidatorPlugin() {
490
+ return {
491
+ name: 'vite:electron-preload-config-validator',
492
+ apply: 'build',
493
+ enforce: 'post',
494
+ configResolved(config) {
495
+ const build = config.build;
496
+ if (!build.target) {
497
+ throw new Error('build.target option is required in the electron vite preload config.');
498
+ }
499
+ else {
500
+ const targets = Array.isArray(build.target) ? build.target : [build.target];
501
+ if (targets.some(t => !t.startsWith('node'))) {
502
+ throw new Error('The electron vite preload config build.target must be "node?".');
503
+ }
504
+ }
505
+ const libOptions = build.lib;
506
+ const rollupOptions = build.rollupOptions;
507
+ if (!(libOptions && libOptions.entry) && !rollupOptions?.input) {
508
+ throw new Error('An entry point is required in the electron vite preload config, ' +
509
+ 'which can be specified using "build.lib.entry" or "build.rollupOptions.input".');
510
+ }
511
+ const resolvedOutputs = resolveBuildOutputs$1(rollupOptions.output, libOptions);
512
+ if (resolvedOutputs) {
513
+ const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs];
514
+ if (outputs.length > 1) {
515
+ throw new Error('The electron vite preload config does not support multiple outputs.');
516
+ }
517
+ else {
518
+ const outpout = outputs[0];
519
+ if (['es', 'cjs'].includes(outpout.format || '')) {
520
+ if (outpout.format === 'es' && !supportESM()) {
521
+ throw new Error('The electron vite preload config output format does not support "es", ' +
522
+ 'you can upgrade electron to the latest version or switch to "cjs" format.');
523
+ }
524
+ }
525
+ else {
526
+ throw new Error(`The electron vite preload config output format must be "cjs"${supportESM() ? ' or "es"' : ''}.`);
527
+ }
528
+ }
529
+ }
530
+ }
531
+ };
532
+ }
533
+ function electronRendererConfigPresetPlugin(options) {
534
+ return {
535
+ name: 'vite:electron-renderer-config-preset',
536
+ enforce: 'pre',
537
+ config(config) {
538
+ const root = options?.root || process.cwd();
539
+ config.base =
540
+ config.mode === 'production' || process.env.NODE_ENV_ELECTRON_VITE === 'production' ? './' : config.base;
541
+ config.root = config.root || './src/renderer';
542
+ const chromeTarget = getElectronChromeTarget();
543
+ const emptyOutDir = () => {
544
+ let outDir = config.build?.outDir;
545
+ if (outDir) {
546
+ if (!path.isAbsolute(outDir)) {
547
+ outDir = path.resolve(root, outDir);
548
+ }
549
+ const resolvedRoot = normalizePath(path.resolve(root));
550
+ return normalizePath(outDir).startsWith(resolvedRoot + '/');
551
+ }
552
+ return true;
553
+ };
554
+ const defaultConfig = {
555
+ build: {
556
+ outDir: path.resolve(root, 'out', 'renderer'),
557
+ target: chromeTarget,
558
+ modulePreload: { polyfill: false },
559
+ rollupOptions: {
560
+ input: findInput(root)
561
+ },
562
+ reportCompressedSize: false,
563
+ minify: false,
564
+ emptyOutDir: emptyOutDir()
565
+ }
566
+ };
567
+ if (config.build?.outDir) {
568
+ config.build.outDir = path.resolve(root, config.build.outDir);
569
+ }
570
+ const buildConfig = mergeConfig(defaultConfig.build, config.build || {});
571
+ if (buildConfig.rollupOptions && !buildConfig.rolldownOptions) {
572
+ buildConfig.rolldownOptions = buildConfig.rollupOptions;
573
+ }
574
+ else if (buildConfig.rollupOptions && buildConfig.rolldownOptions) {
575
+ Object.assign(buildConfig.rolldownOptions, buildConfig.rollupOptions);
576
+ }
577
+ config.build = buildConfig;
578
+ config.envDir = config.envDir || path.resolve(root);
579
+ config.envPrefix = config.envPrefix || ['RENDERER_VITE_', 'VITE_'];
580
+ }
581
+ };
582
+ }
583
+ function electronRendererConfigValidatorPlugin() {
584
+ return {
585
+ name: 'vite:electron-renderer-config-validator',
586
+ enforce: 'post',
587
+ configResolved(config) {
588
+ if (config.base !== './' && config.base !== '/') {
589
+ config.logger.warn(colors.yellow('(!) Should not set "base" option for the electron vite renderer config.'));
590
+ }
591
+ const build = config.build;
592
+ if (!build.target) {
593
+ throw new Error('build.target option is required in the electron vite renderer config.');
594
+ }
595
+ else {
596
+ const targets = Array.isArray(build.target) ? build.target : [build.target];
597
+ if (targets.some(t => !t.startsWith('chrome') && !/^es((202\d{1})|next)$/.test(t))) {
598
+ config.logger.warn('The electron vite renderer config build.target is not "chrome?" or "es?". This could be a mistake.');
599
+ }
600
+ }
601
+ const rollupOptions = build.rollupOptions;
602
+ if (!rollupOptions.input) {
603
+ config.logger.warn(colors.yellow(`index.html file is not found in ${colors.dim('/src/renderer')} directory.`));
604
+ throw new Error('build.rollupOptions.input option is required in the electron vite renderer config.');
605
+ }
606
+ }
607
+ };
608
+ }
609
+
610
+ const nodeAssetRE = /__VITE_NODE_ASSET__([\w$]+)__/g;
611
+ const nodePublicAssetRE = /__VITE_NODE_PUBLIC_ASSET__([a-z\d]{8})__/g;
612
+ const assetImportRE = /(?:[?|&]asset(?:&|$)|\.wasm\?loader$|\.node$)/;
613
+ const assetRE = /[?|&]asset(?:&|$)/;
614
+ const assetUnpackRE = /[?|&]asset&asarUnpack$/;
615
+ const wasmHelperId = '\0__electron-vite-wasm-helper';
616
+ const wasmHelperCode = `
617
+ import { join } from 'path'
618
+ import { readFile } from 'fs/promises'
619
+
620
+ export default async function loadWasm(file, importObject = {}) {
621
+ const wasmBuffer = await readFile(join(__dirname, file))
622
+ const result = await WebAssembly.instantiate(wasmBuffer, importObject)
623
+ return result.instance
624
+ }
625
+ `;
626
+ function assetPlugin() {
627
+ let publicDir = '';
628
+ const publicAssetPathCache = new Map();
629
+ const assetCache = new Map();
630
+ const isImportMetaPathSupported = supportImportMetaPaths();
631
+ return {
632
+ name: 'vite:node-asset',
633
+ apply: 'build',
634
+ enforce: 'pre',
635
+ buildStart() {
636
+ publicAssetPathCache.clear();
637
+ assetCache.clear();
638
+ },
639
+ configResolved(config) {
640
+ publicDir = config.publicDir;
641
+ },
642
+ resolveId(id) {
643
+ if (id === wasmHelperId) {
644
+ return id;
645
+ }
646
+ },
647
+ async load(id) {
648
+ if (id === wasmHelperId) {
649
+ return wasmHelperCode;
650
+ }
651
+ if (id.startsWith('\0') || !assetImportRE.test(id)) {
652
+ return;
653
+ }
654
+ let referenceId;
655
+ const file = cleanUrl(id);
656
+ if (publicDir && file.startsWith(publicDir)) {
657
+ const hash = getHash(file);
658
+ if (!publicAssetPathCache.get(hash)) {
659
+ publicAssetPathCache.set(hash, file);
660
+ }
661
+ referenceId = `__VITE_NODE_PUBLIC_ASSET__${hash}__`;
662
+ }
663
+ else {
664
+ const cached = assetCache.get(file);
665
+ if (cached) {
666
+ referenceId = cached;
667
+ }
668
+ else {
669
+ const source = await fs$1.readFile(file);
670
+ const hash = this.emitFile({
671
+ type: 'asset',
672
+ name: path.basename(file),
673
+ source: source
674
+ });
675
+ referenceId = `__VITE_NODE_ASSET__${hash}__`;
676
+ assetCache.set(file, referenceId);
677
+ }
678
+ }
679
+ if (assetRE.test(id)) {
680
+ const dirnameExpr = isImportMetaPathSupported ? 'import.meta.dirname' : '__dirname';
681
+ if (assetUnpackRE.test(id)) {
682
+ return `
683
+ import { join } from 'path'
684
+ export default join(${dirnameExpr}, ${referenceId}).replace('app.asar', 'app.asar.unpacked')`;
685
+ }
686
+ else {
687
+ return `
688
+ import { join } from 'path'
689
+ export default join(${dirnameExpr}, ${referenceId})`;
690
+ }
691
+ }
692
+ if (id.endsWith('.node')) {
693
+ return `export default require(${referenceId})`;
694
+ }
695
+ if (id.endsWith('.wasm?loader')) {
696
+ return `
697
+ import loadWasm from ${JSON.stringify(wasmHelperId)}
698
+ export default importObject => loadWasm(${referenceId}, importObject)`;
699
+ }
700
+ },
701
+ renderChunk(code, chunk, { sourcemap, dir }) {
702
+ let match;
703
+ let s;
704
+ nodeAssetRE.lastIndex = 0;
705
+ while ((match = nodeAssetRE.exec(code))) {
706
+ s ||= new MagicString(code);
707
+ const [full, hash] = match;
708
+ const filename = this.getFileName(hash);
709
+ const outputFilepath = toRelativePath(filename, chunk.fileName);
710
+ const replacement = JSON.stringify(outputFilepath);
711
+ s.overwrite(match.index, match.index + full.length, replacement, {
712
+ contentOnly: true
713
+ });
714
+ }
715
+ nodePublicAssetRE.lastIndex = 0;
716
+ while ((match = nodePublicAssetRE.exec(code))) {
717
+ s ||= new MagicString(code);
718
+ const [full, hash] = match;
719
+ const filename = publicAssetPathCache.get(hash);
720
+ const outputFilepath = toRelativePath(filename, normalizePath(path.join(dir, chunk.fileName)));
721
+ const replacement = JSON.stringify(outputFilepath);
722
+ s.overwrite(match.index, match.index + full.length, replacement, {
723
+ contentOnly: true
724
+ });
725
+ }
726
+ if (s) {
727
+ return {
728
+ code: s.toString(),
729
+ map: sourcemap ? s.generateMap({ hires: 'boundary' }) : null
730
+ };
731
+ }
732
+ return null;
733
+ }
734
+ };
735
+ }
736
+
737
+ const nodeWorkerAssetUrlRE = /__VITE_NODE_WORKER_ASSET__([\w$]+)__/g;
738
+ const nodeWorkerRE = /\?nodeWorker(?:&|$)/;
739
+ const nodeWorkerImporterRE = /(?:\?)nodeWorker&importer=([^&]+)(?:&|$)/;
740
+ /**
741
+ * Resolve `?nodeWorker` import and automatically generate `Worker` wrapper.
742
+ */
743
+ function workerPlugin() {
744
+ return {
745
+ name: 'vite:node-worker',
746
+ apply: 'build',
747
+ enforce: 'pre',
748
+ resolveId(id, importer) {
749
+ if (id.endsWith('?nodeWorker')) {
750
+ return id + `&importer=${importer}`;
751
+ }
752
+ },
753
+ load(id) {
754
+ if (nodeWorkerRE.test(id)) {
755
+ const match = nodeWorkerImporterRE.exec(id);
756
+ if (match) {
757
+ const hash = this.emitFile({
758
+ type: 'chunk',
759
+ id: cleanUrl(id),
760
+ importer: match[1]
761
+ });
762
+ const assetRefId = `__VITE_NODE_WORKER_ASSET__${hash}__`;
763
+ return `
764
+ import { Worker } from 'node:worker_threads';
765
+ export default function (options) { return new Worker(new URL(${assetRefId}, import.meta.url), options); }`;
766
+ }
767
+ }
768
+ },
769
+ renderChunk(code, chunk, { sourcemap }) {
770
+ let match;
771
+ let s;
772
+ nodeWorkerAssetUrlRE.lastIndex = 0;
773
+ while ((match = nodeWorkerAssetUrlRE.exec(code))) {
774
+ s ||= new MagicString(code);
775
+ const [full, hash] = match;
776
+ const filename = this.getFileName(hash);
777
+ const outputFilepath = toRelativePath(filename, chunk.fileName);
778
+ const replacement = JSON.stringify(outputFilepath);
779
+ s.overwrite(match.index, match.index + full.length, replacement, {
780
+ contentOnly: true
781
+ });
782
+ }
783
+ if (s) {
784
+ return {
785
+ code: s.toString(),
786
+ map: sourcemap ? s.generateMap({ hires: 'boundary' }) : null
787
+ };
788
+ }
789
+ return null;
790
+ }
791
+ };
792
+ }
793
+
794
+ function importMetaPlugin() {
795
+ return {
796
+ name: 'vite:import-meta',
797
+ apply: 'build',
798
+ enforce: 'pre',
799
+ resolveImportMeta(property, { format }) {
800
+ if (property === 'url' && format === 'cjs') {
801
+ return `require("url").pathToFileURL(__filename).href`;
802
+ }
803
+ if (property === 'filename' && format === 'cjs') {
804
+ return `__filename`;
805
+ }
806
+ if (property === 'dirname' && format === 'cjs') {
807
+ return `__dirname`;
808
+ }
809
+ return null;
810
+ }
811
+ };
812
+ }
813
+
814
+ /*
815
+ * The core of this plugin was conceived by pi0 and is taken from the following repository:
816
+ * https://github.com/unjs/unbuild/blob/main/src/builder/plugins/cjs.ts
817
+ * license: https://github.com/unjs/unbuild/blob/main/LICENSE
818
+ */
819
+ const CJSyntaxRe = /__filename|__dirname|require\(|require\.resolve\(/;
820
+ const CJSShim_normal = `
821
+ // -- CommonJS Shims --
822
+ import __cjs_url__ from 'node:url';
823
+ import __cjs_path__ from 'node:path';
824
+ import __cjs_mod__ from 'node:module';
825
+ const __filename = __cjs_url__.fileURLToPath(import.meta.url);
826
+ const __dirname = __cjs_path__.dirname(__filename);
827
+ const require = __cjs_mod__.createRequire(import.meta.url);
828
+ `;
829
+ const CJSShim_node_20_11 = `
830
+ // -- CommonJS Shims --
831
+ import __cjs_mod__ from 'node:module';
832
+ const __filename = import.meta.filename;
833
+ const __dirname = import.meta.dirname;
834
+ const require = __cjs_mod__.createRequire(import.meta.url);
835
+ `;
836
+ const ESMStaticImportRe = /(?<=\s|^|;)import\s*([\s"']*(?<imports>[\p{L}\p{M}\w\t\n\r $*,/{}@.]+)from\s*)?["']\s*(?<specifier>(?<="\s*)[^"]*[^\s"](?=\s*")|(?<='\s*)[^']*[^\s'](?=\s*'))\s*["'][\s;]*/gmu;
837
+ function findStaticImports(code) {
838
+ const matches = [];
839
+ for (const match of code.matchAll(ESMStaticImportRe)) {
840
+ matches.push({ end: (match.index || 0) + match[0].length });
841
+ }
842
+ return matches;
843
+ }
844
+ function esmShimPlugin() {
845
+ const CJSShim = supportImportMetaPaths() ? CJSShim_node_20_11 : CJSShim_normal;
846
+ return {
847
+ name: 'vite:esm-shim',
848
+ apply: 'build',
849
+ enforce: 'post',
850
+ renderChunk(code, _chunk, { format, sourcemap }) {
851
+ if (format === 'es') {
852
+ if (code.includes(CJSShim) || !CJSyntaxRe.test(code)) {
853
+ return null;
854
+ }
855
+ const lastESMImport = findStaticImports(code).pop();
856
+ const indexToAppend = lastESMImport ? lastESMImport.end : 0;
857
+ const s = new MagicString(code);
858
+ s.appendRight(indexToAppend, CJSShim);
859
+ return {
860
+ code: s.toString(),
861
+ map: sourcemap ? s.generateMap({ hires: 'boundary' }) : null
862
+ };
863
+ }
864
+ return null;
865
+ }
866
+ };
867
+ }
868
+
869
+ function buildReporterPlugin() {
870
+ const moduleIds = [];
871
+ return {
872
+ name: 'vite:build-reporter',
873
+ buildEnd() {
874
+ const allModuleIds = Array.from(this.getModuleIds());
875
+ const sourceFiles = allModuleIds.filter(id => {
876
+ if (id.includes('node_modules')) {
877
+ return false;
878
+ }
879
+ const info = this.getModuleInfo(id);
880
+ return info && !info.isExternal;
881
+ });
882
+ moduleIds.push(...sourceFiles);
883
+ },
884
+ api: {
885
+ getWatchFiles() {
886
+ return moduleIds;
887
+ }
888
+ }
889
+ };
890
+ }
891
+
892
+ /* eslint-disable @typescript-eslint/no-explicit-any */
893
+ const modulePathRE = /__VITE_MODULE_PATH__([\w$]+)__/g;
894
+ /**
895
+ * Resolve `?modulePath` import and return the module bundle path.
896
+ */
897
+ function modulePathPlugin(config) {
898
+ const isImportMetaPathSupported = supportImportMetaPaths();
899
+ const assetCache = new Set();
900
+ return {
901
+ name: 'vite:module-path',
902
+ apply: 'build',
903
+ enforce: 'pre',
904
+ buildStart() {
905
+ assetCache.clear();
906
+ },
907
+ async load(id) {
908
+ if (id.endsWith('?modulePath')) {
909
+ // id resolved by Vite resolve plugin
910
+ const re = await bundleEntryFile$1(cleanUrl(id), config, this.meta.watchMode);
911
+ const [outputChunk, ...outputChunks] = re.bundles.output;
912
+ const hash = this.emitFile({
913
+ type: 'asset',
914
+ fileName: outputChunk.fileName,
915
+ source: outputChunk.code
916
+ });
917
+ for (const chunk of outputChunks) {
918
+ if (assetCache.has(chunk.fileName)) {
919
+ continue;
920
+ }
921
+ this.emitFile({
922
+ type: 'asset',
923
+ fileName: chunk.fileName,
924
+ source: chunk.type === 'chunk' ? chunk.code : chunk.source
925
+ });
926
+ assetCache.add(chunk.fileName);
927
+ }
928
+ for (const id of re.watchFiles) {
929
+ this.addWatchFile(id);
930
+ }
931
+ const refId = `__VITE_MODULE_PATH__${hash}__`;
932
+ const dirnameExpr = isImportMetaPathSupported ? 'import.meta.dirname' : '__dirname';
933
+ return `
934
+ import { join } from 'path'
935
+ export default join(${dirnameExpr}, ${refId})`;
936
+ }
937
+ },
938
+ renderChunk(code, chunk, { sourcemap }) {
939
+ let match;
940
+ let s;
941
+ modulePathRE.lastIndex = 0;
942
+ while ((match = modulePathRE.exec(code))) {
943
+ s ||= new MagicString(code);
944
+ const [full, hash] = match;
945
+ const filename = this.getFileName(hash);
946
+ const outputFilepath = toRelativePath(filename, chunk.fileName);
947
+ const replacement = JSON.stringify(outputFilepath);
948
+ s.overwrite(match.index, match.index + full.length, replacement, {
949
+ contentOnly: true
950
+ });
951
+ }
952
+ if (s) {
953
+ return {
954
+ code: s.toString(),
955
+ map: sourcemap ? s.generateMap({ hires: 'boundary' }) : null
956
+ };
957
+ }
958
+ return null;
959
+ }
960
+ };
961
+ }
962
+ async function bundleEntryFile$1(input, config, watch) {
963
+ const reporter = watch ? buildReporterPlugin() : undefined;
964
+ const viteConfig = mergeConfig(config, {
965
+ build: {
966
+ write: false,
967
+ watch: false
968
+ },
969
+ plugins: [
970
+ {
971
+ name: 'vite:entry-file-name',
972
+ outputOptions(output) {
973
+ if (typeof output.entryFileNames !== 'function' && output.entryFileNames) {
974
+ output.entryFileNames = '[name]-[hash]' + path.extname(output.entryFileNames);
975
+ }
976
+ return output;
977
+ }
978
+ },
979
+ reporter
980
+ ],
981
+ logLevel: 'warn',
982
+ configFile: false
983
+ });
984
+ // rewrite the input instead of merging
985
+ const buildOptions = viteConfig.build;
986
+ buildOptions.rollupOptions = {
987
+ ...buildOptions.rollupOptions,
988
+ input
989
+ };
990
+ const bundles = await build(viteConfig);
991
+ return {
992
+ bundles: bundles,
993
+ watchFiles: reporter?.api?.getWatchFiles() || []
994
+ };
995
+ }
996
+
997
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-function-type */
998
+ const VIRTUAL_ENTRY_ID = '\0virtual:isolate-entries';
999
+ const LogLevels = {
1000
+ silent: 0,
1001
+ error: 1,
1002
+ warn: 2,
1003
+ info: 3
1004
+ };
1005
+ function isolateEntriesPlugin(userConfig) {
1006
+ let logger;
1007
+ let entries;
1008
+ let transformedCount = 0;
1009
+ const assetCache = new Set();
1010
+ return {
1011
+ name: 'vite:isolate-entries',
1012
+ apply: 'build',
1013
+ configResolved(config) {
1014
+ logger = config.logger;
1015
+ },
1016
+ options(opts) {
1017
+ const { input } = opts;
1018
+ if (input && typeof input === 'object') {
1019
+ if ((Array.isArray(input) && input.length > 0) || Object.keys(input).length > 1) {
1020
+ opts.input = VIRTUAL_ENTRY_ID;
1021
+ entries = Array.isArray(input) ? input : Object.entries(input).map(([key, value]) => ({ [key]: value }));
1022
+ return opts;
1023
+ }
1024
+ }
1025
+ },
1026
+ buildStart() {
1027
+ transformedCount = 0;
1028
+ assetCache.clear();
1029
+ },
1030
+ resolveId(id) {
1031
+ if (id === VIRTUAL_ENTRY_ID) {
1032
+ return id;
1033
+ }
1034
+ return null;
1035
+ },
1036
+ async load(id) {
1037
+ if (id === VIRTUAL_ENTRY_ID) {
1038
+ const shouldLog = LogLevels[userConfig.logLevel || 'info'] >= LogLevels.info;
1039
+ const shouldWatch = this.meta.watchMode;
1040
+ const watchFiles = new Set();
1041
+ for (const entry of entries) {
1042
+ const re = await bundleEntryFile(entry, userConfig, shouldWatch, shouldLog, transformedCount);
1043
+ const outputChunks = re.bundles.output;
1044
+ for (const chunk of outputChunks) {
1045
+ if (assetCache.has(chunk.fileName)) {
1046
+ continue;
1047
+ }
1048
+ this.emitFile({
1049
+ type: 'asset',
1050
+ fileName: chunk.fileName,
1051
+ source: chunk.type === 'chunk' ? chunk.code : chunk.source
1052
+ });
1053
+ assetCache.add(chunk.fileName);
1054
+ }
1055
+ for (const id of re.watchFiles) {
1056
+ watchFiles.add(id);
1057
+ }
1058
+ transformedCount += re.transformedCount;
1059
+ }
1060
+ for (const id of watchFiles) {
1061
+ this.addWatchFile(id);
1062
+ }
1063
+ return `
1064
+ // This is the virtual entry file
1065
+ console.log(1)`;
1066
+ }
1067
+ },
1068
+ renderStart() {
1069
+ clearLine(-1);
1070
+ logger.info(`${colors.green(`✓`)} ${transformedCount} modules transformed.`);
1071
+ },
1072
+ generateBundle(_, bundle) {
1073
+ for (const chunkName in bundle) {
1074
+ if (chunkName.includes('virtual_isolate-entries')) {
1075
+ delete bundle[chunkName];
1076
+ }
1077
+ }
1078
+ }
1079
+ };
1080
+ }
1081
+ async function bundleEntryFile(input, config, watch, shouldLog, preTransformedCount) {
1082
+ const transformReporter = transformReporterPlugin(preTransformedCount, shouldLog);
1083
+ const buildReporter = watch ? buildReporterPlugin() : undefined;
1084
+ const viteConfig = mergeConfig(config, {
1085
+ build: {
1086
+ write: false,
1087
+ watch: false
1088
+ },
1089
+ plugins: [transformReporter, buildReporter],
1090
+ logLevel: 'warn',
1091
+ configFile: false
1092
+ });
1093
+ // rewrite the input instead of merging
1094
+ viteConfig.build.rollupOptions.input = input;
1095
+ const bundles = await build(viteConfig);
1096
+ return {
1097
+ bundles: bundles,
1098
+ watchFiles: buildReporter?.api?.getWatchFiles() || [],
1099
+ transformedCount: transformReporter?.api?.getTransformedCount() || 0
1100
+ };
1101
+ }
1102
+ function transformReporterPlugin(preTransformedCount = 0, shouldLog = true) {
1103
+ let transformedCount = 0;
1104
+ let root;
1105
+ const log = throttle(id => {
1106
+ writeLine(`transforming (${preTransformedCount + transformedCount}) ${colors.dim(path.relative(root, id))}`);
1107
+ });
1108
+ return {
1109
+ name: 'vite:transform-reporter',
1110
+ configResolved(config) {
1111
+ root = config.root;
1112
+ },
1113
+ transform(_, id) {
1114
+ transformedCount++;
1115
+ if (!shouldLog)
1116
+ return;
1117
+ if (id.includes('?'))
1118
+ return;
1119
+ log(id);
1120
+ },
1121
+ api: {
1122
+ getTransformedCount() {
1123
+ return transformedCount;
1124
+ }
1125
+ }
1126
+ };
1127
+ }
1128
+ function writeLine(output) {
1129
+ if (!process.stdout.isTTY)
1130
+ return;
1131
+ clearLine();
1132
+ if (output.length < process.stdout.columns) {
1133
+ process.stdout.write(output);
1134
+ }
1135
+ else {
1136
+ process.stdout.write(output.substring(0, process.stdout.columns - 1));
1137
+ }
1138
+ }
1139
+ function clearLine(move = 0) {
1140
+ if (!process.stdout.isTTY)
1141
+ return;
1142
+ if (move < 0) {
1143
+ process.stdout.moveCursor(0, move);
1144
+ }
1145
+ process.stdout.clearLine(0);
1146
+ process.stdout.cursorTo(0);
1147
+ }
1148
+ function throttle(fn) {
1149
+ let timerHandle = null;
1150
+ return (...args) => {
1151
+ if (timerHandle)
1152
+ return;
1153
+ fn(...args);
1154
+ timerHandle = setTimeout(() => {
1155
+ timerHandle = null;
1156
+ }, 100);
1157
+ };
1158
+ }
1159
+
1160
+ /**
1161
+ * Automatically externalize dependencies.
1162
+ *
1163
+ * @deprecated use `build.externalizeDeps` config option instead
1164
+ */
1165
+ function externalizeDepsPlugin(options = {}) {
1166
+ const { exclude = [], include = [] } = options;
1167
+ const pkg = loadPackageData() || {};
1168
+ let deps = Object.keys(pkg.dependencies || {});
1169
+ if (include.length) {
1170
+ deps = deps.concat(include.filter(dep => dep.trim() !== ''));
1171
+ }
1172
+ if (exclude.length) {
1173
+ deps = deps.filter(dep => !exclude.includes(dep));
1174
+ }
1175
+ deps = [...new Set(deps)];
1176
+ return {
1177
+ name: 'vite:externalize-deps',
1178
+ enforce: 'pre',
1179
+ config(config) {
1180
+ const defaultConfig = {
1181
+ build: {
1182
+ rollupOptions: {
1183
+ external: deps.length > 0 ? [...deps, new RegExp(`^(${deps.join('|')})/.+`)] : []
1184
+ }
1185
+ }
1186
+ };
1187
+ const buildConfig = mergeConfig(defaultConfig.build, config.build || {});
1188
+ config.build = buildConfig;
1189
+ }
1190
+ };
1191
+ }
1192
+
1193
+ /* eslint-disable @typescript-eslint/no-explicit-any */
1194
+ // Inspired by https://github.com/bytenode/bytenode
1195
+ const _require = createRequire(import.meta.url);
1196
+ function getBytecodeCompilerPath() {
1197
+ return path.join(path.dirname(_require.resolve('electron-vite/package.json')), 'bin', 'electron-bytecode.cjs');
1198
+ }
1199
+ function compileToBytecode(code) {
1200
+ return new Promise((resolve, reject) => {
1201
+ let data = Buffer.from([]);
1202
+ const electronPath = getElectronPath();
1203
+ const bytecodePath = getBytecodeCompilerPath();
1204
+ const proc = spawn(electronPath, [bytecodePath], {
1205
+ env: { ELECTRON_RUN_AS_NODE: '1' },
1206
+ stdio: ['pipe', 'pipe', 'pipe', 'ipc']
1207
+ });
1208
+ if (proc.stdin) {
1209
+ proc.stdin.write(code);
1210
+ proc.stdin.end();
1211
+ }
1212
+ if (proc.stdout) {
1213
+ proc.stdout.on('data', chunk => {
1214
+ data = Buffer.concat([data, chunk]);
1215
+ });
1216
+ proc.stdout.on('error', err => {
1217
+ console.error(err);
1218
+ });
1219
+ proc.stdout.on('end', () => {
1220
+ resolve(data);
1221
+ });
1222
+ }
1223
+ if (proc.stderr) {
1224
+ proc.stderr.on('data', chunk => {
1225
+ console.error('Error: ', chunk.toString());
1226
+ });
1227
+ proc.stderr.on('error', err => {
1228
+ console.error('Error: ', err);
1229
+ });
1230
+ }
1231
+ proc.addListener('message', message => console.log(message));
1232
+ proc.addListener('error', err => console.error(err));
1233
+ proc.on('error', err => reject(err));
1234
+ proc.on('exit', () => {
1235
+ resolve(data);
1236
+ });
1237
+ });
1238
+ }
1239
+ const bytecodeModuleLoaderCode = [
1240
+ `"use strict";`,
1241
+ `const fs = require("fs");`,
1242
+ `const path = require("path");`,
1243
+ `const vm = require("vm");`,
1244
+ `const v8 = require("v8");`,
1245
+ `const Module = require("module");`,
1246
+ `v8.setFlagsFromString("--no-lazy");`,
1247
+ `v8.setFlagsFromString("--no-flush-bytecode");`,
1248
+ `const FLAG_HASH_OFFSET = 12;`,
1249
+ `const SOURCE_HASH_OFFSET = 8;`,
1250
+ `let dummyBytecode;`,
1251
+ `function setFlagHashHeader(bytecodeBuffer) {`,
1252
+ ` if (!dummyBytecode) {`,
1253
+ ` const script = new vm.Script("", {`,
1254
+ ` produceCachedData: true`,
1255
+ ` });`,
1256
+ ` dummyBytecode = script.createCachedData();`,
1257
+ ` }`,
1258
+ ` dummyBytecode.slice(FLAG_HASH_OFFSET, FLAG_HASH_OFFSET + 4).copy(bytecodeBuffer, FLAG_HASH_OFFSET);`,
1259
+ `};`,
1260
+ `function getSourceHashHeader(bytecodeBuffer) {`,
1261
+ ` return bytecodeBuffer.slice(SOURCE_HASH_OFFSET, SOURCE_HASH_OFFSET + 4);`,
1262
+ `};`,
1263
+ `function buffer2Number(buffer) {`,
1264
+ ` let ret = 0;`,
1265
+ ` ret |= buffer[3] << 24;`,
1266
+ ` ret |= buffer[2] << 16;`,
1267
+ ` ret |= buffer[1] << 8;`,
1268
+ ` ret |= buffer[0];`,
1269
+ ` return ret;`,
1270
+ `};`,
1271
+ `Module._extensions[".jsc"] = Module._extensions[".cjsc"] = function (module, filename) {`,
1272
+ ` const bytecodeBuffer = fs.readFileSync(filename);`,
1273
+ ` if (!Buffer.isBuffer(bytecodeBuffer)) {`,
1274
+ ` throw new Error("BytecodeBuffer must be a buffer object.");`,
1275
+ ` }`,
1276
+ ` setFlagHashHeader(bytecodeBuffer);`,
1277
+ ` const length = buffer2Number(getSourceHashHeader(bytecodeBuffer));`,
1278
+ ` let dummyCode = "";`,
1279
+ ` if (length > 1) {`,
1280
+ ` dummyCode = "\\"" + "\\u200b".repeat(length - 2) + "\\"";`,
1281
+ ` }`,
1282
+ ` const script = new vm.Script(dummyCode, {`,
1283
+ ` filename: filename,`,
1284
+ ` lineOffset: 0,`,
1285
+ ` displayErrors: true,`,
1286
+ ` cachedData: bytecodeBuffer`,
1287
+ ` });`,
1288
+ ` if (script.cachedDataRejected) {`,
1289
+ ` throw new Error("Invalid or incompatible cached data (cachedDataRejected)");`,
1290
+ ` }`,
1291
+ ` const require = function (id) {`,
1292
+ ` return module.require(id);`,
1293
+ ` };`,
1294
+ ` require.resolve = function (request, options) {`,
1295
+ ` return Module._resolveFilename(request, module, false, options);`,
1296
+ ` };`,
1297
+ ` if (process.mainModule) {`,
1298
+ ` require.main = process.mainModule;`,
1299
+ ` }`,
1300
+ ` require.extensions = Module._extensions;`,
1301
+ ` require.cache = Module._cache;`,
1302
+ ` const compiledWrapper = script.runInThisContext({`,
1303
+ ` filename: filename,`,
1304
+ ` lineOffset: 0,`,
1305
+ ` columnOffset: 0,`,
1306
+ ` displayErrors: true`,
1307
+ ` });`,
1308
+ ` const dirname = path.dirname(filename);`,
1309
+ ` const args = [module.exports, require, module, filename, dirname, process, global];`,
1310
+ ` return compiledWrapper.apply(module.exports, args);`,
1311
+ `};`
1312
+ ];
1313
+ const bytecodeChunkExtensionRE = /.(jsc|cjsc)$/;
1314
+ /**
1315
+ * Compile source code to v8 bytecode.
1316
+ *
1317
+ * @deprecated use `build.bytecode` config option instead
1318
+ */
1319
+ function bytecodePlugin(options = {}) {
1320
+ if (process.env.NODE_ENV_ELECTRON_VITE !== 'production') {
1321
+ return null;
1322
+ }
1323
+ const { chunkAlias = [], transformArrowFunctions = true, removeBundleJS = true, protectedStrings = [] } = options;
1324
+ const _chunkAlias = Array.isArray(chunkAlias) ? chunkAlias : [chunkAlias];
1325
+ const transformAllChunks = _chunkAlias.length === 0;
1326
+ const isBytecodeChunk = (chunkName) => {
1327
+ return transformAllChunks || _chunkAlias.some(alias => alias === chunkName);
1328
+ };
1329
+ const plugins = [];
1330
+ if (transformArrowFunctions) {
1331
+ plugins.push('@babel/plugin-transform-arrow-functions');
1332
+ }
1333
+ if (protectedStrings.length > 0) {
1334
+ plugins.push([protectStringsPlugin, { protectedStrings: new Set(protectedStrings) }]);
1335
+ }
1336
+ const shouldTransformBytecodeChunk = plugins.length !== 0;
1337
+ const _transform = (code, sourceMaps = false) => {
1338
+ const re = babel.transform(code, { plugins, sourceMaps });
1339
+ return re ? { code: re.code || '', map: re.map } : null;
1340
+ };
1341
+ const useStrict = '"use strict";';
1342
+ const bytecodeModuleLoader = 'bytecode-loader.cjs';
1343
+ let logger;
1344
+ let supported = false;
1345
+ return {
1346
+ name: 'vite:bytecode',
1347
+ apply: 'build',
1348
+ enforce: 'post',
1349
+ configResolved(config) {
1350
+ if (supported) {
1351
+ return;
1352
+ }
1353
+ logger = config.logger;
1354
+ const useInRenderer = config.plugins.some(p => p.name === 'vite:electron-renderer-preset-config');
1355
+ if (useInRenderer) {
1356
+ config.logger.warn(colors.yellow('bytecodePlugin does not support renderer.'));
1357
+ return;
1358
+ }
1359
+ const build = config.build;
1360
+ const resolvedOutputs = resolveBuildOutputs(build.rollupOptions.output, build.lib);
1361
+ if (resolvedOutputs) {
1362
+ const outputs = Array.isArray(resolvedOutputs) ? resolvedOutputs : [resolvedOutputs];
1363
+ const output = outputs[0];
1364
+ if (output.format === 'es') {
1365
+ config.logger.warn(colors.yellow('bytecodePlugin does not support ES module, please remove "type": "module" ' +
1366
+ 'in package.json or set the "build.rollupOptions.output.format" option to "cjs".'));
1367
+ }
1368
+ supported = output.format === 'cjs' && !useInRenderer;
1369
+ }
1370
+ },
1371
+ renderChunk(code, chunk, { sourcemap }) {
1372
+ if (supported && isBytecodeChunk(chunk.name) && shouldTransformBytecodeChunk) {
1373
+ return _transform(code, !!sourcemap);
1374
+ }
1375
+ return null;
1376
+ },
1377
+ async generateBundle(_, output) {
1378
+ if (!supported) {
1379
+ return;
1380
+ }
1381
+ const _chunks = Object.values(output);
1382
+ const chunks = _chunks.filter(chunk => chunk.type === 'chunk' && isBytecodeChunk(chunk.name));
1383
+ if (chunks.length === 0) {
1384
+ return;
1385
+ }
1386
+ const bytecodeChunks = chunks.map(chunk => chunk.fileName);
1387
+ const nonEntryChunks = chunks.filter(chunk => !chunk.isEntry).map(chunk => path.basename(chunk.fileName));
1388
+ const pattern = nonEntryChunks.map(chunk => `(${chunk})`).join('|');
1389
+ const bytecodeRE = pattern ? new RegExp(`require\\(\\S*(?=(${pattern})\\S*\\))`, 'g') : null;
1390
+ const getBytecodeLoaderBlock = (chunkFileName) => {
1391
+ return `require("${toRelativePath(bytecodeModuleLoader, normalizePath(chunkFileName))}");`;
1392
+ };
1393
+ let bytecodeChunkCount = 0;
1394
+ const bundles = Object.keys(output);
1395
+ await Promise.all(bundles.map(async (name) => {
1396
+ const chunk = output[name];
1397
+ if (chunk.type === 'chunk') {
1398
+ let _code = chunk.code;
1399
+ if (bytecodeRE) {
1400
+ let match;
1401
+ let s;
1402
+ while ((match = bytecodeRE.exec(_code))) {
1403
+ s ||= new MagicString(_code);
1404
+ const [prefix, chunkName] = match;
1405
+ const len = prefix.length + chunkName.length;
1406
+ s.overwrite(match.index, match.index + len, prefix + chunkName + 'c', {
1407
+ contentOnly: true
1408
+ });
1409
+ }
1410
+ if (s) {
1411
+ _code = s.toString();
1412
+ }
1413
+ }
1414
+ if (bytecodeChunks.includes(name)) {
1415
+ const bytecodeBuffer = await compileToBytecode(_code);
1416
+ this.emitFile({
1417
+ type: 'asset',
1418
+ fileName: name + 'c',
1419
+ source: bytecodeBuffer
1420
+ });
1421
+ if (!removeBundleJS) {
1422
+ this.emitFile({
1423
+ type: 'asset',
1424
+ fileName: '_' + chunk.fileName,
1425
+ source: chunk.code
1426
+ });
1427
+ }
1428
+ if (chunk.isEntry) {
1429
+ const bytecodeLoaderBlock = getBytecodeLoaderBlock(chunk.fileName);
1430
+ const bytecodeModuleBlock = `require("./${path.basename(name) + 'c'}");`;
1431
+ const code = `${useStrict}\n${bytecodeLoaderBlock}\n${bytecodeModuleBlock}\n`;
1432
+ chunk.code = code;
1433
+ }
1434
+ else {
1435
+ delete output[chunk.fileName];
1436
+ }
1437
+ bytecodeChunkCount += 1;
1438
+ }
1439
+ else {
1440
+ if (chunk.isEntry) {
1441
+ let hasBytecodeMoudle = false;
1442
+ const idsToHandle = new Set([...chunk.imports, ...chunk.dynamicImports]);
1443
+ for (const moduleId of idsToHandle) {
1444
+ if (bytecodeChunks.includes(moduleId)) {
1445
+ hasBytecodeMoudle = true;
1446
+ break;
1447
+ }
1448
+ const moduleInfo = this.getModuleInfo(moduleId);
1449
+ if (moduleInfo && !moduleInfo.isExternal) {
1450
+ const { importers, dynamicImporters } = moduleInfo;
1451
+ for (const importerId of importers)
1452
+ idsToHandle.add(importerId);
1453
+ for (const importerId of dynamicImporters)
1454
+ idsToHandle.add(importerId);
1455
+ }
1456
+ }
1457
+ _code = hasBytecodeMoudle
1458
+ ? _code.replace(/("use strict";)|('use strict';)/, `${useStrict}\n${getBytecodeLoaderBlock(chunk.fileName)}`)
1459
+ : _code;
1460
+ }
1461
+ chunk.code = _code;
1462
+ }
1463
+ }
1464
+ }));
1465
+ if (bytecodeChunkCount && !_chunks.some(ass => ass.type === 'asset' && ass.fileName === bytecodeModuleLoader)) {
1466
+ this.emitFile({
1467
+ type: 'asset',
1468
+ source: bytecodeModuleLoaderCode.join('\n') + '\n',
1469
+ name: 'Bytecode Loader File',
1470
+ fileName: bytecodeModuleLoader
1471
+ });
1472
+ }
1473
+ },
1474
+ writeBundle(_, output) {
1475
+ if (supported) {
1476
+ const bytecodeChunkCount = Object.keys(output).filter(chunk => bytecodeChunkExtensionRE.test(chunk)).length;
1477
+ logger.info(`${colors.green(`✓`)} ${bytecodeChunkCount} chunks compiled into bytecode.`);
1478
+ }
1479
+ }
1480
+ };
1481
+ }
1482
+ function resolveBuildOutputs(outputs, libOptions) {
1483
+ if (libOptions && !Array.isArray(outputs)) {
1484
+ const libFormats = libOptions.formats || [];
1485
+ return libFormats.map(format => ({ ...outputs, format }));
1486
+ }
1487
+ return outputs;
1488
+ }
1489
+ function protectStringsPlugin(api) {
1490
+ const { types: t } = api;
1491
+ function createFromCharCodeFunction(value) {
1492
+ const charCodes = Array.from(value).map(s => s.charCodeAt(0));
1493
+ const charCodeLiterals = charCodes.map(code => t.numericLiteral(code));
1494
+ // String.fromCharCode
1495
+ const memberExpression = t.memberExpression(t.identifier('String'), t.identifier('fromCharCode'));
1496
+ // String.fromCharCode(...arr)
1497
+ const callExpression = t.callExpression(memberExpression, [t.spreadElement(t.identifier('arr'))]);
1498
+ // return String.fromCharCode(...arr)
1499
+ const returnStatement = t.returnStatement(callExpression);
1500
+ // function (arr) { return ... }
1501
+ const functionExpression = t.functionExpression(null, [t.identifier('arr')], t.blockStatement([returnStatement]));
1502
+ // (function(...) { ... })([x, x, x])
1503
+ return t.callExpression(functionExpression, [t.arrayExpression(charCodeLiterals)]);
1504
+ }
1505
+ return {
1506
+ name: 'protect-strings-plugin',
1507
+ visitor: {
1508
+ StringLiteral(path, state) {
1509
+ // obj['property']
1510
+ if (path.parentPath.isMemberExpression({ property: path.node, computed: true })) {
1511
+ return;
1512
+ }
1513
+ // { 'key': value }
1514
+ if (path.parentPath.isObjectProperty({ key: path.node, computed: false })) {
1515
+ return;
1516
+ }
1517
+ // require('fs')
1518
+ if (path.parentPath.isCallExpression() &&
1519
+ t.isIdentifier(path.parentPath.node.callee) &&
1520
+ path.parentPath.node.callee.name === 'require' &&
1521
+ path.parentPath.node.arguments[0] === path.node) {
1522
+ return;
1523
+ }
1524
+ // Only CommonJS is supported, import declaration and export declaration checks are ignored
1525
+ const { value } = path.node;
1526
+ if (state.opts.protectedStrings.has(value)) {
1527
+ path.replaceWith(createFromCharCodeFunction(value));
1528
+ }
1529
+ },
1530
+ TemplateLiteral(path, state) {
1531
+ // Must be a pure static template literal
1532
+ // expressions must be empty (no ${variables})
1533
+ // quasis must have only one element (meaning the entire string is a single static part).
1534
+ if (path.node.expressions.length > 0 || path.node.quasis.length !== 1) {
1535
+ return;
1536
+ }
1537
+ // Extract the raw value of the template literal
1538
+ // path.node.quasis[0].value.raw is used to get the raw string, including escape sequences
1539
+ // path.node.quasis[0].value.cooked is used to get the processed/cooked string (with escape sequences handled)
1540
+ const value = path.node.quasis[0].value.cooked;
1541
+ if (value && state.opts.protectedStrings.has(value)) {
1542
+ path.replaceWith(createFromCharCodeFunction(value));
1543
+ }
1544
+ }
1545
+ }
1546
+ };
1547
+ }
1548
+
1549
+ function defineConfig(config) {
1550
+ return config;
1551
+ }
1552
+ async function resolveConfig(inlineConfig, command, defaultMode = 'development') {
1553
+ const config = inlineConfig;
1554
+ const mode = inlineConfig.mode || defaultMode;
1555
+ process.env.NODE_ENV = defaultMode;
1556
+ let userConfig;
1557
+ let configFileDependencies = [];
1558
+ let { configFile } = config;
1559
+ if (configFile !== false) {
1560
+ const configEnv = {
1561
+ mode,
1562
+ command
1563
+ };
1564
+ const loadResult = await loadConfigFromFile(configEnv, configFile, config.root, config.logLevel, config.ignoreConfigWarning);
1565
+ if (loadResult) {
1566
+ const root = config.root;
1567
+ delete config.root;
1568
+ delete config.configFile;
1569
+ config.configFile = false;
1570
+ const outDir = config.build?.outDir;
1571
+ if (loadResult.config.main) {
1572
+ const mainViteConfig = mergeConfig(loadResult.config.main, deepClone(config));
1573
+ mainViteConfig.mode = inlineConfig.mode || mainViteConfig.mode || defaultMode;
1574
+ if (outDir) {
1575
+ resetOutDir(mainViteConfig, outDir, 'main');
1576
+ }
1577
+ const configDrivenPlugins = await resolveConfigDrivenPlugins(mainViteConfig);
1578
+ const builtInMainPlugins = [
1579
+ electronMainConfigPresetPlugin({ root }),
1580
+ electronMainConfigValidatorPlugin(),
1581
+ assetPlugin(),
1582
+ workerPlugin(),
1583
+ modulePathPlugin(mergeConfig({
1584
+ plugins: [
1585
+ electronMainConfigPresetPlugin({ root }),
1586
+ assetPlugin(),
1587
+ importMetaPlugin(),
1588
+ esmShimPlugin(),
1589
+ ...configDrivenPlugins
1590
+ ]
1591
+ }, mainViteConfig)),
1592
+ importMetaPlugin(),
1593
+ esmShimPlugin(),
1594
+ ...configDrivenPlugins
1595
+ ];
1596
+ mainViteConfig.plugins = builtInMainPlugins.concat(mainViteConfig.plugins || []);
1597
+ loadResult.config.main = mainViteConfig;
1598
+ }
1599
+ if (loadResult.config.preload) {
1600
+ const preloadViteConfig = mergeConfig(loadResult.config.preload, deepClone(config));
1601
+ preloadViteConfig.mode = inlineConfig.mode || preloadViteConfig.mode || defaultMode;
1602
+ if (outDir) {
1603
+ resetOutDir(preloadViteConfig, outDir, 'preload');
1604
+ }
1605
+ const configDrivenPlugins = await resolveConfigDrivenPlugins(preloadViteConfig);
1606
+ const builtInPreloadPlugins = [
1607
+ electronPreloadConfigPresetPlugin({ root }),
1608
+ electronPreloadConfigValidatorPlugin(),
1609
+ assetPlugin(),
1610
+ importMetaPlugin(),
1611
+ esmShimPlugin(),
1612
+ ...configDrivenPlugins
1613
+ ];
1614
+ if (preloadViteConfig.build?.isolatedEntries) {
1615
+ builtInPreloadPlugins.push(isolateEntriesPlugin(mergeConfig({
1616
+ plugins: [
1617
+ electronPreloadConfigPresetPlugin({ root }),
1618
+ assetPlugin(),
1619
+ importMetaPlugin(),
1620
+ esmShimPlugin(),
1621
+ ...configDrivenPlugins
1622
+ ]
1623
+ }, preloadViteConfig)));
1624
+ }
1625
+ preloadViteConfig.plugins = builtInPreloadPlugins.concat(preloadViteConfig.plugins);
1626
+ loadResult.config.preload = preloadViteConfig;
1627
+ }
1628
+ if (loadResult.config.renderer) {
1629
+ const rendererViteConfig = mergeConfig(loadResult.config.renderer, deepClone(config));
1630
+ rendererViteConfig.mode = inlineConfig.mode || rendererViteConfig.mode || defaultMode;
1631
+ if (outDir) {
1632
+ resetOutDir(rendererViteConfig, outDir, 'renderer');
1633
+ }
1634
+ const builtInRendererPlugins = [
1635
+ electronRendererConfigPresetPlugin({ root }),
1636
+ electronRendererConfigValidatorPlugin()
1637
+ ];
1638
+ if (rendererViteConfig.build?.isolatedEntries) {
1639
+ builtInRendererPlugins.push(isolateEntriesPlugin(mergeConfig({
1640
+ plugins: [electronRendererConfigPresetPlugin({ root })]
1641
+ }, rendererViteConfig)));
1642
+ }
1643
+ rendererViteConfig.plugins = builtInRendererPlugins.concat(rendererViteConfig.plugins || []);
1644
+ loadResult.config.renderer = rendererViteConfig;
1645
+ }
1646
+ userConfig = loadResult.config;
1647
+ configFile = loadResult.path;
1648
+ configFileDependencies = loadResult.dependencies;
1649
+ }
1650
+ }
1651
+ const resolved = {
1652
+ config: userConfig,
1653
+ configFile: configFile ? normalizePath(configFile) : undefined,
1654
+ configFileDependencies
1655
+ };
1656
+ return resolved;
1657
+ }
1658
+ function resetOutDir(config, outDir, subOutDir) {
1659
+ let userOutDir = config.build?.outDir;
1660
+ if (outDir === userOutDir) {
1661
+ userOutDir = path.resolve(config.root || process.cwd(), outDir, subOutDir);
1662
+ if (config.build) {
1663
+ config.build.outDir = userOutDir;
1664
+ }
1665
+ else {
1666
+ config.build = { outDir: userOutDir };
1667
+ }
1668
+ }
1669
+ }
1670
+ async function resolveConfigDrivenPlugins(config) {
1671
+ const userPlugins = (await asyncFlatten(config.plugins || [])).filter(Boolean);
1672
+ const configDrivenPlugins = [];
1673
+ const hasExternalizeDepsPlugin = userPlugins.some(p => p.name === 'vite:externalize-deps');
1674
+ if (!hasExternalizeDepsPlugin) {
1675
+ const externalOptions = config.build?.externalizeDeps ?? true;
1676
+ if (externalOptions) {
1677
+ isOptions(externalOptions)
1678
+ ? configDrivenPlugins.push(externalizeDepsPlugin(externalOptions))
1679
+ : configDrivenPlugins.push(externalizeDepsPlugin());
1680
+ }
1681
+ }
1682
+ const hasBytecodePlugin = userPlugins.some(p => p.name === 'vite:bytecode');
1683
+ if (!hasBytecodePlugin) {
1684
+ const bytecodeOptions = config.build?.bytecode;
1685
+ if (bytecodeOptions) {
1686
+ isOptions(bytecodeOptions)
1687
+ ? configDrivenPlugins.push(bytecodePlugin(bytecodeOptions))
1688
+ : configDrivenPlugins.push(bytecodePlugin());
1689
+ }
1690
+ }
1691
+ return configDrivenPlugins;
1692
+ }
1693
+ function isOptions(value) {
1694
+ return typeof value === 'object' && value !== null;
1695
+ }
1696
+ const CONFIG_FILE_NAME = 'electron.vite.config';
1697
+ async function loadConfigFromFile(configEnv, configFile, configRoot = process.cwd(), logLevel, ignoreConfigWarning = false) {
1698
+ if (configFile && /^vite\.config\.(js|ts|mjs|cjs|mts|cts)$/.test(configFile)) {
1699
+ throw new Error(`config file cannot be named ${configFile}.`);
1700
+ }
1701
+ const resolvedPath = configFile
1702
+ ? path.resolve(configFile)
1703
+ : findConfigFile(configRoot, ['js', 'ts', 'mjs', 'cjs', 'mts', 'cts']);
1704
+ if (!resolvedPath) {
1705
+ return {
1706
+ path: '',
1707
+ config: { main: {}, preload: {}, renderer: {} },
1708
+ dependencies: []
1709
+ };
1710
+ }
1711
+ try {
1712
+ const result = await loadConfigFromFile$1(configEnv, resolvedPath, configRoot, logLevel);
1713
+ if (!result) {
1714
+ return {
1715
+ path: '',
1716
+ config: { main: {}, preload: {}, renderer: {} },
1717
+ dependencies: []
1718
+ };
1719
+ }
1720
+ const config = result.config;
1721
+ if (!isObject(config)) {
1722
+ throw new Error(`config must export or return an object`);
1723
+ }
1724
+ if (!ignoreConfigWarning) {
1725
+ const missingFields = ['main', 'renderer', 'preload'].filter(field => !config[field]);
1726
+ if (missingFields.length > 0) {
1727
+ createLogger(logLevel).warn(`${colors.yellow(colors.bold('(!)'))} ${colors.yellow(`${missingFields.join(' and ')} config is missing`)}\n`);
1728
+ }
1729
+ }
1730
+ return {
1731
+ path: normalizePath(result.path),
1732
+ config,
1733
+ dependencies: result.dependencies
1734
+ };
1735
+ }
1736
+ catch (e) {
1737
+ createLogger(logLevel).error(colors.red(`failed to load config from ${resolvedPath}`), { error: e });
1738
+ throw e;
1739
+ }
1740
+ }
1741
+ function findConfigFile(configRoot, extensions) {
1742
+ for (const ext of extensions) {
1743
+ const configFile = path.resolve(configRoot, `${CONFIG_FILE_NAME}.${ext}`);
1744
+ if (fs.existsSync(configFile)) {
1745
+ return configFile;
1746
+ }
1747
+ }
1748
+ return '';
1749
+ }
1750
+
1751
+ export { loadEnv as a, bytecodePlugin as b, resolveHostname as c, defineConfig as d, externalizeDepsPlugin as e, loadConfigFromFile as l, resolveConfig as r, startElectron as s };