cache stuff
This commit is contained in:
parent
609c793844
commit
98d8b9ef5a
|
|
@ -1,96 +0,0 @@
|
|||
# Build Caching in Nano-Remix
|
||||
|
||||
The nano-remix package now includes intelligent build caching to improve performance by avoiding unnecessary rebuilds.
|
||||
|
||||
## How it Works
|
||||
|
||||
The caching system tracks:
|
||||
|
||||
- File modification timestamps
|
||||
- Last build times
|
||||
- Output file existence
|
||||
|
||||
Routes are only rebuilt when:
|
||||
|
||||
1. Source files have been modified since last build
|
||||
2. Output files don't exist
|
||||
3. Cache is explicitly disabled or forced
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Development Mode (with caching)
|
||||
|
||||
```typescript
|
||||
import { nanoRemix } from "@workshop/nano-remix"
|
||||
|
||||
// Default behavior - uses intelligent caching
|
||||
export default {
|
||||
fetch: (req: Request) => nanoRemix(req),
|
||||
}
|
||||
```
|
||||
|
||||
### Development Mode (without caching)
|
||||
|
||||
```typescript
|
||||
import { nanoRemix } from "@workshop/nano-remix"
|
||||
|
||||
// Disable caching for development if you want immediate rebuilds
|
||||
export default {
|
||||
fetch: (req: Request) =>
|
||||
nanoRemix(req, {
|
||||
disableCache: true,
|
||||
}),
|
||||
}
|
||||
```
|
||||
|
||||
### Production Setup
|
||||
|
||||
```typescript
|
||||
import { nanoRemix, preloadAllRoutes } from "@workshop/nano-remix"
|
||||
|
||||
// Pre-build all routes on startup for production
|
||||
const server = {
|
||||
async fetch(req: Request) {
|
||||
return nanoRemix(req)
|
||||
},
|
||||
}
|
||||
|
||||
// Build all routes once on server startup
|
||||
await preloadAllRoutes()
|
||||
|
||||
export default server
|
||||
```
|
||||
|
||||
### Cache Management
|
||||
|
||||
```typescript
|
||||
import { clearBuildCache, getBuildCacheStats } from "@workshop/nano-remix"
|
||||
|
||||
// Clear cache (useful for development)
|
||||
clearBuildCache()
|
||||
|
||||
// Get cache statistics for monitoring
|
||||
const stats = getBuildCacheStats()
|
||||
console.log("Cache entries:", stats.length)
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
|
||||
```typescript
|
||||
type Options = {
|
||||
routesDir?: string // Custom routes directory
|
||||
distDir?: string // Custom output directory
|
||||
disableCache?: boolean // Disable caching entirely
|
||||
}
|
||||
```
|
||||
|
||||
## Performance Impact
|
||||
|
||||
With caching enabled:
|
||||
|
||||
- ✅ First request to a route: Normal build time
|
||||
- ✅ Subsequent requests: Near-instant response (no rebuild)
|
||||
- ✅ File changes: Automatic rebuild on next request
|
||||
- ✅ Production: Pre-build all routes once
|
||||
|
||||
This should significantly improve your server performance, especially for routes that haven't changed!
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { join, dirname } from "node:path"
|
||||
import { join } from "node:path"
|
||||
|
||||
type BuildRouteOptions = {
|
||||
distDir: string
|
||||
|
|
@ -7,6 +7,7 @@ type BuildRouteOptions = {
|
|||
force?: boolean
|
||||
}
|
||||
|
||||
const cache = new Map<string, boolean>()
|
||||
export const buildRoute = async ({ distDir, routeName, filepath, force = false }: BuildRouteOptions) => {
|
||||
if (!force && !(await needsBuild(routeName, distDir))) {
|
||||
return
|
||||
|
|
@ -25,10 +26,9 @@ export const buildRoute = async ({ distDir, routeName, filepath, force = false }
|
|||
if (exitCode !== 0) {
|
||||
const stderr = await new Response(proc.stderr).text()
|
||||
throw new Error(`Build process failed with exit code ${exitCode}: ${stderr}`)
|
||||
} else {
|
||||
cache.set(distDir + routeName, true)
|
||||
}
|
||||
|
||||
const stdout = await new Response(proc.stdout).text()
|
||||
console.log(stdout)
|
||||
}
|
||||
|
||||
const needsBuild = async (routeName: string, distDir: string) => {
|
||||
|
|
@ -38,8 +38,10 @@ const needsBuild = async (routeName: string, distDir: string) => {
|
|||
|
||||
try {
|
||||
const outputPath = join(distDir, routeName + ".js")
|
||||
const exists = await Bun.file(outputPath).exists()
|
||||
const inCache = cache.get(distDir + routeName)
|
||||
|
||||
return !(await Bun.file(outputPath).exists())
|
||||
return !exists || !inCache
|
||||
} catch (error) {
|
||||
return true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,7 @@ export type Loader<Data extends object> = (
|
|||
) => Promise<Data> | Data
|
||||
export type LoaderProps<T> = T extends Loader<infer R> ? Awaited<R> : never
|
||||
|
||||
export type Action<Data = unknown> = (
|
||||
req: Request,
|
||||
params: Record<string, string>
|
||||
) => Promise<Response | Data>
|
||||
export type Action<Data = unknown> = (req: Request, params: any) => Promise<Response | Data>
|
||||
|
||||
export type Head = {
|
||||
title?: string
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ type Options = {
|
|||
routesDir?: string
|
||||
distDir?: string
|
||||
publicDir?: string
|
||||
disableCache?: boolean
|
||||
}
|
||||
|
||||
let defaultPublicDir: string | undefined
|
||||
|
|
@ -54,7 +53,7 @@ export const nanoRemix = async (req: Request, options: Options = {}) => {
|
|||
|
||||
// If the the route includes an extension it is a static file that we serve from the distDir
|
||||
if (!ext) {
|
||||
await buildRoute({ distDir, routeName, filepath: route.filePath, force: options.disableCache })
|
||||
await buildRoute({ distDir, routeName, filepath: route.filePath })
|
||||
return await renderServer(req, route)
|
||||
} else {
|
||||
const file = Bun.file(join(distDir, routeName + ext))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import KV from "@workshop/shared/kv"
|
||||
import { submitAction, useAction, type Head, type LoaderProps } from "@workshop/nano-remix"
|
||||
import { useCallback } from "hono/jsx/dom"
|
||||
import { TodoEditor } from "@workshop/todo"
|
||||
import { TodoEditor } from "../../todoEditor"
|
||||
import { debounce } from "@workshop/shared/utils"
|
||||
import "../../index.css"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user