vite-plugin-react-server
Version:
Vite plugin for React Server Components (RSC)
95 lines (92 loc) • 11.3 kB
JavaScript
/**
* vite-plugin-react-server
* Copyright (c) Nico Brinkkemper
* MIT License
*/
import { join } from 'node:path';
import { createReadStream } from 'node:fs';
import { stat } from 'node:fs/promises';
import { pipeline } from 'node:stream/promises';
import { requestInfo } from '../helpers/requestInfo.js';
import { logError } from '../error/logError.js';
const configurePreviewServer = function _configurePreviewServer({ server, userOptions }) {
const staticHostDir = join(
userOptions.projectRoot,
userOptions.build.outDir,
userOptions.build.static
);
server.middlewares.use(async (req, res, next) => {
if (!req.url) {
return next();
}
const logger = server.config.customLogger || server.config.logger;
const handlerOptions = {
...userOptions,
logger
};
const { contentType, filePath, isRscRequest } = requestInfo(
req,
handlerOptions,
staticHostDir
);
if (filePath && isRscRequest) {
try {
const stats = await stat(filePath);
if (stats.isFile()) {
res.setHeader("Content-Type", contentType);
const controller = new AbortController();
const { signal } = controller;
if (!res.writable) {
res.statusCode = 499;
res.end("Client closed request");
return;
}
try {
const readStream = createReadStream(filePath);
readStream.on("error", () => {
if (!res.writable) {
controller.abort("aborted by preview server");
}
});
await pipeline(readStream, res, { signal });
} catch (error) {
if (error != null && typeof error === "object" && "code" in error) {
const streamError = error;
if (streamError.code === "ERR_STREAM_PREMATURE_CLOSE" || streamError.name === "AbortError") {
if (res.writable) {
res.statusCode = 499;
res.end("Client closed request");
}
} else if (streamError.code === "ENOENT") {
res.statusCode = 404;
logError(streamError, logger);
res.end("File not found");
} else {
logError(streamError, logger);
res.statusCode = 500;
res.end("Internal server error");
}
}
return;
}
return;
}
} catch (error) {
const err = error;
if (err.code === "ENOENT") {
logError(err, logger);
res.statusCode = 404;
res.end("File not found");
} else {
logError(err, logger);
res.statusCode = 500;
res.end("Internal server error");
}
return;
}
}
next();
});
};
export { configurePreviewServer };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlndXJlUHJldmlld1NlcnZlci5qcyIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcGx1Z2luL3JlYWN0LXN0YXRpYy9jb25maWd1cmVQcmV2aWV3U2VydmVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgIFxuICBTdHJlYW1FcnJvciwgIFxufSBmcm9tIFwiLi4vdHlwZXMuanNcIjtcbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBjcmVhdGVSZWFkU3RyZWFtIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCB7IHN0YXQgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgcGlwZWxpbmUgfSBmcm9tIFwibm9kZTpzdHJlYW0vcHJvbWlzZXNcIjtcbmltcG9ydCB7IHJlcXVlc3RJbmZvIH0gZnJvbSBcIi4uL2hlbHBlcnMvcmVxdWVzdEluZm8uanNcIjtcbmltcG9ydCB7IGxvZ0Vycm9yIH0gZnJvbSBcIi4uL2Vycm9yL2xvZ0Vycm9yLmpzXCI7XG5pbXBvcnQgdHlwZSB7IENvbmZpZ3VyZVByZXZpZXdTZXJ2ZXJGbiB9IGZyb20gXCIuL3R5cGVzLmpzXCI7XG5cbmV4cG9ydCBjb25zdCBjb25maWd1cmVQcmV2aWV3U2VydmVyOiBDb25maWd1cmVQcmV2aWV3U2VydmVyRm4gPVxuICBmdW5jdGlvbiBfY29uZmlndXJlUHJldmlld1NlcnZlcih7IHNlcnZlciwgdXNlck9wdGlvbnMgfSkge1xuICAgIGNvbnN0IHN0YXRpY0hvc3REaXIgPSBqb2luKFxuICAgICAgdXNlck9wdGlvbnMucHJvamVjdFJvb3QsXG4gICAgICB1c2VyT3B0aW9ucy5idWlsZC5vdXREaXIsXG4gICAgICB1c2VyT3B0aW9ucy5idWlsZC5zdGF0aWNcbiAgICApO1xuXG4gICAgc2VydmVyLm1pZGRsZXdhcmVzLnVzZShhc3luYyAocmVxLCByZXMsIG5leHQpID0+IHtcbiAgICAgIGlmICghcmVxLnVybCkge1xuICAgICAgICByZXR1cm4gbmV4dCgpO1xuICAgICAgfVxuICAgICAgY29uc3QgbG9nZ2VyID0gc2VydmVyLmNvbmZpZy5jdXN0b21Mb2dnZXIgfHwgc2VydmVyLmNvbmZpZy5sb2dnZXI7XG4gICAgICBjb25zdCBoYW5kbGVyT3B0aW9ucyA9IHtcbiAgICAgICAgLi4udXNlck9wdGlvbnMsXG4gICAgICAgIGxvZ2dlcixcbiAgICAgIH07XG4gICAgICBjb25zdCB7IGNvbnRlbnRUeXBlLCBmaWxlUGF0aCwgaXNSc2NSZXF1ZXN0IH0gPSByZXF1ZXN0SW5mbyhcbiAgICAgICAgcmVxLFxuICAgICAgICBoYW5kbGVyT3B0aW9ucyxcbiAgICAgICAgc3RhdGljSG9zdERpciwgIFxuICAgICAgKTtcbiAgICAgIFxuICAgICAgLy8gSGFuZGxlIHN0YXRpYyBmaWxlcyBpbmNsdWRpbmcgQ1NTXG4gICAgICBpZiAoZmlsZVBhdGggJiYgKGlzUnNjUmVxdWVzdCkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBzdGF0cyA9IGF3YWl0IHN0YXQoZmlsZVBhdGgpO1xuICAgICAgICAgIGlmIChzdGF0cy5pc0ZpbGUoKSkge1xuICAgICAgICAgICAgcmVzLnNldEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBjb250ZW50VHlwZSk7XG5cbiAgICAgICAgICAgIC8vIENyZWF0ZSBhYm9ydCBjb250cm9sbGVyIGZvciB0aGUgc3RyZWFtXG4gICAgICAgICAgICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICAgICAgICAgICAgY29uc3QgeyBzaWduYWwgfSA9IGNvbnRyb2xsZXI7XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHJlc3BvbnNlIGlzIHN0aWxsIHdyaXRhYmxlIGJlZm9yZSBzdHJlYW1pbmdcbiAgICAgICAgICAgIGlmICghcmVzLndyaXRhYmxlKSB7XG4gICAgICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gNDk5O1xuICAgICAgICAgICAgICByZXMuZW5kKFwiQ2xpZW50IGNsb3NlZCByZXF1ZXN0XCIpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlYWRTdHJlYW0gPSBjcmVhdGVSZWFkU3RyZWFtKGZpbGVQYXRoKTtcbiAgICAgICAgICAgICAgcmVhZFN0cmVhbS5vbihcImVycm9yXCIsICgpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIXJlcy53cml0YWJsZSkge1xuICAgICAgICAgICAgICAgICAgY29udHJvbGxlci5hYm9ydChcImFib3J0ZWQgYnkgcHJldmlldyBzZXJ2ZXJcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgYXdhaXQgcGlwZWxpbmUocmVhZFN0cmVhbSwgcmVzLCB7IHNpZ25hbCB9KTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBlcnJvciAhPSBudWxsICYmXG4gICAgICAgICAgICAgICAgdHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICAgICAgXCJjb2RlXCIgaW4gZXJyb3JcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyZWFtRXJyb3IgPSBlcnJvciBhcyBTdHJlYW1FcnJvcjtcbiAgICAgICAgICAgICAgICAvLyBIYW5kbGUgZGlmZmVyZW50IGVycm9yIGNhc2VzXG4gICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgc3RyZWFtRXJyb3IuY29kZSA9PT0gXCJFUlJfU1RSRUFNX1BSRU1BVFVSRV9DTE9TRVwiIHx8XG4gICAgICAgICAgICAgICAgICBzdHJlYW1FcnJvci5uYW1lID09PSBcIkFib3J0RXJyb3JcIlxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgLy8gQ2xpZW50IGNsb3NlZCB0aGUgY29ubmVjdGlvblxuICAgICAgICAgICAgICAgICAgaWYgKHJlcy53cml0YWJsZSkge1xuICAgICAgICAgICAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDQ5OTtcbiAgICAgICAgICAgICAgICAgICAgcmVzLmVuZChcIkNsaWVudCBjbG9zZWQgcmVxdWVzdFwiKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHN0cmVhbUVycm9yLmNvZGUgPT09IFwiRU5PRU5UXCIpIHtcbiAgICAgICAgICAgICAgICAgIC8vIEZpbGUgbm90IGZvdW5kXG4gICAgICAgICAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDQwNDtcbiAgICAgICAgICAgICAgICAgIGxvZ0Vycm9yKHN0cmVhbUVycm9yLCBsb2dnZXIpO1xuXG4gICAgICAgICAgICAgICAgICByZXMuZW5kKFwiRmlsZSBub3QgZm91bmRcIik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIC8vIFNlcnZlciBlcnJvclxuICAgICAgICAgICAgICAgICAgbG9nRXJyb3Ioc3RyZWFtRXJyb3IsIGxvZ2dlcik7XG4gICAgICAgICAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDUwMDtcbiAgICAgICAgICAgICAgICAgIHJlcy5lbmQoXCJJbnRlcm5hbCBzZXJ2ZXIgZXJyb3JcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgY29uc3QgZXJyID0gZXJyb3IgYXMgRXJyb3I7XG4gICAgICAgICAgLy8gSGFuZGxlIGZpbGUgc3lzdGVtIGVycm9yc1xuICAgICAgICAgIGlmICgoZXJyIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSA9PT0gXCJFTk9FTlRcIikge1xuICAgICAgICAgICAgbG9nRXJyb3IoZXJyLCBsb2dnZXIpO1xuICAgICAgICAgICAgcmVzLnN0YXR1c0NvZGUgPSA0MDQ7XG4gICAgICAgICAgICByZXMuZW5kKFwiRmlsZSBub3QgZm91bmRcIik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxvZ0Vycm9yKGVyciwgbG9nZ2VyKTtcbiAgICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gNTAwO1xuICAgICAgICAgICAgcmVzLmVuZChcIkludGVybmFsIHNlcnZlciBlcnJvclwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBuZXh0KCk7XG4gICAgfSk7XG4gIH07XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBV08sTUFBTSx5QkFDWCxTQUFTLHVCQUFBLENBQXdCLEVBQUUsTUFBQSxFQUFRLGFBQWUsRUFBQTtBQUN4RCxFQUFBLE1BQU0sYUFBZ0IsR0FBQSxJQUFBO0FBQUEsSUFDcEIsV0FBWSxDQUFBLFdBQUE7QUFBQSxJQUNaLFlBQVksS0FBTSxDQUFBLE1BQUE7QUFBQSxJQUNsQixZQUFZLEtBQU0sQ0FBQTtBQUFBLEdBQ3BCO0FBRUEsRUFBQSxNQUFBLENBQU8sV0FBWSxDQUFBLEdBQUEsQ0FBSSxPQUFPLEdBQUEsRUFBSyxLQUFLLElBQVMsS0FBQTtBQUMvQyxJQUFJLElBQUEsQ0FBQyxJQUFJLEdBQUssRUFBQTtBQUNaLE1BQUEsT0FBTyxJQUFLLEVBQUE7QUFBQTtBQUVkLElBQUEsTUFBTSxNQUFTLEdBQUEsTUFBQSxDQUFPLE1BQU8sQ0FBQSxZQUFBLElBQWdCLE9BQU8sTUFBTyxDQUFBLE1BQUE7QUFDM0QsSUFBQSxNQUFNLGNBQWlCLEdBQUE7QUFBQSxNQUNyQixHQUFHLFdBQUE7QUFBQSxNQUNIO0FBQUEsS0FDRjtBQUNBLElBQUEsTUFBTSxFQUFFLFdBQUEsRUFBYSxRQUFVLEVBQUEsWUFBQSxFQUFpQixH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