Skip to content

Commit

Permalink
fix http dev webpack server middleware loading (#1733)
Browse files Browse the repository at this point in the history
  • Loading branch information
yishengjiang99 authored Sep 3, 2020
1 parent 8ae327b commit 62aee49
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 51 deletions.
96 changes: 52 additions & 44 deletions packages/xarc-app-dev/src/lib/dev-admin/dev-http.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable no-console */

import { createReadStream } from "fs";
import { createServer, IncomingMessage, RequestListener, ServerResponse } from "http";
import { Readable } from "stream";
import { getType } from "mime";
import { createServer, Server } from "http";
import * as Url from "url";
import { resolve } from "path";
const Middleware = require("./middleware");
import { resolve as pathResolve } from "path";

const Middleware = require("./middleware");
const FakeRes = require("../fake-res");
export interface DevHttpServerOptions {
port: number;
host: string;
Expand All @@ -15,11 +20,10 @@ export type HttpRequestEvent = "connect" | "response" | "timeout" | "close" | "f
export type HttpServerEvent = "open" | "close" | "listening" | "error";

export interface DevHttpServer {
webpackDevHttpPlugin: RequestListener;
start: () => void;
stop?: () => void;
addRequestListener: (event: HttpRequestEvent, handler: any) => void;
addServerEventListener: (event: HttpServerEvent, hander: any) => void;
stop: () => void;
httpServer?: Server;
addListener: (event: HttpServerEvent, hander: any) => void;
}

export const setupHttpDevServer = function({
Expand All @@ -39,53 +43,57 @@ export const setupHttpDevServer = function({

middleware.setup();

const requestEventHooks = {};
const server: Server = createServer(async (req, res) => {
try {
const next1 = await middleware.process(req, res, {
skip: () => middleware.canContinue,
replyHtml: html =>
res.writeHead(200, { "Content-Type": "text/html" }).end(`<!DOCTYPE html>${html}`),
replyError: err => res.writeHead(500, err) && res.end(),
replyNotFound: () => res.writeHead(404, "dev server express Not Found") && res.end(), //res.status(404).send("dev server express Not Found"),
replyStaticData: data => {
res.writeHead(200, { "Content-Type": getType(req.url) });
Readable.from(data).pipe(res);
},
replyFile: file =>
res.writeHead(200, { "Content-Type": getType(file) }) &&
createReadStream(pathResolve(file)).pipe(res)
});

const webpackDevHttpPlugin: RequestListener = function(
req: IncomingMessage,
res: ServerResponse
) {
Object.keys(requestEventHooks).map(eventName => {
req.addListener(eventName, event => requestEventHooks[eventName]({ ...event, ...req }));
});
middleware.process(req, res, {
skip: () => Promise.resolve(),
replyHtml: html => {
res
.writeHead(200, {
"Content-Type": "text/html"
})
.end(`<!DOCTYPE html>${html}`);
},
replyError: err => {
res.writeHead(500, err);
},
replyNotFound: () => res.writeHead(404, "dev server express Not Found"), //res.status(404).send("dev server express Not Found"),
replyStaticData: data => {
const type = require("mime").getType(req.url);
res.writeHead(200, {
"Content-Type": type
});
res.end(data);
},
replyFile: file => createReadStream(resolve(file)).pipe(res)
});
};
const server = createServer(webpackDevHttpPlugin);
if (next1 !== middleware.canContinue) return;

const devFakeRes = new FakeRes();
await middleware.devMiddleware(req, devFakeRes, () => Promise.resolve());
if (devFakeRes.responded) {
devFakeRes.httpRespond(res);
return;
}

middleware.hotMiddleware(req, res, err => {
if (err) {
console.error("webpack hot middleware error", err);
res.writeHead(500, err.message);
}
});
} catch (e) {
console.error("webpack dev middleware error", e);
res.statusCode = 500;
res.end(e.message);
}
});

return {
start: () => server.listen(port, host),
webpackDevHttpPlugin,
addServerEventListener: (event: HttpServerEvent, cb) => {
server.addListener(event.toString(), cb);
},
stop: () => {
server.close(function() {
/* eslint-disable no-console */
console.log("Server closed!");
});
},
addRequestListener: (event: HttpRequestEvent, cb: any) => (requestEventHooks[event] = cb)
addListener: (event: HttpServerEvent, cb) => {
server.addListener(event.toString(), cb);
},
httpServer: server
};
};
export const setup = setupHttpDevServer;
15 changes: 8 additions & 7 deletions packages/xarc-app-dev/src/lib/dev-admin/dev-server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable global-require, no-console */
import { DevHttpServer, setupHttpDevServer } from "./dev-http";
import { setupHttpDevServer } from "./dev-http";
import { createServer } from "http";

const ck = require("chalker");
Expand All @@ -21,19 +21,20 @@ if (process.env.WEBPACK_DEV === undefined) {
}

if (createServer) {
const devHttpServer: DevHttpServer = setupHttpDevServer({
const devHttpServer = setupHttpDevServer({
host: archetype.webpack.devHostname,
port: archetype.webpack.devPort
});
devHttpServer.start();
devHttpServer.addServerEventListener("error", err => {
devHttpServer.addListener("error", err => {
console.error(ck`<red>HTTP webpack dev server having an error</>${err}`);
});
devHttpServer.addServerEventListener("listening", e => {

devHttpServer.addListener("listening", () =>
console.log(
ck`<green>Node.js webpack dev server listening on port ${archetype.webpack.devPort}</>`
);
});
)
);
devHttpServer.start();
} else if (fastifyServer) {
fastifyServer({
electrode: {
Expand Down
7 changes: 7 additions & 0 deletions packages/xarc-app-dev/src/lib/fake-res.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ class FakeRes extends EventEmitter {
res.body = this._content;
return res;
}

httpRespond(res) {
res.writeHeader(this._statusCode, this._headers);
res.statusCode = this._statusCode;
res.end(this._content);
return res;
}
}

module.exports = FakeRes;

0 comments on commit 62aee49

Please sign in to comment.