UNPKG

5.6 kBPlain TextView Raw
1import debug = require("debug");
2import express = require("express");
3import expressSession = require("express-session");
4import { createServer } from "http";
5import { RemoteMessageType, REQUIRE_FUNC_NAME } from "neweb-core";
6import { ModulePacker } from "neweb-pack";
7import { ServerPageRenderer } from "neweb-react/server";
8import { Application, SeancesManager, Server } from "neweb-server";
9import { join, resolve } from "path";
10import SessionFileStore = require("session-file-store");
11import SocketIO = require("socket.io");
12import ExpressHttpHandler from "./ExpressHttpHandler";
13import ModuleServer from "./ModulesServer";
14import NewebServerPageRenderer from "./neweb-components/server/PageRenderer";
15import SessionsManager from "./SessionsManager";
16import SocketIOClient from "./SocketIOClient";
17export interface IServerBootstrapConfig {
18 rootPath: string;
19 port: number;
20 env: "production" | "development";
21 expressApp?: express.Express;
22 engine?: "react" | "neweb";
23}
24class ServerBootstrap {
25 protected engine: "react" | "neweb" = "neweb";
26 constructor(protected config: IServerBootstrapConfig) {
27 this.engine = this.config.engine || "neweb";
28 }
29 public async start() {
30 const rootPath = this.config.rootPath;
31 const port = this.config.port;
32 const env = this.config.env;
33 // settings
34 const appPath = resolve(join(rootPath, "app"));
35 const modulesPath = join(appPath, "..", "modules");
36 const sessionsPath = join(appPath, "..", "sessions");
37 // logs
38 if (env === "development") {
39 debug.enable("*,-engine:*,-engine,-socket.io-parser,-socket.io:*");
40 }
41 const expressApp = this.config.expressApp ? this.config.expressApp : express();
42 // neweb-pack
43 const modulePacker = new ModulePacker({
44 appRoot: appPath,
45 excludedModules: ["react", "react-dom", "neweb", "neweb-components"],
46 modulesPath,
47 REQUIRE_FUNC_NAME,
48 disableCacheForLocalModules: env === "development",
49 webpackConfig: {
50 module: {
51 rules: [{
52 test: /\.html$/,
53 use: [{
54 loader: require.resolve("html-loader"),
55 options: {
56 minimize: true,
57 },
58 }],
59 }],
60 },
61 },
62 });
63 // create app
64 const app = new Application({
65 appDir: appPath,
66 env,
67 modulePacker,
68 });
69 await app.init();
70
71 const appConfig = await app.getConfig();
72
73 const sessionsFileStore = SessionFileStore(expressSession);
74 const sessionsStorage = new sessionsFileStore({
75 path: sessionsPath,
76 retries: 1,
77 ttl: appConfig.session.ttl || 86400 * 100000,
78 });
79 const session = expressSession({
80 secret: appConfig.session.secret,
81 saveUninitialized: true,
82 resave: true,
83 store: sessionsStorage,
84 });
85
86 // static
87 expressApp.use(express.static(resolve(join(appPath, "public"))));
88 expressApp.get("/bundle." + env + ".js", (_, res) =>
89 res.sendFile(resolve(join(__dirname, "..", "dist", "bundle." + env + "." + this.engine + ".js"))));
90
91 const sessionsManager = new SessionsManager({
92 sessionsPath,
93 sessionsStorage,
94 });
95 const seancesManager = new SeancesManager({
96 app,
97 sessionsManager,
98 });
99 // neweb
100 const pageRenderer = this.engine === "react" ? new ServerPageRenderer({
101 app,
102 }) : new NewebServerPageRenderer({
103 app,
104 });
105 const server = new Server({
106 app,
107 seancesManager,
108 pageRenderer,
109 });
110 const modulesServer = new ModuleServer({
111 modulesPath,
112 });
113 expressApp.get("/modules/:type/:name/:version.js", modulesServer.handle);
114
115 const expressHandler = new ExpressHttpHandler({
116 app: expressApp,
117 server,
118 });
119 expressApp.use(session, expressHandler.handle);
120
121 const httpServer = createServer(expressApp);
122 // Setup SocketIO
123 const io = SocketIO();
124 io.use((socket, next) => {
125 session(socket.request, socket.request.res, next);
126 });
127 io.on("connection", (socket) => {
128 socket.on(RemoteMessageType.Initialize, async ({ seanceId }: { seanceId: string }) => {
129 const socketClient = new SocketIOClient({
130 socket,
131 seanceId,
132 });
133 const request = await socketClient.getRequest();
134 server.connectClient({
135 seanceId,
136 client: socketClient,
137 request,
138 });
139 });
140 });
141 io.attach(httpServer);
142 // Start listening
143 httpServer.listen(port, (err: any) => {
144 if (err) {
145 debug("http")("Error server starting", err);
146 process.exit(1);
147 return;
148 }
149 debug("http")("Http server at port ", port);
150 });
151 }
152}
153export default ServerBootstrap;