Skip to content

Instantly share code, notes, and snippets.

@lazypanda-instance
Created March 2, 2024 18:15
Show Gist options
  • Save lazypanda-instance/04e426b8c550013710c65917022ba3d1 to your computer and use it in GitHub Desktop.
Save lazypanda-instance/04e426b8c550013710c65917022ba3d1 to your computer and use it in GitHub Desktop.
Angular v17 server.ts file for SSR and Prerender support.
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-extra-semi */
/* eslint-disable @typescript-eslint/no-var-requires */
import "zone.js/node";
import { ngExpressEngine } from "@nguniversal/express-engine";
import * as express from "express";
import { join } from "path";
import { AppServerModule } from "./src/main.server";
import { APP_BASE_HREF } from "@angular/common";
import { existsSync } from "fs";
import { getWindow, getDocument } from "ssr-window";
(global as any).window = getWindow();
(global as any).document = getDocument();
(global as any).navigator = {
language: "en",
};
// const domino = require("domino");
// const fs = require("fs");
// const path = require("path");
// const template = fs
// .readFileSync(path.join(".", "dist/blog-fe/browser", "index.html"))
// .toString();
// const win = domino.createWindow(template);
// global["window"] = win;
// global["document"] = win.document;
// global["DOMTokenList"] = win.DOMTokenList;
// global["Node"] = win.Node;
// global["Text"] = win.Text;
// global["HTMLElement"] = win.HTMLElement;
// global["navigator"] = win.navigator;
// global["MutationObserver"] = getMockMutationObserver();
// global["requestAnimationFrame"] = function (callback) {
// let lastTime = 0;
// const currTime = new Date().getTime();
// const timeToCall = Math.max(0, 16 - (currTime - lastTime));
// const id = window.setTimeout(function () {
// callback(currTime + timeToCall);
// }, timeToCall);
// lastTime = currTime + timeToCall;
// return id;
// };
// global["cancelAnimationFrame"] = function (id) {
// clearTimeout(id);
// };
// function getMockMutationObserver() {
// return class {
// observe(node, options) {}
// disconnect() {}
// takeRecords() {
// return [];
// }
// };
// }
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), "dist/blog-fe/browser");
const indexHtml = existsSync(join(distFolder, "index.original.html"))
? "index.original.html"
: "index";
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine(
"html",
ngExpressEngine({
bootstrap: AppServerModule,
})
);
server.set("view engine", "html");
server.set("views", distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get(
"*.*",
express.static(distFolder, {
maxAge: "1y",
}) as any
);
server.use(function (req, res, next) {
(req as any).start = Date.now();
next();
});
// All regular routes use the Universal engine
server.get("*", (req, res) => {
console.log(
"# render via universal engine, url: " + req.headers.host + req.url
);
res.render(indexHtml, {
req,
providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }],
});
});
server.use(function (req) {
const time = Date.now() - (req as any).start;
console.log("time: " + time);
});
return server;
}
function run(): void {
const port = process.env.PORT || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = (mainModule && mainModule.filename) || "";
if (moduleFilename === __filename || moduleFilename.includes("iisnode")) {
run();
}
export * from "./src/main.server";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment