0
# Cache Management
1
2
Node.js module cache management for hot module reloading and development workflows. Provides utilities to clear specific files from Node.js require cache and ESM module cache busting for development environments.
3
4
## Capabilities
5
6
### Clear Require Cache Function
7
8
Clears specific files from the Node.js require cache for hot module reloading.
9
10
```typescript { .api }
11
/**
12
* Clears specific files from Node.js require cache
13
* Useful for hot module reloading in development environments
14
* @param files - Array of absolute file paths to remove from cache
15
*/
16
function clearRequireCache(files: string[]): void;
17
```
18
19
**Usage Examples:**
20
21
```typescript
22
import { clearRequireCache } from "@tailwindcss/node/require-cache";
23
24
// Clear specific files from cache
25
const filesToClear = [
26
"/path/to/project/src/config.js",
27
"/path/to/project/src/utils.js"
28
];
29
30
clearRequireCache(filesToClear);
31
32
// Now requiring these files will reload them from disk
33
const config = require("/path/to/project/src/config.js"); // Fresh load
34
```
35
36
### Hot Module Reloading Setup
37
38
Integration with file watchers for automatic cache clearing:
39
40
```typescript
41
import { clearRequireCache } from "@tailwindcss/node/require-cache";
42
import { watch } from "chokidar";
43
import path from "path";
44
45
// Set up hot module reloading for a project
46
function setupHMR(watchPaths: string[]) {
47
const watcher = watch(watchPaths, {
48
ignoreInitial: true
49
});
50
51
watcher.on('change', (changedFile) => {
52
const absolutePath = path.resolve(changedFile);
53
54
console.log(`File changed: ${absolutePath}`);
55
56
// Clear from require cache
57
clearRequireCache([absolutePath]);
58
59
// Also clear any files that depend on this file
60
const dependentFiles = findDependentFiles(absolutePath);
61
if (dependentFiles.length > 0) {
62
clearRequireCache(dependentFiles);
63
console.log(`Cleared dependent files:`, dependentFiles);
64
}
65
66
// Trigger rebuild
67
rebuild();
68
});
69
70
return watcher;
71
}
72
73
// Usage
74
const watcher = setupHMR([
75
"src/**/*.js",
76
"config/**/*.js",
77
"tailwind.config.js"
78
]);
79
```
80
81
### Development Server Integration
82
83
Use with development servers for automatic reloading:
84
85
```typescript
86
import { clearRequireCache } from "@tailwindcss/node/require-cache";
87
import express from "express";
88
89
const app = express();
90
91
// Middleware to clear cache on development requests
92
app.use('/api/reload', (req, res) => {
93
const { files } = req.body;
94
95
if (Array.isArray(files)) {
96
clearRequireCache(files.map(file => path.resolve(file)));
97
res.json({ success: true, cleared: files.length });
98
} else {
99
res.status(400).json({ error: "Files array required" });
100
}
101
});
102
103
// Development route that always uses fresh modules
104
app.get('/api/config', (req, res) => {
105
const configPath = path.resolve('./config.js');
106
107
// Clear cache to ensure fresh config
108
clearRequireCache([configPath]);
109
110
// Require fresh config
111
delete require.cache[configPath]; // Alternative approach
112
const config = require(configPath);
113
114
res.json(config);
115
});
116
```
117
118
### Build Tool Integration
119
120
Integration with build tools for cache management:
121
122
```typescript
123
import { clearRequireCache } from "@tailwindcss/node/require-cache";
124
125
// Webpack plugin example
126
class CacheClearPlugin {
127
constructor(private patterns: string[]) {}
128
129
apply(compiler: any) {
130
compiler.hooks.watchRun.tap('CacheClearPlugin', () => {
131
// Clear cache for specific patterns on rebuild
132
const filesToClear = this.patterns.flatMap(pattern =>
133
glob.sync(pattern).map(file => path.resolve(file))
134
);
135
136
if (filesToClear.length > 0) {
137
clearRequireCache(filesToClear);
138
console.log(`Cleared ${filesToClear.length} files from require cache`);
139
}
140
});
141
}
142
}
143
144
// Usage in webpack config
145
module.exports = {
146
plugins: [
147
new CacheClearPlugin([
148
'src/config/**/*.js',
149
'tailwind.config.js'
150
])
151
]
152
};
153
```
154
155
### Configuration Reloading
156
157
Implement configuration hot reloading for development:
158
159
```typescript
160
import { clearRequireCache } from "@tailwindcss/node/require-cache";
161
import fs from "fs";
162
163
class ConfigManager {
164
private configPath: string;
165
private config: any;
166
private watchers: Set<() => void> = new Set();
167
168
constructor(configPath: string) {
169
this.configPath = path.resolve(configPath);
170
this.loadConfig();
171
this.watchConfig();
172
}
173
174
private loadConfig() {
175
// Clear cache to ensure fresh load
176
clearRequireCache([this.configPath]);
177
178
try {
179
this.config = require(this.configPath);
180
console.log('Config loaded:', this.configPath);
181
} catch (error) {
182
console.error('Failed to load config:', error);
183
this.config = {};
184
}
185
}
186
187
private watchConfig() {
188
fs.watchFile(this.configPath, () => {
189
console.log('Config file changed, reloading...');
190
this.loadConfig();
191
192
// Notify watchers
193
this.watchers.forEach(callback => callback());
194
});
195
}
196
197
getConfig() {
198
return this.config;
199
}
200
201
onConfigChange(callback: () => void) {
202
this.watchers.add(callback);
203
return () => this.watchers.delete(callback);
204
}
205
}
206
207
// Usage
208
const configManager = new ConfigManager('./app.config.js');
209
210
const unwatch = configManager.onConfigChange(() => {
211
console.log('Config updated:', configManager.getConfig());
212
// Restart services, update app state, etc.
213
});
214
```
215
216
## ESM Cache Busting
217
218
The package also provides ESM cache busting through the ESM cache loader:
219
220
### ESM Module Registration
221
222
```typescript
223
// ESM cache loader is automatically registered when importing @tailwindcss/node
224
import "@tailwindcss/node"; // Registers ESM cache loader
225
226
// The loader adds cache-busting IDs to ESM imports
227
// import('./module.js') becomes import('./module.js?id=1234567890')
228
```
229
230
### Custom ESM Cache Implementation
231
232
```typescript
233
// For custom ESM cache busting (advanced usage)
234
import { pathToFileURL } from "url";
235
import { register } from "node:module";
236
237
// Register custom ESM loader
238
register(pathToFileURL('./custom-esm-loader.mjs'));
239
240
// In custom-esm-loader.mjs:
241
export async function resolve(specifier, context, nextResolve) {
242
const result = await nextResolve(specifier, context);
243
244
// Add cache busting parameter
245
if (shouldBustCache(result.url)) {
246
const url = new URL(result.url);
247
url.searchParams.set('cache-bust', Date.now().toString());
248
return { ...result, url: url.toString() };
249
}
250
251
return result;
252
}
253
```
254
255
## Performance Considerations
256
257
### Selective Cache Clearing
258
259
```typescript
260
import { clearRequireCache } from "@tailwindcss/node/require-cache";
261
262
// Clear only related files instead of entire cache
263
function clearRelatedFiles(changedFile: string) {
264
const relatedFiles = findRelatedFiles(changedFile);
265
clearRequireCache(relatedFiles);
266
}
267
268
function findRelatedFiles(changedFile: string): string[] {
269
// Implementation depends on your dependency graph
270
// Example: clear config files when source files change
271
if (changedFile.includes('/src/')) {
272
return [
273
path.resolve('./tailwind.config.js'),
274
path.resolve('./app.config.js')
275
];
276
}
277
278
return [changedFile];
279
}
280
```
281
282
### Cache Statistics
283
284
```typescript
285
import { clearRequireCache } from "@tailwindcss/node/require-cache";
286
287
// Track cache clearing statistics
288
class CacheManager {
289
private clearCount = 0;
290
private clearedFiles = new Set<string>();
291
292
clearCache(files: string[]) {
293
clearRequireCache(files);
294
295
this.clearCount++;
296
files.forEach(file => this.clearedFiles.add(file));
297
298
console.log(`Cache clear #${this.clearCount}: ${files.length} files`);
299
}
300
301
getStatistics() {
302
return {
303
totalClears: this.clearCount,
304
uniqueFilesCleared: this.clearedFiles.size,
305
currentCacheSize: Object.keys(require.cache).length
306
};
307
}
308
}
309
310
const cacheManager = new CacheManager();
311
```
312
313
### Memory Management
314
315
```typescript
316
import { clearRequireCache } from "@tailwindcss/node/require-cache";
317
318
// Prevent memory leaks in long-running processes
319
function periodicCacheCleanup() {
320
const maxCacheSize = 1000;
321
const currentCacheSize = Object.keys(require.cache).length;
322
323
if (currentCacheSize > maxCacheSize) {
324
// Clear non-core modules
325
const nonCoreModules = Object.keys(require.cache)
326
.filter(key => !key.includes('node_modules'))
327
.slice(0, Math.floor(maxCacheSize * 0.5));
328
329
clearRequireCache(nonCoreModules);
330
331
console.log(`Cleared ${nonCoreModules.length} modules from cache`);
332
}
333
}
334
335
// Run cleanup every 10 minutes in development
336
if (process.env.NODE_ENV === 'development') {
337
setInterval(periodicCacheCleanup, 10 * 60 * 1000);
338
}
339
```
340
341
## Platform Considerations
342
343
### Bun Compatibility
344
345
```typescript
346
// The package detects Bun and skips ESM registration
347
if (process.versions.bun) {
348
// ESM modules populate require.cache in Bun
349
// so cache clearing works the same way
350
clearRequireCache(files);
351
} else {
352
// Node.js requires ESM cache loader registration
353
// This is handled automatically by @tailwindcss/node
354
}
355
```
356
357
### Node.js Version Compatibility
358
359
```typescript
360
// Module.register() was added in Node v18.19.0 and v20.6.0
361
if (typeof Module.register === 'function') {
362
// Modern Node.js with ESM loader support
363
Module.register(loaderPath);
364
} else {
365
// Older Node.js versions - fallback to require cache only
366
console.warn('ESM cache busting not available in this Node.js version');
367
}
368
```
369
370
## Best Practices
371
372
1. **Clear Related Files**: When clearing cache, also clear dependent modules
373
2. **Use Absolute Paths**: Always use absolute paths with `clearRequireCache()`
374
3. **Selective Clearing**: Clear only necessary files to avoid performance issues
375
4. **Development Only**: Avoid cache clearing in production environments
376
5. **Error Handling**: Wrap cache operations in try-catch blocks
377
6. **Memory Monitoring**: Monitor cache size in long-running processes