Skip to content

Commit 73033bb

Browse files
Attempt to setup vite in electron
1 parent 7ad5073 commit 73033bb

19 files changed

Lines changed: 924 additions & 194 deletions

electron-app/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ typings/
8989
dist/
9090

9191
# Electron-Forge
92+
.vite/
9293
out/
9394

9495
# Ember build
Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
1-
module.exports = {
1+
import { MakerDeb } from '@electron-forge/maker-deb';
2+
import { MakerSquirrel } from '@electron-forge/maker-squirrel';
3+
import { MakerZIP } from '@electron-forge/maker-zip';
4+
import { FusesPlugin } from '@electron-forge/plugin-fuses';
5+
import { VitePlugin } from '@electron-forge/plugin-vite';
6+
import type { ForgeConfig } from '@electron-forge/shared-types';
7+
import { FuseV1Options, FuseVersion } from '@electron/fuses';
8+
9+
const config: ForgeConfig = {
210
packagerConfig: {
311
asar: true,
4-
darwinDarkModeSupport: 'true',
12+
darwinDarkModeSupport: true,
513
icon: 'electron-app/resources/icon',
614
name: 'Swach',
715
packageManager: 'pnpm',
@@ -24,8 +32,8 @@ module.exports = {
2432
},
2533
osxNotarize: {
2634
tool: 'notarytool',
27-
appleId: process.env['APPLE_ID'],
28-
appleIdPassword: process.env['APPLE_ID_PASSWORD'],
35+
appleId: process.env['APPLE_ID'] as string,
36+
appleIdPassword: process.env['APPLE_ID_PASSWORD'] as string,
2937
teamId: '779MXKT6B5',
3038
},
3139
protocols: [
@@ -112,6 +120,42 @@ module.exports = {
112120
platforms: ['darwin'],
113121
},
114122
],
123+
plugins: [
124+
new VitePlugin({
125+
// `build` can specify multiple entry builds, which can be Main process, Preload scripts, Worker process, etc.
126+
// If you are familiar with Vite configuration, it will look really familiar.
127+
build: [
128+
{
129+
// `entry` is just an alias for `build.lib.entry` in the corresponding file of `config`.
130+
entry: 'src/main.ts',
131+
config: 'vite.main.config.ts',
132+
target: 'main',
133+
},
134+
{
135+
entry: 'electron-app/src/preload.ts',
136+
config: 'vite.preload.config.ts',
137+
target: 'preload',
138+
},
139+
],
140+
renderer: [
141+
{
142+
name: 'main_window',
143+
config: 'vite.renderer.config.ts',
144+
},
145+
],
146+
}),
147+
// Fuses are used to enable/disable various Electron functionality
148+
// at package time, before code signing the application
149+
new FusesPlugin({
150+
version: FuseVersion.V1,
151+
[FuseV1Options.RunAsNode]: false,
152+
[FuseV1Options.EnableCookieEncryption]: true,
153+
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
154+
[FuseV1Options.EnableNodeCliInspectArguments]: false,
155+
[FuseV1Options.EnableEmbeddedAsarIntegrityValidation]: true,
156+
[FuseV1Options.OnlyLoadAppFromAsar]: true,
157+
}),
158+
],
115159
// publishers: [
116160
// {
117161
// name: '@electron-forge/publisher-snapcraft',
@@ -122,3 +166,5 @@ module.exports = {
122166
// },
123167
// ],
124168
};
169+
170+
export default config;

electron-app/forge.env.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/// <reference types="@electron-forge/plugin-vite/forge-vite-env" />

electron-app/package.json

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
"productName": "swach",
44
"version": "1.2.15",
55
"description": "A robust color management tool for the modern age.",
6-
"main": "src/index.js",
6+
"main": ".vite/build/main.js",
7+
"type": "module",
78
"scripts": {
89
"start": "electron-forge start",
910
"package": "electron-forge package",
1011
"make": "electron-forge make",
1112
"publish": "electron-forge publish",
12-
"lint": "echo \"No linting configured\""
13+
"lint": "eslint --ext .ts,.tsx ."
1314
},
1415
"keywords": [],
1516
"author": {
@@ -39,11 +40,20 @@
3940
"@electron-forge/maker-snap": "^7.8.3",
4041
"@electron-forge/maker-squirrel": "^7.8.3",
4142
"@electron-forge/maker-zip": "^7.8.3",
43+
"@electron-forge/plugin-auto-unpack-natives": "^7.8.3",
44+
"@electron-forge/plugin-fuses": "^7.8.3",
45+
"@electron-forge/plugin-vite": "^7.8.3",
46+
"@electron/fuses": "^1.8.0",
4247
"@electron-forge/publisher-snapcraft": "^7.8.3",
4348
"@sentry/cli": "^2.51.1",
49+
"@types/electron-squirrel-startup": "^1.0.2",
50+
"@typescript-eslint/eslint-plugin": "^5.62.0",
51+
"@typescript-eslint/parser": "^5.62.0",
4452
"electron": "^33.4.11",
4553
"electron-debug": "^3.2.0",
46-
"electron-download": "^4.1.1"
54+
"electron-download": "^4.1.1",
55+
"typescript": "~4.5.4",
56+
"vite": "^5.4.19"
4757
},
4858
"packageManager": "pnpm@10.11.0",
4959
"engines": {
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
const { autoUpdater, dialog } = require('electron');
1+
import { autoUpdater, dialog } from 'electron';
22

3-
const setupUpdateServer = (app) => {
3+
export const setupUpdateServer = (app) => {
44
const server = 'https://download.swach.io';
55
const feed = `${server}/update/${process.platform}/${app.getVersion()}`;
66

@@ -39,7 +39,3 @@ const setupUpdateServer = (app) => {
3939

4040
return autoUpdater;
4141
};
42-
43-
module.exports = {
44-
setupUpdateServer,
45-
};

electron-app/src/browsers/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
'use strict';
1+
import windowFactory from './window.js';
22

3-
module.exports = (dirname) => ({
4-
settings: require('./window')(dirname, 'settings', 'Settings'),
3+
export default (dirname) => ({
4+
settings: windowFactory(dirname, 'settings', 'Settings'),
55
});
Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,18 @@
1-
'use strict';
1+
// window.js (ESM)
2+
import { BrowserWindow } from 'electron';
23

3-
const { BrowserWindow } = require('electron');
4-
5-
module.exports = (dirname, route, title) => {
4+
export default (dirname, route, title) => {
5+
/** @type {import('electron').BrowserWindow | undefined} */
66
let win;
77

8-
/**
9-
* [init]
10-
* @param {boolean} force [force launching new window]
11-
* @return {void} [new Colorpicker]
12-
*/
13-
let init = () => {
14-
if (win === null || win === undefined) createWindow();
8+
const init = () => {
9+
if (win == null) createWindow();
1510
else win.show();
16-
17-
// win.openDevTools();
11+
// win.webContents.openDevTools();
1812
};
1913

20-
/**
21-
* [createWindow - create new Window]
22-
* @param {int} width [width of the window]
23-
* @param {int} height [height of the window]
24-
* @return {void}
25-
*/
26-
let createWindow = () => {
27-
let options = {
14+
const createWindow = () => {
15+
const options = {
2816
width: 700,
2917
height: 500,
3018
minWidth: 460,
@@ -39,22 +27,20 @@ module.exports = (dirname, route, title) => {
3927
};
4028

4129
win = new BrowserWindow(options);
30+
4231
const windowRoute = `serve://dist#/${route}`;
4332
win.loadURL(windowRoute);
4433

4534
win.on('closed', () => {
4635
win = undefined;
4736
});
4837

49-
win.on('page-title-updated', function (e) {
38+
win.on('page-title-updated', (e) => {
5039
e.preventDefault();
5140
});
5241
};
5342

54-
let getWindow = () => win;
43+
const getWindow = () => win;
5544

56-
return {
57-
init: init,
58-
getWindow: getWindow,
59-
};
45+
return { init, getWindow };
6046
};
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
async function launchPicker(mb, type = 'global') {
1+
export async function launchPicker(mb, type = 'global') {
22
mb.hideWindow();
33

44
const color = await mb.window.webContents.executeJavaScript(
Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
const { app, dialog } = require('electron');
1+
import { app, dialog } from 'electron';
22

3-
function noUpdatesAvailableDialog() {
3+
export function noUpdatesAvailableDialog() {
44
const dialogOpts = {
55
type: 'info',
66
title: 'Already up to date',
@@ -11,7 +11,7 @@ function noUpdatesAvailableDialog() {
1111
return dialog.showMessageBox(dialogOpts);
1212
}
1313

14-
function restartDialog() {
14+
export function restartDialog() {
1515
const dialogOpts = {
1616
type: 'question',
1717
buttons: ['Restart', 'Later'],
@@ -28,8 +28,3 @@ function restartDialog() {
2828
}
2929
});
3030
}
31-
32-
module.exports = {
33-
noUpdatesAvailableDialog,
34-
restartDialog,
35-
};
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
1-
const fs = require('fs');
2-
const path = require('path');
3-
const { fileURLToPath, pathToFileURL } = require('url');
4-
const { promisify } = require('util');
5-
6-
const access = promisify(fs.access);
1+
import { access } from 'node:fs/promises';
2+
import path from 'node:path';
3+
import { fileURLToPath, pathToFileURL } from 'node:url';
4+
import { net, protocol } from 'electron';
75

86
//
97
// Patch asset loading -- Ember apps use absolute paths to reference their
108
// assets, e.g. `<img src="/images/foo.jpg">`. When the current URL is a `file:`
119
// URL, that ends up resolving to the absolute filesystem path `/images/foo.jpg`
1210
// rather than being relative to the root of the Ember app. So, we intercept
13-
// `file:` URL request and look to see if they point to an asset when
11+
// `file:` URL requests and look to see if they point to an asset when
1412
// interpreted as being relative to the root of the Ember app. If so, we return
1513
// that path, and if not we leave them as-is, as their absolute path.
1614
//
17-
async function getAssetPath(emberAppDir, url) {
18-
let urlPath = fileURLToPath(url);
15+
export async function getAssetPath(emberAppDir: string, url: string) {
16+
const urlPath = fileURLToPath(url);
1917
// Get the root of the path -- should be '/' on MacOS or something like
20-
// 'C:\' on Windows
21-
let { root } = path.parse(urlPath);
18+
// 'C:\\' on Windows
19+
const { root } = path.parse(urlPath);
2220
// Get the relative path from the root to the full path
23-
let relPath = path.relative(root, urlPath);
21+
const relPath = path.relative(root, urlPath);
2422
// Join the relative path with the Ember app directory
25-
let appPath = path.join(emberAppDir, relPath);
23+
const appPath = path.join(emberAppDir, relPath);
24+
2625
try {
2726
await access(appPath);
2827
return appPath;
@@ -31,14 +30,12 @@ async function getAssetPath(emberAppDir, url) {
3130
}
3231
}
3332

34-
module.exports = function handleFileURLs(emberAppDir) {
35-
const { protocol, net } = require('electron');
36-
33+
export default function handleFileURLs(emberAppDir: string) {
3734
if (protocol.handle) {
3835
// Electron >= 25
3936
protocol.handle('file', async ({ url }) => {
40-
let path = await getAssetPath(emberAppDir, url);
41-
return net.fetch(pathToFileURL(path), {
37+
const assetPath = await getAssetPath(emberAppDir, url);
38+
return net.fetch(pathToFileURL(assetPath), {
4239
bypassCustomProtocolHandlers: true,
4340
});
4441
});
@@ -48,6 +45,4 @@ module.exports = function handleFileURLs(emberAppDir) {
4845
callback(await getAssetPath(emberAppDir, url));
4946
});
5047
}
51-
};
52-
53-
module.exports.getAssetPath = getAssetPath;
48+
}

0 commit comments

Comments
 (0)