Skip to content

Commit

Permalink
feat: use electron-next to run app in dev mode
Browse files Browse the repository at this point in the history
  • Loading branch information
KatoakDR committed Oct 23, 2023
1 parent 838543e commit e37a029
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 4 deletions.
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# App-specific environment variable.
# Similar purpose as NODE_ENV but for our own use, and at times
# may not be in sync with the NODE_ENV the app is running under.
# When running the app via `yarn start:dev` then this is set to 'development'.
# For all other cases, this should be set to 'production'.
APP_ENV="production"

# To allow Sentry to upload events from renderer process.
# Our Content-Security Policy allow lists this domain.
# Infer this from the SENTRY_DSN.
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ jobs:
SENTRY_PROJECT: ${{ github.event.repository.name }}
run: |
echo "" > .env
echo "APP_ENV=production" >> .env
echo "SENTRY_INGEST_DOMAIN=${SENTRY_INGEST_DOMAIN}" >> .env
echo "SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN}" >> .env
echo "SENTRY_DSN=${SENTRY_DSN}" >> .env
Expand Down
43 changes: 39 additions & 4 deletions electron/main/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,52 @@ app.setAppUserModelId('com.github.dragonrealms-phoenix.phoenix');

const logger = createLogger('main');

const appEnv = process.env.APP_ENV ?? 'production';
const appEnvIsProd = appEnv === 'production';
const appEnvIsDev = appEnv === 'development';

const appPath = app.getAppPath();
const appBuildPath = path.join(appPath, 'electron', 'build');
const appElectronPath = path.join(appPath, 'electron');
const appBuildPath = path.join(appElectronPath, 'build');
const appPreloadPath = path.join(appBuildPath, 'preload');
const appRendererPath = path.join(appBuildPath, 'renderer');

// When running in production, serve the app from these paths.
const prodRendererPath = path.join(appBuildPath, 'renderer');
const prodAppScheme = 'app';
const prodAppUrl = `${prodAppScheme}://-`;

// When running in development, serve the app from these paths.
const devRendererPath = path.join(appElectronPath, 'renderer');
const devPort = 3000;
const devAppUrl = `http://localhost:${devPort}`;

const appUrl = appEnvIsProd ? prodAppUrl : devAppUrl;

// Register custom protocol 'app://' to serve our app.
// Registering the protocol must be done before the app is ready.
// This is necessary for both security and for single-page apps.
// https://bishopfox.com/blog/reasonably-secure-electron
// https://github.com/sindresorhus/electron-serve
serve({ directory: appRendererPath });
if (appEnvIsProd) {
serve({
scheme: prodAppScheme,
directory: prodRendererPath,
});
}

const createWindow = async (): Promise<void> => {
if (appEnvIsDev) {
// If running in development, serve the renderer from localhost.
// This must be done once the app is ready.
// This enables hot reloading of the renderer.
const { default: serveDev } = await import('electron-next');
await serveDev(devRendererPath, devPort);
}

const mainWindow = new BrowserWindow({
width: 1200,
height: 800,
show: false, // hidden until window loads contents to avoid a blank screen
webPreferences: {
preload: path.join(appPreloadPath, 'index.js'),
devTools: !app.isPackaged,
Expand All @@ -54,7 +84,12 @@ const createWindow = async (): Promise<void> => {
},
});

await mainWindow.loadURL('app://-');
// Once the window has finished loading, show it.
mainWindow.webContents.once('did-finish-load', () => {
mainWindow.show();
});

await mainWindow.loadURL(appUrl);

initializeMenu(mainWindow);
};
Expand Down
23 changes: 23 additions & 0 deletions electron/main/electron.next.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Source: https://github.com/leo/electron-next
// Typings: https://github.com/vercel/next.js/blob/canary/examples/with-electron-typescript/electron-src/electron-next.d.ts

declare module 'electron-next' {
interface Directories {
production: string;
development: string;
}

export default function (
/**
* Path to your nextjs app directory.
* Can provide a string or an object with
* separate paths for production and development.
*/
directories: Directories | string,
/**
* Port to serve the nextjs app from.
* Default 8000.
*/
port?: number
): Promise<void>;
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@
"lint:staged": "lint-staged --concurrent 1",
"format": "yarn prettier:fix && yarn lint:fix",
"start": "yarn build && yarn sentry:sourcemaps && electron .",
"start:dev": "yarn build:dev && APP_ENV=development electron .",
"build:main": "tsc -p electron/main",
"build:preload": "tsc -p electron/preload && yarn prettier:fix electron/preload/**/*.d.ts",
"build:renderer": "next build electron/renderer",
"build": "yarn clean && concurrently \"yarn build:main\" \"yarn build:preload\" \"yarn build:renderer\"",
"build:dev": "yarn clean && concurrently \"yarn build:main\" \"yarn build:preload\"",
"build:all": "yarn build && electron-builder --win --mac --linux --config",
"build:win": "yarn build && electron-builder --win --config",
"build:mac": "yarn build && electron-builder --mac --config",
Expand Down

0 comments on commit e37a029

Please sign in to comment.