Skip to content

Instantly share code, notes, and snippets.

@Enalmada
Created October 2, 2018 15:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Enalmada/77b4d4b12655d2a62cd76606d7ee9edc to your computer and use it in GitHub Desktop.
Save Enalmada/77b4d4b12655d2a62cd76606d7ee9edc to your computer and use it in GitHub Desktop.
Next.js http2 push test
const express = require("express");
const next = require("next");
const expressHealthcheck = require("express-healthcheck");
const Sentry = require("@sentry/node");
const fs = require("fs");
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== "production";
const app = next({dev});
const handle = app.getRequestHandler();
const path = require("path");
const helmet = require("helmet");
Sentry.init({
dsn: "<DSN>",
environment: process.env.NODE_ENV || "development",
release: "VERSION_PLACEHOLDER",
});
function linkFile(name, as) {
return `<${name}>; as=${as}; rel=preload`;
}
function getFiles(dir, mapping, as) {
try {
const files_ = [];
const files = fs.readdirSync(dir);
for (const i in files) {
const name = linkFile(`${mapping}${files[i]}`, as);
files_.push(name);
}
return files_;
} catch (err) {
return [];
}
}
const buildId = !dev
? fs.readFileSync("./.next/BUILD_ID", "utf8").toString()
: "";
const createServer = () => {
const server = express();
server.use(helmet());
// Performance desired in this case
server.use(helmet.dnsPrefetchControl({allow: true}));
// Lets not force our summary domain to https
server.use(helmet.hsts({includeSubDomains: false}));
server.use(Sentry.Handlers.requestHandler());
// The error handler must be before any other error middleware
server.use(Sentry.Handlers.errorHandler());
server.use("/health", expressHealthcheck());
server.get("/favicon.ico", (req, res) => {
app.serveStatic(req, res, path.resolve("./static/icons/favicon.ico"));
});
server.get("/service-worker.js", (req, res) => {
// Don't cache sw as a best practice
res.set("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
app.serveStatic(req, res, path.resolve("./.next/service-worker.js"));
});
const robotsOptions = {
root: `${__dirname}/static/`,
headers: {
"Content-Type": "text/plain;charset=UTF-8",
},
};
server.get("/robots.txt", (req, res) => (
res.status(200).sendFile("robots.txt", robotsOptions)
));
server.get("/", (req, res) => {
const allFiles = getFiles("./.next/static/css", "/_next/static/css/", "style")
.concat(getFiles("./.next/static/chunks", "/_next/static/chunks/", "script"))
.concat(getFiles("./.next/static/runtime", "/_next/static/runtime/", "script"));
allFiles.push(linkFile(`/_next/static/${buildId}/pages/_app.js`, "script"));
allFiles.push(linkFile(`/_next/static/${buildId}/pages/_error.js`, "script"));
allFiles.push(linkFile(`/_next/static/${buildId}/pages/index.js`, "script"));
if (allFiles.length > 0) {
res.set("Link", allFiles.toString());
}
handle(req, res);
});
server.get("*", (req, res) => {
handle(req, res);
});
return server;
};
const server = createServer();
if (!process.env.LAMBDA) {
app.prepare()
.then(() => {
server.listen(port, (err) => {
if (err) throw err;
// eslint-disable-next-line
console.log(`> Ready on http://localhost:${port}`);
});
});
}
exports.app = app;
exports.server = server;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment