Skip to content

Commit eb02517

Browse files
committed
fix(dev-server): improve exiting dev server process
1 parent 2574094 commit eb02517

File tree

5 files changed

+272
-213
lines changed

5 files changed

+272
-213
lines changed

src/declarations/stencil-private.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,7 @@ export interface DevServerContext {
10271027
dirTemplate: string;
10281028
getBuildResults: () => Promise<CompilerBuildResults>;
10291029
getCompilerRequest: (path: string) => Promise<CompilerRequestResponse>;
1030+
isServerListening: boolean;
10301031
logRequest: (req: { method: string; pathname?: string }, status: number) => void;
10311032
prerenderConfig: PrerenderConfig;
10321033
serve302: (req: any, res: any, pathname?: string) => void;

src/dev-server/server-context.ts

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
import type * as d from '../declarations';
2+
import { responseHeaders } from './dev-server-utils';
3+
import fs from 'graceful-fs';
4+
import path from 'path';
5+
import util from 'util';
6+
7+
export function createServerContext(
8+
sys: d.CompilerSystem,
9+
sendMsg: d.DevServerSendMessage,
10+
devServerConfig: d.DevServerConfig,
11+
buildResultsResolves: BuildRequestResolve[],
12+
compilerRequestResolves: CompilerRequestResolve[],
13+
) {
14+
const logRequest = (req: d.HttpRequest, status: number) => {
15+
if (devServerConfig) {
16+
sendMsg({
17+
requestLog: {
18+
method: req.method || '?',
19+
url: req.pathname || '?',
20+
status,
21+
},
22+
});
23+
}
24+
};
25+
26+
const serve500 = (req: d.HttpRequest, res: any, error: any, xSource: string) => {
27+
try {
28+
res.writeHead(
29+
500,
30+
responseHeaders({
31+
'content-type': 'text/plain; charset=utf-8',
32+
'x-source': xSource,
33+
}),
34+
);
35+
res.write(util.inspect(error));
36+
res.end();
37+
logRequest(req, 500);
38+
} catch (e) {
39+
sendMsg({ error: { message: 'serve500: ' + e } });
40+
}
41+
};
42+
43+
const serve404 = (req: d.HttpRequest, res: any, xSource: string, content: string = null) => {
44+
try {
45+
if (req.pathname === '/favicon.ico') {
46+
const defaultFavicon = path.join(devServerConfig.devServerDir, 'static', 'favicon.ico');
47+
res.writeHead(
48+
200,
49+
responseHeaders({
50+
'content-type': 'image/x-icon',
51+
'x-source': `favicon: ${xSource}`,
52+
}),
53+
);
54+
const rs = fs.createReadStream(defaultFavicon);
55+
rs.on('error', err => {
56+
res.writeHead(
57+
404,
58+
responseHeaders({
59+
'content-type': 'text/plain; charset=utf-8',
60+
'x-source': `createReadStream error: ${err}, ${xSource}`,
61+
}),
62+
);
63+
res.write(util.inspect(err));
64+
res.end();
65+
});
66+
rs.pipe(res);
67+
return;
68+
}
69+
70+
if (content == null) {
71+
content = ['404 File Not Found', 'Url: ' + req.pathname, 'File: ' + req.filePath].join('\n');
72+
}
73+
res.writeHead(
74+
404,
75+
responseHeaders({
76+
'content-type': 'text/plain; charset=utf-8',
77+
'x-source': xSource,
78+
}),
79+
);
80+
res.write(content);
81+
res.end();
82+
83+
logRequest(req, 400);
84+
} catch (e) {
85+
serve500(req, res, e, xSource);
86+
}
87+
};
88+
89+
const serve302 = (req: d.HttpRequest, res: any, pathname: string = null) => {
90+
logRequest(req, 302);
91+
res.writeHead(302, { location: pathname || devServerConfig.basePath || '/' });
92+
res.end();
93+
};
94+
95+
const getBuildResults = () =>
96+
new Promise<d.CompilerBuildResults>((resolve, reject) => {
97+
if (serverCtx.isServerListening) {
98+
buildResultsResolves.push({ resolve, reject });
99+
sendMsg({ requestBuildResults: true });
100+
} else {
101+
reject('dev server closed');
102+
}
103+
});
104+
105+
const getCompilerRequest = (compilerRequestPath: string) =>
106+
new Promise<d.CompilerRequestResponse>((resolve, reject) => {
107+
if (serverCtx.isServerListening) {
108+
compilerRequestResolves.push({
109+
path: compilerRequestPath,
110+
resolve,
111+
reject,
112+
});
113+
sendMsg({ compilerRequestPath });
114+
} else {
115+
reject('dev server closed');
116+
}
117+
});
118+
119+
const serverCtx: d.DevServerContext = {
120+
connectorHtml: null,
121+
dirTemplate: null,
122+
getBuildResults,
123+
getCompilerRequest,
124+
isServerListening: false,
125+
logRequest,
126+
prerenderConfig: null,
127+
serve302,
128+
serve404,
129+
serve500,
130+
sys,
131+
};
132+
133+
return serverCtx;
134+
}
135+
136+
export interface CompilerRequestResolve {
137+
path: string;
138+
resolve: (results: d.CompilerRequestResponse) => void;
139+
reject: (msg: any) => void;
140+
}
141+
142+
export interface BuildRequestResolve {
143+
resolve: (results: d.CompilerBuildResults) => void;
144+
reject: (msg: any) => void;
145+
}

0 commit comments

Comments
 (0)