Skip to content

Commit

Permalink
feat: add flag to disable shell mode for nest start --watch
Browse files Browse the repository at this point in the history
When running on Linux/WSL, `nest start --watch` does not wait the app to shutdown on restart.
That leads to two instances of application running simultaneously, especially if it has async
shutdown hooks. That commit fixes that adding an option to disable shell mode when spawning
child processes so then app will completely shutdown first and only then started again.
Thanks @jleverenz for the investigation and solution idea in nestjs/nest-cli/1614

fixes nestjs/nest-cli/1614
  • Loading branch information
quallrum committed Nov 11, 2024
1 parent ed9d8b8 commit 21291f2
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 1 deletion.
9 changes: 8 additions & 1 deletion actions/start.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,15 @@ export class StartAction extends BuildAction {
commandOptions,
defaultConfiguration.sourceRoot,
);
const noShellOption = commandOptions.find((option) => option.name === 'noShell')
const useShell = noShellOption ? !noShellOption.value : true;
const onSuccess = this.createOnSuccessHook(
entryFile,
sourceRoot,
debugFlag,
outDir,
binaryToRun,
useShell,
);

await this.runBuild(
Expand All @@ -103,6 +106,7 @@ export class StartAction extends BuildAction {
debugFlag: boolean | string | undefined,
outDirName: string,
binaryToRun: string,
useShell: boolean,
) {
let childProcessRef: any;
process.on(
Expand All @@ -120,6 +124,7 @@ export class StartAction extends BuildAction {
debugFlag,
outDirName,
binaryToRun,
useShell,
);
childProcessRef.on('exit', () => (childProcessRef = undefined));
});
Expand All @@ -133,6 +138,7 @@ export class StartAction extends BuildAction {
debugFlag,
outDirName,
binaryToRun,
useShell,
);
childProcessRef.on('exit', (code: number) => {
process.exitCode = code;
Expand All @@ -148,6 +154,7 @@ export class StartAction extends BuildAction {
debug: boolean | string | undefined,
outDirName: string,
binaryToRun: string,
useShell: boolean,
) {
let outputFilePath = join(outDirName, sourceRoot, entryFile);
if (!fs.existsSync(outputFilePath + '.js')) {
Expand Down Expand Up @@ -179,7 +186,7 @@ export class StartAction extends BuildAction {

return spawn(binaryToRun, processArgs, {
stdio: 'inherit',
shell: true,
shell: useShell,
});
}
}
5 changes: 5 additions & 0 deletions commands/start.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export class StartCommand extends AbstractCommand {
'--preserveWatchOutput',
'Use "preserveWatchOutput" option when using tsc watch mode.',
)
.option('--noShell', 'Spawn child processes without shell (see node\'s child_process.spawn() method docs)')
.description('Run Nest application.')
.action(async (app: string, command: Command) => {
const options: Input[] = [];
Expand Down Expand Up @@ -79,6 +80,10 @@ export class StartCommand extends AbstractCommand {
!!command.watch &&
!isWebpackEnabled,
});
options.push({
name: 'noShell',
value: !!command.noShell,
})

const availableBuilders = ['tsc', 'webpack', 'swc'];
if (command.builder && !availableBuilders.includes(command.builder)) {
Expand Down

0 comments on commit 21291f2

Please sign in to comment.