@jeffersonwilliammachado/vite-express
Version:
160 lines (152 loc) • 6.36 kB
JavaScript
;
var express = require('express');
var fs = require('fs');
var fetch = require('node-fetch');
var path = require('path');
var pc = require('picocolors');
var Vite = require('vite');
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
const { NODE_ENV } = process.env;
const Config = {
mode: (NODE_ENV === "production" ? "production" : "development"),
vitePort: process.env.VITE_PORT || 5173,
viteHost: process.env.VITE_HOST || 'localhost',
viteServerSecure: false,
};
function getViteHost() {
return `${Config.viteServerSecure ? "https" : "http"}://${Config.viteHost}:${Config.vitePort}`;
}
function info(msg) {
const timestamp = new Date().toLocaleString("en-US").split(",")[1].trim();
console.log(`${pc.dim(timestamp)} ${pc.bold(pc.cyan("[vite-express]"))} ${pc.green(msg)}`);
}
function isStaticFilePath(path) {
return path.match(/\.\w+$/);
}
function serveStatic(app) {
return __awaiter(this, void 0, void 0, function* () {
info(`Running in ${pc.yellow(Config.mode)} mode`);
if (Config.mode === "production") {
const config = yield Vite.resolveConfig({}, "build");
const distPath = path.resolve(config.root, config.build.outDir);
app.use(express.static(distPath));
if (!fs.existsSync(distPath)) {
info(`${pc.yellow(`Static files at ${pc.gray(distPath)} not found!`)}`);
yield build();
}
info(`${pc.green(`Serving static files from ${pc.gray(distPath)}`)}`);
}
else {
app.use((req, res, next) => {
if (isStaticFilePath(req.path)) {
fetch(`${getViteHost()}${req.path}`).then((response) => {
if (!response.ok)
return next();
res.redirect(response.url);
});
}
else
next();
});
}
const layer = app._router.stack.pop();
app._router.stack = [
...app._router.stack.slice(0, 2),
layer,
...app._router.stack.slice(2),
];
});
}
function startDevServer() {
return __awaiter(this, void 0, void 0, function* () {
const server = yield Vite.createServer({
clearScreen: false,
server: {
port: Config.vitePort,
host: Config.viteHost
},
}).then((server) => server.listen());
const vitePort = server.config.server.port;
const viteHost = server.config.server.host;
if (vitePort && vitePort !== Config.vitePort)
Config.vitePort = vitePort;
if (viteHost && viteHost !== Config.viteHost)
Config.viteHost = viteHost;
Config.viteServerSecure = Boolean(server.config.server.https);
info(`Vite is listening ${pc.gray(getViteHost())}`);
return server;
});
}
function serveHTML(app) {
return __awaiter(this, void 0, void 0, function* () {
if (Config.mode === "production") {
const config = yield Vite.resolveConfig({}, "build");
const distPath = path.resolve(config.root, config.build.outDir);
app.use("*", (_, res) => {
res.sendFile(path.resolve(distPath, "index.html"));
});
}
else {
app.get("/*", (req, res, next) => __awaiter(this, void 0, void 0, function* () {
if (isStaticFilePath(req.path))
return next();
fetch(getViteHost())
.then((res) => res.text())
.then((content) => content.replace(/(\/@react-refresh|\/@vite\/client)/g, `${getViteHost()}$1`))
.then((content) => res.header("Content-Type", "text/html").send(content));
}));
}
});
}
function config(config) {
if (config.mode)
Config.mode = config.mode;
if (config.vitePort)
Config.vitePort = config.vitePort;
if (config.viteHost)
Config.viteHost = config.viteHost;
}
function bind(app, server, callback) {
return __awaiter(this, void 0, void 0, function* () {
if (Config.mode === "development") {
const devServer = yield startDevServer();
server.on("close", () => devServer === null || devServer === void 0 ? void 0 : devServer.close());
}
yield serveStatic(app);
yield serveHTML(app);
callback === null || callback === void 0 ? void 0 : callback();
});
}
function listen(app, port, callback) {
const server = app.listen(port, () => bind(app, server, callback));
return server;
}
function build() {
return __awaiter(this, void 0, void 0, function* () {
info("Build starting...");
yield Vite.build();
info("Build completed!");
});
}
var main = { config, bind, listen, build };
module.exports = main;