Start a production server from `sourcecred start` (#247)
Summary: This commit changes `yarn start` to run a production version of the API server, which serves static files from a pre-built directory and also handles API requests. Test Plan: ```shell $ yarn build $ yarn backend $ node ./bin/sourcecred.js start -d /tmp/srccrd & $ mkdir -p /tmp/srccrd $ echo hello >/tmp/srccrd/world $ curl -s localhost:4000/ | file - /dev/stdin: HTML document, ASCII text, with very long lines, with no line terminators $ curl -s localhost:4000/api/v1/data/world hello ``` wchargin-branch: cli-start-prod-server
This commit is contained in:
parent
ac8d0ff66c
commit
cb1339a0a7
|
@ -2,8 +2,14 @@
|
|||
|
||||
import express from "express";
|
||||
|
||||
export default function apiApp(sourcecredDirectory: string) {
|
||||
export default function apiApp(
|
||||
sourcecredDirectory: string,
|
||||
staticFiles?: string
|
||||
) {
|
||||
const app = express();
|
||||
app.use("/api/v1/data", express.static(sourcecredDirectory));
|
||||
if (staticFiles != null) {
|
||||
app.use(express.static(staticFiles));
|
||||
}
|
||||
return app;
|
||||
}
|
||||
|
|
|
@ -2,11 +2,10 @@
|
|||
|
||||
import {Command} from "@oclif/command";
|
||||
import chalk from "chalk";
|
||||
import child_process from "child_process";
|
||||
import express from "express";
|
||||
import fs from "fs";
|
||||
import {choosePort} from "react-dev-utils/WebpackDevServerUtils";
|
||||
import tmp from "tmp";
|
||||
|
||||
import apiApp from "../../app/apiApp";
|
||||
import {sourcecredDirectoryFlag} from "../common";
|
||||
|
||||
// Makes the script crash on unhandled rejections instead of silently
|
||||
|
@ -35,14 +34,11 @@ export default class StartCommand extends Command {
|
|||
}
|
||||
|
||||
async function startServer(sourcecredDirectory: string) {
|
||||
let server, webpack;
|
||||
let server;
|
||||
function cleanup() {
|
||||
if (server && server.listening) {
|
||||
server.close();
|
||||
}
|
||||
if (webpack) {
|
||||
webpack.kill();
|
||||
}
|
||||
}
|
||||
|
||||
let shuttingDown = false;
|
||||
|
@ -59,10 +55,13 @@ async function startServer(sourcecredDirectory: string) {
|
|||
});
|
||||
});
|
||||
|
||||
const webpackWorkdir = tmp.dirSync({unsafeCleanup: true}).name;
|
||||
const staticFiles = "./build/";
|
||||
if (!fs.existsSync(staticFiles)) {
|
||||
console.error("Build output not found. Did you run `yarn build`?");
|
||||
}
|
||||
|
||||
console.log(chalk.bold("Starting Express..."));
|
||||
const expressApp = createExpressApp(webpackWorkdir, sourcecredDirectory);
|
||||
const expressApp = apiApp(sourcecredDirectory, staticFiles);
|
||||
server = await new Promise(async (resolve, _unused_reject) => {
|
||||
const port = await choosePort(HOST, DEFAULT_PORT);
|
||||
let server = expressApp.listen(port, () => {
|
||||
|
@ -74,44 +73,7 @@ async function startServer(sourcecredDirectory: string) {
|
|||
cleanup();
|
||||
});
|
||||
console.log(
|
||||
chalk.green(`Server listening on port ${server.address().port}. `) +
|
||||
`You might want to wait for Webpack to say ${chalk.bold("[built]")}.`
|
||||
chalk.green(`Server listening on port ${server.address().port}.`)
|
||||
);
|
||||
console.log();
|
||||
|
||||
console.log(chalk.bold("Starting Webpack..."));
|
||||
webpack = startWebpack(webpackWorkdir);
|
||||
webpack.on("exit", (code, signal) => {
|
||||
console.log(
|
||||
`${chalk.bold("Webpack exited")} with ${code} (signal: ${signal})`
|
||||
);
|
||||
cleanup();
|
||||
});
|
||||
}
|
||||
|
||||
function createExpressApp(webpackWorkdir, sourcecredDirectory) {
|
||||
const app = express();
|
||||
app.use(express.static(webpackWorkdir));
|
||||
app.use("/__data__", express.static(sourcecredDirectory));
|
||||
return app;
|
||||
}
|
||||
|
||||
function startWebpack(workdir: string) {
|
||||
const webpack = child_process.spawn(
|
||||
"yarn",
|
||||
[
|
||||
"--silent",
|
||||
"webpack",
|
||||
"--config",
|
||||
"./config/webpack.config.dev.js",
|
||||
"--output-path",
|
||||
workdir,
|
||||
"--watch",
|
||||
],
|
||||
{
|
||||
env: {...process.env, NODE_ENV: "development"},
|
||||
stdio: "inherit",
|
||||
}
|
||||
);
|
||||
return webpack;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue