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