Skip to content

Commit e37a029

Browse files
committed
feat: use electron-next to run app in dev mode
1 parent 838543e commit e37a029

File tree

5 files changed

+73
-4
lines changed

5 files changed

+73
-4
lines changed

.env.example

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# App-specific environment variable.
2+
# Similar purpose as NODE_ENV but for our own use, and at times
3+
# may not be in sync with the NODE_ENV the app is running under.
4+
# When running the app via `yarn start:dev` then this is set to 'development'.
5+
# For all other cases, this should be set to 'production'.
6+
APP_ENV="production"
7+
18
# To allow Sentry to upload events from renderer process.
29
# Our Content-Security Policy allow lists this domain.
310
# Infer this from the SENTRY_DSN.

.github/workflows/build.yml

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ jobs:
5454
SENTRY_PROJECT: ${{ github.event.repository.name }}
5555
run: |
5656
echo "" > .env
57+
echo "APP_ENV=production" >> .env
58+
5759
echo "SENTRY_INGEST_DOMAIN=${SENTRY_INGEST_DOMAIN}" >> .env
5860
echo "SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN}" >> .env
5961
echo "SENTRY_DSN=${SENTRY_DSN}" >> .env

electron/main/app.ts

+39-4
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,52 @@ app.setAppUserModelId('com.github.dragonrealms-phoenix.phoenix');
1616

1717
const logger = createLogger('main');
1818

19+
const appEnv = process.env.APP_ENV ?? 'production';
20+
const appEnvIsProd = appEnv === 'production';
21+
const appEnvIsDev = appEnv === 'development';
22+
1923
const appPath = app.getAppPath();
20-
const appBuildPath = path.join(appPath, 'electron', 'build');
24+
const appElectronPath = path.join(appPath, 'electron');
25+
const appBuildPath = path.join(appElectronPath, 'build');
2126
const appPreloadPath = path.join(appBuildPath, 'preload');
22-
const appRendererPath = path.join(appBuildPath, 'renderer');
27+
28+
// When running in production, serve the app from these paths.
29+
const prodRendererPath = path.join(appBuildPath, 'renderer');
30+
const prodAppScheme = 'app';
31+
const prodAppUrl = `${prodAppScheme}://-`;
32+
33+
// When running in development, serve the app from these paths.
34+
const devRendererPath = path.join(appElectronPath, 'renderer');
35+
const devPort = 3000;
36+
const devAppUrl = `http://localhost:${devPort}`;
37+
38+
const appUrl = appEnvIsProd ? prodAppUrl : devAppUrl;
2339

2440
// Register custom protocol 'app://' to serve our app.
2541
// Registering the protocol must be done before the app is ready.
2642
// This is necessary for both security and for single-page apps.
2743
// https://bishopfox.com/blog/reasonably-secure-electron
2844
// https://github.com/sindresorhus/electron-serve
29-
serve({ directory: appRendererPath });
45+
if (appEnvIsProd) {
46+
serve({
47+
scheme: prodAppScheme,
48+
directory: prodRendererPath,
49+
});
50+
}
3051

3152
const createWindow = async (): Promise<void> => {
53+
if (appEnvIsDev) {
54+
// If running in development, serve the renderer from localhost.
55+
// This must be done once the app is ready.
56+
// This enables hot reloading of the renderer.
57+
const { default: serveDev } = await import('electron-next');
58+
await serveDev(devRendererPath, devPort);
59+
}
60+
3261
const mainWindow = new BrowserWindow({
3362
width: 1200,
3463
height: 800,
64+
show: false, // hidden until window loads contents to avoid a blank screen
3565
webPreferences: {
3666
preload: path.join(appPreloadPath, 'index.js'),
3767
devTools: !app.isPackaged,
@@ -54,7 +84,12 @@ const createWindow = async (): Promise<void> => {
5484
},
5585
});
5686

57-
await mainWindow.loadURL('app://-');
87+
// Once the window has finished loading, show it.
88+
mainWindow.webContents.once('did-finish-load', () => {
89+
mainWindow.show();
90+
});
91+
92+
await mainWindow.loadURL(appUrl);
5893

5994
initializeMenu(mainWindow);
6095
};

electron/main/electron.next.d.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Source: https://github.com/leo/electron-next
2+
// Typings: https://github.com/vercel/next.js/blob/canary/examples/with-electron-typescript/electron-src/electron-next.d.ts
3+
4+
declare module 'electron-next' {
5+
interface Directories {
6+
production: string;
7+
development: string;
8+
}
9+
10+
export default function (
11+
/**
12+
* Path to your nextjs app directory.
13+
* Can provide a string or an object with
14+
* separate paths for production and development.
15+
*/
16+
directories: Directories | string,
17+
/**
18+
* Port to serve the nextjs app from.
19+
* Default 8000.
20+
*/
21+
port?: number
22+
): Promise<void>;
23+
}

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@
3636
"lint:staged": "lint-staged --concurrent 1",
3737
"format": "yarn prettier:fix && yarn lint:fix",
3838
"start": "yarn build && yarn sentry:sourcemaps && electron .",
39+
"start:dev": "yarn build:dev && APP_ENV=development electron .",
3940
"build:main": "tsc -p electron/main",
4041
"build:preload": "tsc -p electron/preload && yarn prettier:fix electron/preload/**/*.d.ts",
4142
"build:renderer": "next build electron/renderer",
4243
"build": "yarn clean && concurrently \"yarn build:main\" \"yarn build:preload\" \"yarn build:renderer\"",
44+
"build:dev": "yarn clean && concurrently \"yarn build:main\" \"yarn build:preload\"",
4345
"build:all": "yarn build && electron-builder --win --mac --linux --config",
4446
"build:win": "yarn build && electron-builder --win --config",
4547
"build:mac": "yarn build && electron-builder --mac --config",

0 commit comments

Comments
 (0)