Skip to content

Commit dfc9358

Browse files
alan-agius4vikerman
authored andcommitted
fix(builders): display server console message
Fixes #1355
1 parent e93647b commit dfc9358

File tree

2 files changed

+47
-16
lines changed

2 files changed

+47
-16
lines changed

modules/builders/src/ssr-dev-server/index.ts

+25-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,18 @@ import {
3030
catchError,
3131
startWith,
3232
mapTo,
33+
ignoreElements,
3334
} from 'rxjs/operators';
34-
import { getAvailablePort, execAsObservable } from './utils';
35+
import { getAvailablePort, spawnAsObservable } from './utils';
3536
import * as browserSync from 'browser-sync';
3637
import { join } from 'path';
3738

39+
/** Log messages to ignore and not rely to the logger */
40+
const IGNORED_STDOUT_MESSAGES = [
41+
'server listening on',
42+
'Angular is running in the development mode. Call enableProdMode() to enable the production mode.'
43+
];
44+
3845
export type SSRDevServerBuilderOptions = Schema & json.JsonObject;
3946

4047
export function execute(
@@ -77,7 +84,7 @@ export function execute(
7784
if (!s.success) {
7885
return of(s);
7986
}
80-
return startNodeServer(s, nodeServerPort).pipe(
87+
return startNodeServer(s, nodeServerPort, context.logger).pipe(
8188
mapTo(s),
8289
catchError(err => {
8390
context.logger.error(`A server error has occurred.\n${mapErrorToMessage(err)}`);
@@ -126,16 +133,29 @@ export function execute(
126133
);
127134
}
128135

129-
function startNodeServer(serverOutput: BuilderOutput, port: number): Observable<void> {
136+
function startNodeServer(
137+
serverOutput: BuilderOutput,
138+
port: number,
139+
logger: logging.LoggerApi,
140+
): Observable<void> {
130141
const outputPath = serverOutput.outputPath as string;
131142
const path = join(outputPath, 'main.js');
132143
const env = { ...process.env, PORT: '' + port };
133144

134-
return execAsObservable(`node ${path}`, { env })
145+
return spawnAsObservable('node', [`"${path}"`], { env, shell: true })
135146
.pipe(
136147
// Emit a signal after the process has been started
148+
tap(({ stderr, stdout }) => {
149+
if (stderr) {
150+
logger.error(stderr);
151+
}
152+
153+
if (stdout && !IGNORED_STDOUT_MESSAGES.some(x => stdout.includes(x))) {
154+
logger.info(stdout);
155+
}
156+
}),
157+
ignoreElements(),
137158
startWith(undefined),
138-
mapTo(undefined),
139159
);
140160
}
141161

modules/builders/src/ssr-dev-server/utils.ts

+22-11
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import { exec, ExecOptions } from 'child_process';
9+
import { spawn, SpawnOptions } from 'child_process';
1010
import { Observable } from 'rxjs';
1111
import * as treeKill from 'tree-kill';
1212
import { createServer, AddressInfo } from 'net';
@@ -24,18 +24,29 @@ export function getAvailablePort(): Promise<number> {
2424
});
2525
}
2626

27-
export function execAsObservable(command: string, options: ExecOptions):
28-
Observable<{ stdout: string, stderr: string }> {
27+
export function spawnAsObservable(
28+
command: string,
29+
args: string[] = [],
30+
options: SpawnOptions = {}
31+
): Observable<{ stdout?: string, stderr?: string }> {
2932
return new Observable(obs => {
30-
const proc = exec(command, options, (err, stdout, stderr) => {
31-
if (err) {
32-
obs.error(err);
33-
return;
34-
}
33+
const proc = spawn(command, args, options);
34+
if (!proc) {
35+
obs.error(new Error(`${command} cannot be spawned.`));
36+
return;
37+
}
38+
39+
if (proc.stdout) {
40+
proc.stdout.on('data', data => obs.next({ stdout: data.toString() }));
41+
}
42+
43+
if (proc.stderr) {
44+
proc.stderr.on('data', data => obs.next({ stderr: data.toString() }));
45+
}
3546

36-
obs.next({ stdout, stderr });
37-
obs.complete();
38-
});
47+
proc
48+
.on('error', err => obs.error(err))
49+
.on('close', () => obs.complete());
3950

4051
return () => {
4152
if (!proc.killed) {

0 commit comments

Comments
 (0)