Skip to content

Commit

Permalink
feat: add react router entry point
Browse files Browse the repository at this point in the history
Signed-off-by: Logan McAnsh <logan@mcan.sh>
  • Loading branch information
mcansh committed Nov 16, 2024
1 parent fba6aca commit b3a722f
Show file tree
Hide file tree
Showing 24 changed files with 481 additions and 165 deletions.
4 changes: 2 additions & 2 deletions examples/playground/server.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from "chalk";
import { remixFastify } from "@mcansh/remix-fastify";
import { reactRouterFastify } from "@mcansh/remix-fastify/react-router";
import { installGlobals } from "@remix-run/node";
import { fastify } from "fastify";
import sourceMapSupport from "source-map-support";
Expand All @@ -14,7 +14,7 @@ app.post("/api/echo", async (request, reply) => {
reply.send(request.body);
});

await app.register(remixFastify, {
await app.register(reactRouterFastify, {
getLoadContext(request, reply) {
return { loadContextName: "Logan" };
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// vite.config.ts
import { vitePlugin as remix } from "file:///Users/lmcansh/remix-fastify/node_modules/.pnpm/@remix-run+dev@2.10.0_@remix-run+react@2.14.0_react-dom@19.0.0-rc-100dfd7dab-20240701_react@1_fdtw53wollluzaehojg7fjacfe/node_modules/@remix-run/dev/dist/index.js";
import { defineConfig } from "file:///Users/lmcansh/remix-fastify/node_modules/.pnpm/vite@5.4.9_@types+node@22.7.7_lightningcss@1.26.0/node_modules/vite/dist/node/index.js";
import tsconfigPaths from "file:///Users/lmcansh/remix-fastify/node_modules/.pnpm/vite-tsconfig-paths@5.0.1_typescript@5.6.3_vite@5.4.9_@types+node@22.7.7_lightningcss@1.26.0_/node_modules/vite-tsconfig-paths/dist/index.js";
import tailwindcss from "file:///Users/lmcansh/remix-fastify/node_modules/.pnpm/@tailwindcss+vite@4.0.0-alpha.28_vite@5.4.9_@types+node@22.7.7_lightningcss@1.26.0_/node_modules/@tailwindcss/vite/dist/index.mjs";
var vite_config_default = defineConfig({
plugins: [remix(), tsconfigPaths(), tailwindcss()]
});
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvVXNlcnMvbG1jYW5zaC9yZW1peC1mYXN0aWZ5L2V4YW1wbGVzL3BsYXlncm91bmRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIi9Vc2Vycy9sbWNhbnNoL3JlbWl4LWZhc3RpZnkvZXhhbXBsZXMvcGxheWdyb3VuZC92aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vVXNlcnMvbG1jYW5zaC9yZW1peC1mYXN0aWZ5L2V4YW1wbGVzL3BsYXlncm91bmQvdml0ZS5jb25maWcudHNcIjtpbXBvcnQgeyB2aXRlUGx1Z2luIGFzIHJlbWl4IH0gZnJvbSBcIkByZW1peC1ydW4vZGV2XCI7XG5pbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tIFwidml0ZVwiO1xuaW1wb3J0IHRzY29uZmlnUGF0aHMgZnJvbSBcInZpdGUtdHNjb25maWctcGF0aHNcIjtcbmltcG9ydCB0YWlsd2luZGNzcyBmcm9tIFwiQHRhaWx3aW5kY3NzL3ZpdGVcIjtcblxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAgcGx1Z2luczogW3JlbWl4KCksIHRzY29uZmlnUGF0aHMoKSwgdGFpbHdpbmRjc3MoKV0sXG59KTtcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBa1UsU0FBUyxjQUFjLGFBQWE7QUFDdFcsU0FBUyxvQkFBb0I7QUFDN0IsT0FBTyxtQkFBbUI7QUFDMUIsT0FBTyxpQkFBaUI7QUFFeEIsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDMUIsU0FBUyxDQUFDLE1BQU0sR0FBRyxjQUFjLEdBQUcsWUFBWSxDQUFDO0FBQ25ELENBQUM7IiwKICAibmFtZXMiOiBbXQp9Cg==
6 changes: 2 additions & 4 deletions examples/react-router/server.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import chalk from "chalk";
import { remixFastify } from "@mcansh/remix-fastify";
import { reactRouterFastify } from "@mcansh/remix-fastify/react-router";
import { fastify } from "fastify";
import sourceMapSupport from "source-map-support";
import getPort, { portNumbers } from "get-port";
Expand All @@ -8,9 +8,7 @@ sourceMapSupport.install();

let app = fastify();

await app.register(remixFastify, {
virtualModule: "virtual:react-router/server-build",
});
await app.register(reactRouterFastify);

const desiredPort = Number(process.env.PORT) || 3000;
const portToUse = await getPort({
Expand Down
27 changes: 23 additions & 4 deletions packages/remix-fastify/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@mcansh/remix-fastify",
"version": "4.0.1",
"description": "Fastify server request handler for Remix",
"description": "Fastify server request handler for Remix and React Router",
"repository": "mcansh/remix-fastify",
"license": "MIT",
"author": "Logan McAnsh <logan@mcan.sh> (https://mcan.sh)",
Expand All @@ -11,6 +11,7 @@
"keywords": [
"remix",
"remix-run",
"react-router",
"fastify"
],
"funding": [
Expand All @@ -25,6 +26,14 @@
".": {
"require": "./dist/index.cjs",
"import": "./dist/index.js"
},
"./react-router": {
"require": "./dist/react-router.cjs",
"import": "./dist/react-router.js"
},
"./remix": {
"require": "./dist/remix.cjs",
"import": "./dist/remix.js"
}
},
"main": "./dist/index.cjs",
Expand All @@ -35,10 +44,18 @@
"dist",
"package.json",
"README.md",
"LICENSE"
"LICENSE",
"react-router.cjs",
"react-router.d.cts",
"react-router.d.ts",
"react-router.js",
"remix.cjs",
"remix.d.cts",
"remix.d.ts",
"remix.js"
],
"scripts": {
"prepublishOnly": "npm run build && cp ../../LICENSE LICENSE && publint && attw $(npm pack)",
"prepublishOnly": "npm run build && cp ../../LICENSE LICENSE && publint && attw --pack",
"typecheck": "tsc",
"dev": "tsup --watch",
"build": "tsup",
Expand All @@ -52,18 +69,20 @@
"pretty-cache-header": "^1.0.0"
},
"devDependencies": {
"@react-router/node": "7.0.0-pre.5",
"@remix-run/node": "^2.13.1",
"@types/node": "^22.7.7",
"@typescript/lib-dom": "npm:@types/web@^0.0.174",
"fastify": "^5.0.0",
"node-mocks-http": "^1.16.1",
"react-router": "^7.0.0-pre.5",
"typescript": "^5.6.3",
"vite": "^5.4.9"
},
"peerDependencies": {
"@remix-run/node": "^2.0.0",
"fastify": "^3.29.0 || ^4.0.0 || ^5.0.0",
"react-router": "*",
"react-router": ">=7.0.0 || >=7.0.0.pre",
"vite": "^5.0.0"
},
"peerDependenciesMeta": {
Expand Down
1 change: 1 addition & 0 deletions packages/remix-fastify/react-router.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("./dist/react-router");
1 change: 1 addition & 0 deletions packages/remix-fastify/react-router.d.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type * from "./dist/react-router";
1 change: 1 addition & 0 deletions packages/remix-fastify/react-router.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type * from "./dist/react-router";
1 change: 1 addition & 0 deletions packages/remix-fastify/react-router.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./dist/react-router";
1 change: 1 addition & 0 deletions packages/remix-fastify/remix.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("./dist/remix");
1 change: 1 addition & 0 deletions packages/remix-fastify/remix.d.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type * from "./dist/remix";
1 change: 1 addition & 0 deletions packages/remix-fastify/remix.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type * from "./dist/remix";
1 change: 1 addition & 0 deletions packages/remix-fastify/remix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./dist/remix";
10 changes: 6 additions & 4 deletions packages/remix-fastify/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export type { GetLoadContextFunction, RequestHandler } from "./server";
export { createRequestHandler } from "./server";
export { remixFastify } from "./plugin";
export type { RemixFastifyOptions } from "./plugin";
export type {
GetLoadContextFunction,
RequestHandler,
RemixFastifyOptions,
} from "./remix";
export { createRequestHandler, remixFastify } from "./remix";
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import type { FastifyInstance } from "fastify";

import path from "node:path";
import url from "node:url";
import fp from "fastify-plugin";
import type { InlineConfig, ViteDevServer } from "vite";
import fastifyStatic, { type FastifyStaticOptions } from "@fastify/static";
import { cacheHeader } from "pretty-cache-header";
import type { ServerBuild } from "@remix-run/node";

import { createRequestHandler } from "./server";
import type { HttpServer, GetLoadContextFunction } from "./server";
import type { GetLoadContextFunction, HttpServer } from "../shared";
import type { CreateRequestHandlerFunction as RRCreateRequestHandlerFunction } from "../servers/react-router";
import type { CreateRequestHandlerFunction as RemixCreateRequestHandlerFunction } from "../servers/remix";

export type RemixFastifyOptions<Server extends HttpServer = HttpServer> = {
export type PluginOptions<
Server extends HttpServer = HttpServer,
AppLoadContext = unknown,
ServerBuild = unknown,
> = {
/**
* The base path for the Remix app.
* match the `basename` in your Vite config.
Expand All @@ -35,7 +39,7 @@ export type RemixFastifyOptions<Server extends HttpServer = HttpServer> = {
* You can think of this as an escape hatch that allows you to pass
* environment/platform-specific values through to your loader/action.
*/
getLoadContext?: GetLoadContextFunction<Server>;
getLoadContext: GetLoadContextFunction<Server, AppLoadContext>;
mode?: string;
/**
* Options to pass to the Vite server in development.
Expand Down Expand Up @@ -67,28 +71,40 @@ export type RemixFastifyOptions<Server extends HttpServer = HttpServer> = {
productionServerBuild?:
| ServerBuild
| (() => ServerBuild | Promise<ServerBuild>);
virtualModule?:

/**
* The virtual module to load in development.
*/
virtualModule:
| "virtual:remix/server-build"
| "virtual:react-router/server-build";
};

export const remixFastify = fp<RemixFastifyOptions>(
async (
fastify,
{
basename = "/",
buildDirectory = "build",
serverBuildFile = "index.js",
getLoadContext,
mode = process.env.NODE_ENV,
viteOptions,
fastifyStaticOptions,
assetCacheControl = { public: true, maxAge: "1 year", immutable: true },
defaultCacheControl = { public: true, maxAge: "1 hour" },
productionServerBuild,
virtualModule = "virtual:remix/server-build",
},
) => {
export function createPlugin(
fastify: FastifyInstance,
{
basename = "/",
buildDirectory = "build",
serverBuildFile = "index.js",
getLoadContext,
mode = process.env.NODE_ENV,
viteOptions,
fastifyStaticOptions,
assetCacheControl = { public: true, maxAge: "1 year", immutable: true },
defaultCacheControl = { public: true, maxAge: "1 hour" },
productionServerBuild,
virtualModule,
}: PluginOptions,
// TODO: look if importing the function as a type requires the peer dependency
createRequestHandler:
| RemixCreateRequestHandlerFunction
| RRCreateRequestHandlerFunction,
) {
console.log(`inside createPlugin`);

return async () => {
console.log(`inside createPlugin async`);

let cwd = process.env.REMIX_ROOT ?? process.cwd();

let vite: ViteDevServer | undefined;
Expand All @@ -113,9 +129,11 @@ export const remixFastify = fp<RemixFastifyOptions>(
);
let SERVER_BUILD_URL = url.pathToFileURL(SERVER_BUILD).href;

let remixHandler = createRequestHandler<HttpServer>({
let handler = createRequestHandler<HttpServer>({
mode,
// @ts-expect-error - fix this
getLoadContext,
// @ts-expect-error - fix this
build: vite
? () => vite.ssrLoadModule(virtualModule)
: (productionServerBuild ?? (() => import(SERVER_BUILD_URL))),
Expand All @@ -139,6 +157,7 @@ export const remixFastify = fp<RemixFastifyOptions>(
serveDotFiles: true,
lastModified: true,
setHeaders(res, filepath) {
console.log({ filepath });
let isAsset = filepath.startsWith(ASSET_DIR);
res.setHeader(
"cache-control",
Expand All @@ -161,15 +180,10 @@ export const remixFastify = fp<RemixFastifyOptions>(
});

childServer.all("*", (request, reply) => {
remixHandler(request, reply);
handler(request, reply);
});
},
{ prefix: basename },
);
},
{
// replaced with the package name during build
name: process.env.__PACKAGE_NAME__,
fastify: process.env.__FASTIFY_VERSION__,
},
);
};
}
30 changes: 30 additions & 0 deletions packages/remix-fastify/src/plugins/react-router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import fp from "fastify-plugin";

import type { HttpServer } from "../shared";
import type { AppLoadContext, ServerBuild } from "react-router";
import { createRequestHandler } from "../servers/react-router";
import { createPlugin, type PluginOptions } from ".";

export type ReactRouterFastifyOptions = Omit<
PluginOptions<HttpServer, AppLoadContext, ServerBuild>,
"virtualModule"
>;

export const reactRouterFastify = fp<ReactRouterFastifyOptions>(
async (fastify, options) => {
let plugin = createPlugin(
fastify,
{
...options,
virtualModule: "virtual:react-router/server-build",
},
createRequestHandler,
);
return plugin();
},
{
// replaced with the package name during build
name: process.env.__PACKAGE_NAME__,
fastify: process.env.__FASTIFY_VERSION__,
},
);
30 changes: 30 additions & 0 deletions packages/remix-fastify/src/plugins/remix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import fp from "fastify-plugin";
import type { AppLoadContext, ServerBuild } from "@remix-run/node";

import { createRequestHandler } from "../servers/remix";
import type { HttpServer } from "../shared";
import { createPlugin, type PluginOptions } from ".";

export type RemixFastifyOptions = Omit<
PluginOptions<HttpServer, AppLoadContext, ServerBuild>,
"virtualModule"
>;

export const remixFastify = fp<RemixFastifyOptions>(
async (fastify, options) => {
let plugin = createPlugin(
fastify,
{
...options,
virtualModule: "virtual:remix/server-build",
},
createRequestHandler,
);
return plugin();
},
{
// replaced with the package name during build
name: process.env.__PACKAGE_NAME__,
fastify: process.env.__FASTIFY_VERSION__,
},
);
12 changes: 12 additions & 0 deletions packages/remix-fastify/src/react-router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { AppLoadContext } from "react-router";
import type {
HttpServer,
GetLoadContextFunction as SharedGetLoadContextFunction,
} from "./shared";
export type { RequestHandler } from "./shared";
export { createRequestHandler } from "./servers/react-router";
export { reactRouterFastify } from "./plugins/react-router";
export type { ReactRouterFastifyOptions } from "./plugins/react-router";

export type GetLoadContextFunction<Server extends HttpServer> =
SharedGetLoadContextFunction<Server, AppLoadContext>;
12 changes: 12 additions & 0 deletions packages/remix-fastify/src/remix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { AppLoadContext } from "@remix-run/node";
import type {
HttpServer,
GetLoadContextFunction as SharedGetLoadContextFunction,
} from "./shared";
export type { RequestHandler } from "./shared";
export { createRequestHandler } from "./servers/remix";
export { remixFastify } from "./plugins/remix";
export type { RemixFastifyOptions } from "./plugins/remix";

export type GetLoadContextFunction<Server extends HttpServer> =
SharedGetLoadContextFunction<Server, AppLoadContext>;
Loading

0 comments on commit b3a722f

Please sign in to comment.