Skip to content
Permalink
Browse files

feat(core): add support for restarting the Electron process quickly f…

…rom terminal

just time 'rs' in your terminal
  • Loading branch information
MarshallOfSound committed May 7, 2018
1 parent 4135c6c commit 24aab4fda2f04c41cf70438f131e04980789fe2d
@@ -65,6 +65,7 @@ import './util/terminate';

await new Promise((resolve) => {
spawned.on('exit', (code: number) => {
if ((spawned as any).restarted) return;
if (code !== 0) {
process.exit(code);
}
@@ -50,50 +50,70 @@ export default async ({

await runHook(forgeConfig, 'generateAssets');

let electronExecPath = path.resolve(dir, 'node_modules/electron/cli');
let lastSpawned: ChildProcess | null = null;

// If a plugin has taken over the start command let's stop here
const spawnedPluginChild = await forgeConfig.pluginInterface.overrideStartLogic({
dir,
appPath,
interactive,
enableLogging,
args,
runAsNode,
inspect,
});
if (typeof spawnedPluginChild === 'string') {
electronExecPath = spawnedPluginChild;
} else if (spawnedPluginChild) {
await runHook(forgeConfig, 'postStart', spawnedPluginChild);
return spawnedPluginChild;
}

const spawnOpts = {
cwd: dir,
stdio: 'inherit',
env: Object.assign({}, process.env, enableLogging ? {
ELECTRON_ENABLE_LOGGING: 'true',
ELECTRON_ENABLE_STACK_DUMPING: 'true',
} : {}) as NodeJS.ProcessEnv,
const forgeSpawnWrapper = async () => {
lastSpawned = await forgeSpawn();
return lastSpawned;
};

if (runAsNode) {
spawnOpts.env.ELECTRON_RUN_AS_NODE = 'true';
} else {
delete spawnOpts.env.ELECTRON_RUN_AS_NODE;
}
const forgeSpawn = async () => {
let electronExecPath = require(path.resolve(dir, 'node_modules/electron'));

// If a plugin has taken over the start command let's stop here
const spawnedPluginChild = await forgeConfig.pluginInterface.overrideStartLogic({
dir,
appPath,
interactive,
enableLogging,
args,
runAsNode,
inspect,
});
if (typeof spawnedPluginChild === 'string') {
electronExecPath = spawnedPluginChild;
} else if (spawnedPluginChild) {
await runHook(forgeConfig, 'postStart', spawnedPluginChild);
return spawnedPluginChild;
}

if (inspect) {
args = ['--inspect' as (string|number)].concat(args);
}
const spawnOpts = {
cwd: dir,
stdio: 'inherit',
env: Object.assign({}, process.env, enableLogging ? {
ELECTRON_ENABLE_LOGGING: 'true',
ELECTRON_ENABLE_STACK_DUMPING: 'true',
} : {}) as NodeJS.ProcessEnv,
};

if (runAsNode) {
spawnOpts.env.ELECTRON_RUN_AS_NODE = 'true';
} else {
delete spawnOpts.env.ELECTRON_RUN_AS_NODE;
}

if (inspect) {
args = ['--inspect' as (string|number)].concat(args);
}

let spawned!: ChildProcess;

let spawned!: ChildProcess;
await asyncOra('Launching Application', async () => {
spawned = spawn(electronExecPath, [appPath].concat(args as string[]), spawnOpts);
});

await asyncOra('Launching Application', async () => {
spawned = spawn(process.execPath, [electronExecPath, appPath].concat(args as string[]), spawnOpts);
await runHook(forgeConfig, 'postStart', spawned);
return spawned;
};

process.stdin.on('data', (data) => {
if (data.toString().trim() === 'rs' && lastSpawned) {
console.info('\nRestarting App\n'.cyan);
(lastSpawned as any).restarted = true;
lastSpawned.kill('SIGTERM');
forgeSpawnWrapper();
}
});

await runHook(forgeConfig, 'postStart', spawned);
return spawned;
return forgeSpawnWrapper();
};
@@ -73,6 +73,8 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
process.on('SIGINT', this.exitHandler.bind(this, { exit: true }));
}

private loggedOutputUrl = false;

getHook(name: string) {
switch (name) {
case 'prePackage':
@@ -83,9 +85,15 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
};
case 'postStart':
return async (_: any, child: ChildProcess) => {
console.info('\n\nWebpack Output Available: http://localhost:9000\n');
if (!this.loggedOutputUrl) {
console.info(`\n\nWebpack Output Available: ${'http://localhost:9000'.cyan}\n`);
this.loggedOutputUrl = true;
}
d('hooking electron process exit');
child.on('exit', () => this.exitHandler({ cleanup: true, exit: true }));
child.on('exit', () => {
if ((child as any).restarted) return;
this.exitHandler({ cleanup: true, exit: true })
});
};
}
return null;
@@ -286,7 +294,12 @@ export default class WebpackPlugin extends PluginBase<WebpackPluginConfig> {
});
}

private alreadyStarted = false;

async startLogic(): Promise<false> {
if (this.alreadyStarted) return false;
this.alreadyStarted = true;

const logger = new Logger();
this.loggers.push(logger);
await this.compileMain(true, logger);

0 comments on commit 24aab4f

Please sign in to comment.
You can’t perform that action at this time.