-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathweb-dev-server.config.js
More file actions
91 lines (87 loc) · 3 KB
/
web-dev-server.config.js
File metadata and controls
91 lines (87 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { fileURLToPath } from 'url';
import { stat } from 'node:fs/promises';
import { join } from 'node:path';
import { esbuildPlugin } from '@web/dev-server-esbuild';
import { litCss } from 'web-dev-server-plugin-lit-css';
import { routerPlugin } from './dev-server/plugins/router.ts';
import { injectImportMapPlugin } from './dev-server/plugins/inject-import-map.ts';
/**
* Redirect .js requests to .ts files for elements and lib directories.
* This ensures the file watcher detects .ts changes and triggers live reload.
*/
function liveReloadTsChangesMiddleware(ctx, next) {
if (!ctx.path.includes('node_modules')
&& ctx.path.match(/\/(elements|lib)\/.*\.js$/)) {
ctx.redirect(ctx.path.replace('.js', '.ts'));
} else {
return next();
}
}
/**
* Set ETag based on file modification time for elements/lib JS files.
* When files change, ETag changes, forcing browser to re-fetch.
*/
async function cacheBusterMiddleware(ctx, next) {
await next();
if (ctx.path.match(/\/(elements|lib)\/.*\.(js|ts)$/)) {
try {
const filePath = ctx.path.endsWith('.ts')
? join(process.cwd(), ctx.path)
: join(process.cwd(), ctx.path.replace('.js', '.ts'));
const stats = await stat(filePath);
const mtime = stats.mtime.getTime();
ctx.response.set('Cache-Control', 'no-store, no-cache, must-revalidate');
ctx.response.set('Pragma', 'no-cache');
ctx.response.etag = `modified-${mtime}`;
} catch {
// File doesn't exist as .ts, ignore
}
}
}
export default {
rootDir: ".",
watch: true,
watchOptions: {
ignored: ['**/node_modules/**', '**/.wireit/**'],
},
plugins: [
esbuildPlugin({
ts: true,
tsx: true,
jsxFactory: 'React.createElement',
jsxFragment: 'React.Fragment',
tsconfig: fileURLToPath(new URL('./tsconfig.json', import.meta.url)),
}),
litCss({
// Exclude dev-server styles, patternfly-react CSS, lightdom CSS, and /styles/ directory from Lit CSS transformation
exclude: /dev-server\/styles\/.*\.css$|patternfly-react\/dist\/.*\.css$|.*-lightdom\.css$|styles\/.*\.css$/,
}),
routerPlugin(),
injectImportMapPlugin(),
// Watch TypeScript files and trigger reload on changes
{
name: 'watch-ts-files',
serverStart(args) {
// Add TypeScript files to file watcher
args.fileWatcher.add('elements/**/*.ts');
args.fileWatcher.add('lib/**/*.ts');
},
},
],
middleware: [
liveReloadTsChangesMiddleware,
cacheBusterMiddleware,
function setCorrectMimeTypes(context, next) {
// Ensure CSS files from patternfly-react are served with correct MIME type
// BUT don't interfere with litCss-transformed component CSS imports
if (context.url && context.url.includes('patternfly-react/dist/') && context.url.endsWith('.css')) {
return next().then(() => {
if (context.response.is('application/javascript')) {
context.response.type = 'text/css';
}
});
}
return next();
}
],
}