Skip to content

Commit

Permalink
fix(dev-server): improve exiting dev server process
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdbradley committed Sep 17, 2020
1 parent 2574094 commit eb02517
Show file tree
Hide file tree
Showing 5 changed files with 272 additions and 213 deletions.
1 change: 1 addition & 0 deletions src/declarations/stencil-private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,7 @@ export interface DevServerContext {
dirTemplate: string;
getBuildResults: () => Promise<CompilerBuildResults>;
getCompilerRequest: (path: string) => Promise<CompilerRequestResponse>;
isServerListening: boolean;
logRequest: (req: { method: string; pathname?: string }, status: number) => void;
prerenderConfig: PrerenderConfig;
serve302: (req: any, res: any, pathname?: string) => void;
Expand Down
145 changes: 145 additions & 0 deletions src/dev-server/server-context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import type * as d from '../declarations';
import { responseHeaders } from './dev-server-utils';
import fs from 'graceful-fs';
import path from 'path';
import util from 'util';

export function createServerContext(
sys: d.CompilerSystem,
sendMsg: d.DevServerSendMessage,
devServerConfig: d.DevServerConfig,
buildResultsResolves: BuildRequestResolve[],
compilerRequestResolves: CompilerRequestResolve[],
) {
const logRequest = (req: d.HttpRequest, status: number) => {
if (devServerConfig) {
sendMsg({
requestLog: {
method: req.method || '?',
url: req.pathname || '?',
status,
},
});
}
};

const serve500 = (req: d.HttpRequest, res: any, error: any, xSource: string) => {
try {
res.writeHead(
500,
responseHeaders({
'content-type': 'text/plain; charset=utf-8',
'x-source': xSource,
}),
);
res.write(util.inspect(error));
res.end();
logRequest(req, 500);
} catch (e) {
sendMsg({ error: { message: 'serve500: ' + e } });
}
};

const serve404 = (req: d.HttpRequest, res: any, xSource: string, content: string = null) => {
try {
if (req.pathname === '/favicon.ico') {
const defaultFavicon = path.join(devServerConfig.devServerDir, 'static', 'favicon.ico');
res.writeHead(
200,
responseHeaders({
'content-type': 'image/x-icon',
'x-source': `favicon: ${xSource}`,
}),
);
const rs = fs.createReadStream(defaultFavicon);
rs.on('error', err => {
res.writeHead(
404,
responseHeaders({
'content-type': 'text/plain; charset=utf-8',
'x-source': `createReadStream error: ${err}, ${xSource}`,
}),
);
res.write(util.inspect(err));
res.end();
});
rs.pipe(res);
return;
}

if (content == null) {
content = ['404 File Not Found', 'Url: ' + req.pathname, 'File: ' + req.filePath].join('\n');
}
res.writeHead(
404,
responseHeaders({
'content-type': 'text/plain; charset=utf-8',
'x-source': xSource,
}),
);
res.write(content);
res.end();

logRequest(req, 400);
} catch (e) {
serve500(req, res, e, xSource);
}
};

const serve302 = (req: d.HttpRequest, res: any, pathname: string = null) => {
logRequest(req, 302);
res.writeHead(302, { location: pathname || devServerConfig.basePath || '/' });
res.end();
};

const getBuildResults = () =>
new Promise<d.CompilerBuildResults>((resolve, reject) => {
if (serverCtx.isServerListening) {
buildResultsResolves.push({ resolve, reject });
sendMsg({ requestBuildResults: true });
} else {
reject('dev server closed');
}
});

const getCompilerRequest = (compilerRequestPath: string) =>
new Promise<d.CompilerRequestResponse>((resolve, reject) => {
if (serverCtx.isServerListening) {
compilerRequestResolves.push({
path: compilerRequestPath,
resolve,
reject,
});
sendMsg({ compilerRequestPath });
} else {
reject('dev server closed');
}
});

const serverCtx: d.DevServerContext = {
connectorHtml: null,
dirTemplate: null,
getBuildResults,
getCompilerRequest,
isServerListening: false,
logRequest,
prerenderConfig: null,
serve302,
serve404,
serve500,
sys,
};

return serverCtx;
}

export interface CompilerRequestResolve {
path: string;
resolve: (results: d.CompilerRequestResponse) => void;
reject: (msg: any) => void;
}

export interface BuildRequestResolve {
resolve: (results: d.CompilerBuildResults) => void;
reject: (msg: any) => void;
}
Loading

0 comments on commit eb02517

Please sign in to comment.