Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions app/root.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { cssBundleHref } from "@remix-run/css-bundle";
import type { LinksFunction } from "@remix-run/node";
import {
Links,
Expand All @@ -8,12 +7,9 @@ import {
Scripts,
ScrollRestoration,
} from "@remix-run/react";
import styles from "./tailwind.css";

export const links: LinksFunction = () => [
...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []),
{ rel: "stylesheet", href: styles },
];
//css should be imported as a side effect for vite
import "./tailwind.css";

export default function App() {
return (
Expand All @@ -27,8 +23,8 @@ export default function App() {
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
<LiveReload />
<Scripts />
</body>
</html>
);
Expand Down
2 changes: 1 addition & 1 deletion remix.env.d.ts → env.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/// <reference types="@remix-run/dev" />
/// <reference types="@remix-run/node" />
/// <reference types="vite/client" />
27 changes: 13 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,16 @@
"type": "module",
"scripts": {
"build": "run-p build:*",
"build:remix": "remix build",
"build:remix": "vite build && vite build --ssr",
"build:server": "esbuild --platform=node --format=esm ./server.ts --outdir=./",
"dev": "remix dev -c \"npm run dev:server\" --manual",
"dev:server": "tsx watch --clear-screen=false --ignore 'app/**' --ignore 'build/**' --ignore 'node_modules/**' --inspect ./server.ts",
"start": "cross-env NODE_ENV=production node server.js",
"dev": "node --loader ts-node/esm --watch-path ./server.ts --watch ./server.ts",
"start": "cross-env NODE_ENV=production node server.js",
"typecheck": "tsc"
},
"dependencies": {
"@remix-run/css-bundle": "*",
"@remix-run/express": "*",
"@remix-run/node": "*",
"@remix-run/react": "*",
"@remix-run/express": "^2.2.0",
"@remix-run/node": "^2.2.0",
"@remix-run/react": "^2.2.0",
"compression": "^1.7.4",
"cross-env": "^7.0.3",
"express": "^4.18.2",
Expand All @@ -26,23 +24,24 @@
"source-map-support": "^0.5.21"
},
"devDependencies": {
"@remix-run/dev": "*",
"@remix-run/eslint-config": "*",
"@remix-run/dev": "^2.2.0",
"@remix-run/eslint-config": "^2.2.0",
"@swc/core": "1.3.82",
"@types/compression": "^1.7.2",
"@types/express": "^4.17.17",
"@types/morgan": "^1.9.4",
"@types/react": "^18.0.35",
"@types/react-dom": "^18.0.11",
"@types/source-map-support": "^0.5.6",
"autoprefixer": "^10.4.16",
"chokidar": "^3.5.3",
"esbuild": "^0.19.4",
"eslint": "^8.38.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.3",
"tsx": "^3.14.0",
"typescript": "^5.0.4"
"ts-node": "^10.9.1",
"typescript": "^5.0.4",
"vite": "^4.5.0",
"vite-tsconfig-paths": "^4.2.1"
},
"engines": {
"node": ">=18"
Expand Down
1 change: 1 addition & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
11 changes: 0 additions & 11 deletions remix.config.js

This file was deleted.

119 changes: 32 additions & 87 deletions server.ts
Original file line number Diff line number Diff line change
@@ -1,113 +1,58 @@
import * as fs from "node:fs";
import express from "express";
import compression from "compression";
import morgan from "morgan";
import { createRequestHandler, type RequestHandler } from "@remix-run/express";
import { broadcastDevReady, installGlobals } from "@remix-run/node";
import sourceMapSupport from "source-map-support";

import {
unstable_createViteServer,
unstable_loadViteServerBuild,
} from "@remix-run/dev";
import { createRequestHandler } from "@remix-run/express";
import { installGlobals } from "@remix-run/node";

// patch in Remix runtime globals
installGlobals();
sourceMapSupport.install();

/**
* @typedef {import('@remix-run/node').ServerBuild} ServerBuild
*/
const BUILD_PATH = "./build/index.js";
const WATCH_PATH = "./build/version.txt";

/**
* Initial build
* @type {ServerBuild}
*/
let build = await import(BUILD_PATH);

// We'll make chokidar a dev dependency so it doesn't get bundled in production.
const chokidar =
process.env.NODE_ENV === "development" ? await import("chokidar") : null;

const app = express();

// handle asset requests
let vite =
process.env.NODE_ENV === "production"
? undefined
: await unstable_createViteServer();

if (vite) {
app.use(vite.middlewares);
} else {
app.use(
"/build",
express.static("public/build", { immutable: true, maxAge: "1y" })
);
}

app.use(compression());

// http://expressjs.com/en/advanced/best-practice-security.html#at-a-minimum-disable-x-powered-by-header
app.disable("x-powered-by");

// Remix fingerprints its assets so we can cache forever.
app.use(
"/build",
express.static("public/build", { immutable: true, maxAge: "1y" })
);

// Everything else (like favicon.ico) is cached for an hour. You may want to be
// more aggressive with this caching.
app.use(express.static("public", { maxAge: "1h" }));

app.use(morgan("tiny"));

// Check if the server is running in development mode and use the devBuild to reflect realtime changes in the codebase.
// handle SSR requests
app.all(
"*",
process.env.NODE_ENV === "development"
? createDevRequestHandler()
: createRequestHandler({
build,
mode: process.env.NODE_ENV,
})
createRequestHandler({
build: vite
? () => unstable_loadViteServerBuild(vite)
: await import("./build/index.js"),
})
);

const port = process.env.PORT || 3000;

app.listen(port, async () => {
console.log(`Express server listening on port ${port}`);

// send "ready" message to dev server
if (process.env.NODE_ENV === "development") {
await broadcastDevReady(build);
}
});

// Create a request handler that watches for changes to the server build during development.
function createDevRequestHandler(): RequestHandler {
async function handleServerUpdate() {
// 1. re-import the server build
build = await reimportServer();

// Add debugger to assist in v2 dev debugging
if (build?.assets === undefined) {
console.log(build.assets);
debugger;
}

// 2. tell dev server that this app server is now up-to-date and ready
await broadcastDevReady(build);
}

chokidar
?.watch(WATCH_PATH, { ignoreInitial: true })
.on("add", handleServerUpdate)
.on("change", handleServerUpdate);

// wrap request handler to make sure its recreated with the latest build for every request
return async (req, res, next) => {
try {
return createRequestHandler({
build,
mode: "development",
})(req, res, next);
} catch (error) {
next(error);
}
};
}

// ESM import cache busting
/**
* @type {() => Promise<ServerBuild>}
*/
async function reimportServer() {
const stat = fs.statSync(BUILD_PATH);

// use a timestamp query parameter to bust the import cache
return import(BUILD_PATH + "?t=" + stat.mtimeMs);
}
const port = 3000;
app.listen(port, () =>
console.log("Express server listening on http://localhost:" + port)
);
5 changes: 4 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
"include": ["env.d.ts", "**/*.ts", "**/*.tsx"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"isolatedModules": true,
Expand All @@ -22,5 +22,8 @@

// Remix takes care of building everything in `remix build`.
"noEmit": true
},
"ts-node": {
"swc": true
}
}
21 changes: 21 additions & 0 deletions vite.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { unstable_vitePlugin as remix } from "@remix-run/dev";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
optimizeDeps: {
include: ["react", "react-dom/client"],
},
plugins: [
remix({
ignoredRouteFiles: ["**/.*"],
tailwind: true,
postcss: true,
// appDirectory: "app",
// assetsBuildDirectory: "public/build",
// publicPath: "/build/",
// serverBuildPath: "build/index.js",
}),
tsconfigPaths(),
],
});