0
# Development Server
1
2
Development server configuration and APIs for hot module replacement and live reloading. The Stencil dev server provides a complete development environment with file watching, automatic rebuilds, and browser synchronization.
3
4
## Capabilities
5
6
### Server Configuration
7
8
Configuration options for the Stencil development server.
9
10
```typescript { .api }
11
/**
12
* Development server configuration
13
*/
14
interface StencilDevServerConfig {
15
/** IP address for the dev server */
16
address?: string;
17
/** Base path for server routes */
18
basePath?: string;
19
/** Enable experimental dev modules bundling */
20
experimentalDevModules?: boolean;
21
/** Enable gzip compression */
22
gzip?: boolean;
23
/** HTTPS configuration */
24
https?: Credentials;
25
/** Initial URL to open */
26
initialLoadUrl?: string;
27
/** Log all requests to terminal */
28
logRequests?: boolean;
29
/** Open browser automatically */
30
openBrowser?: boolean;
31
/** Server port number */
32
port?: number;
33
/** Reload strategy for file changes */
34
reloadStrategy?: PageReloadStrategy;
35
/** Custom request listener file path */
36
requestListenerPath?: string;
37
/** Root directory to serve files from */
38
root?: string;
39
/** Enable server-side rendering */
40
ssr?: boolean;
41
/** Startup timeout in milliseconds */
42
startupTimeout?: number;
43
/** Enable websocket client */
44
websocket?: boolean;
45
/** Fork worker process for server */
46
worker?: boolean;
47
}
48
49
interface Credentials {
50
/** SSL private key */
51
key: string;
52
/** SSL certificate */
53
cert: string;
54
}
55
56
type PageReloadStrategy = 'hmr' | 'pageReload' | null;
57
58
/**
59
* Extended dev server configuration with internal options
60
*/
61
interface DevServerConfig extends StencilDevServerConfig {
62
/** Browser URL for opening */
63
browserUrl?: string;
64
/** Dev server working directory */
65
devServerDir?: string;
66
/** Glob patterns to exclude from HMR */
67
excludeHmr?: string[];
68
/** History API fallback configuration */
69
historyApiFallback?: HistoryApiFallback;
70
/** Prerender configuration file */
71
prerenderConfig?: string;
72
/** Protocol (http or https) */
73
protocol?: 'http' | 'https';
74
/** Source index.html file */
75
srcIndexHtml?: string;
76
/** Ping route for build status */
77
pingRoute?: string | null;
78
}
79
80
interface HistoryApiFallback {
81
/** Fallback index file */
82
index?: string;
83
/** Disable dot rule */
84
disableDotRule?: boolean;
85
}
86
```
87
88
**Usage Examples:**
89
90
```typescript
91
import { Config } from '@stencil/core';
92
93
export const config: Config = {
94
devServer: {
95
port: 3333,
96
address: '0.0.0.0',
97
openBrowser: true,
98
reloadStrategy: 'hmr',
99
logRequests: false,
100
gzip: true,
101
https: {
102
key: './ssl/server.key',
103
cert: './ssl/server.crt'
104
},
105
requestListenerPath: './dev-server-middleware.js'
106
}
107
};
108
```
109
110
### Server Interface
111
112
Runtime interface for the development server instance.
113
114
```typescript { .api }
115
/**
116
* Development server runtime interface
117
*/
118
interface DevServer extends BuildEmitEvents {
119
/** Server address */
120
address: string;
121
/** Base path */
122
basePath: string;
123
/** Browser URL */
124
browserUrl: string;
125
/** Protocol used */
126
protocol: string;
127
/** Port number */
128
port: number;
129
/** Root directory */
130
root: string;
131
/** Close the server */
132
close(): Promise<void>;
133
}
134
135
/**
136
* Build event emitter interface
137
*/
138
interface BuildEmitEvents {
139
emit(eventName: 'fileAdd', path: string): void;
140
emit(eventName: 'fileDelete', path: string): void;
141
emit(eventName: 'fileUpdate', path: string): void;
142
emit(eventName: 'dirAdd', path: string): void;
143
emit(eventName: 'dirDelete', path: string): void;
144
emit(eventName: 'buildStart', buildStart: CompilerBuildStart): void;
145
emit(eventName: 'buildFinish', buildResults: CompilerBuildResults): void;
146
emit(eventName: 'buildNoChange', buildNoChange: BuildNoChangeResults): void;
147
emit(eventName: 'buildLog', buildLog: BuildLog): void;
148
emit(eventName: 'fsChange', fsWatchResults: FsWatchResults): void;
149
}
150
```
151
152
### Hot Module Replacement
153
154
HMR configuration and data structures for live reloading.
155
156
```typescript { .api }
157
/**
158
* Hot module replacement data
159
*/
160
interface HotModuleReplacement {
161
/** Components that were updated */
162
componentsUpdated?: string[];
163
/** Files to exclude from HMR */
164
excludeHmr?: string[];
165
/** External stylesheets that were updated */
166
externalStylesUpdated?: string[];
167
/** Images that were updated */
168
imagesUpdated?: string[];
169
/** Whether index.html was updated */
170
indexHtmlUpdated?: boolean;
171
/** Inline styles that were updated */
172
inlineStylesUpdated?: HmrStyleUpdate[];
173
/** Reload strategy to use */
174
reloadStrategy: PageReloadStrategy;
175
/** Scripts that were added */
176
scriptsAdded?: string[];
177
/** Scripts that were deleted */
178
scriptsDeleted?: string[];
179
/** Whether service worker was updated */
180
serviceWorkerUpdated?: boolean;
181
/** Version ID for cache busting */
182
versionId?: string;
183
}
184
185
interface HmrStyleUpdate {
186
/** Style element ID */
187
styleId: string;
188
/** Complete style tag HTML */
189
styleTag: string;
190
/** Style text content */
191
styleText: string;
192
}
193
```
194
195
### Request Middleware
196
197
Custom request handling for the development server.
198
199
```typescript { .api }
200
/**
201
* Custom request listener function signature
202
* Used with requestListenerPath configuration
203
*/
204
type DevServerRequestListener = (
205
req: IncomingMessage,
206
res: ServerResponse,
207
next: () => void
208
) => void;
209
```
210
211
**Usage Example - Custom Middleware:**
212
213
```javascript
214
// dev-server-middleware.js
215
module.exports = function(req, res, next) {
216
// Handle API routes
217
if (req.url.startsWith('/api/')) {
218
if (req.url === '/api/health') {
219
res.setHeader('Content-Type', 'application/json');
220
res.writeHead(200);
221
res.end(JSON.stringify({ status: 'ok', timestamp: Date.now() }));
222
return;
223
}
224
225
if (req.url === '/api/users') {
226
res.setHeader('Content-Type', 'application/json');
227
res.writeHead(200);
228
res.end(JSON.stringify([
229
{ id: 1, name: 'John Doe' },
230
{ id: 2, name: 'Jane Smith' }
231
]));
232
return;
233
}
234
235
// API not found
236
res.writeHead(404);
237
res.end('API endpoint not found');
238
return;
239
}
240
241
// Redirect old URLs
242
if (req.url === '/old-page') {
243
res.writeHead(301, { Location: '/new-page' });
244
res.end();
245
return;
246
}
247
248
// Add custom headers
249
res.setHeader('X-Dev-Server', 'Stencil');
250
251
// Pass to default handler
252
next();
253
};
254
```
255
256
### Server Events
257
258
Events emitted by the development server for monitoring and integration.
259
260
```typescript { .api }
261
/**
262
* Server event types
263
*/
264
type DevServerEventName =
265
| 'buildStart'
266
| 'buildFinish'
267
| 'buildLog'
268
| 'buildNoChange'
269
| 'fileAdd'
270
| 'fileUpdate'
271
| 'fileDelete'
272
| 'dirAdd'
273
| 'dirDelete'
274
| 'fsChange';
275
276
/**
277
* File system change event data
278
*/
279
interface FsWatchResults {
280
/** Directories that were added */
281
dirsAdded: string[];
282
/** Directories that were deleted */
283
dirsDeleted: string[];
284
/** Files that were updated */
285
filesUpdated: string[];
286
/** Files that were added */
287
filesAdded: string[];
288
/** Files that were deleted */
289
filesDeleted: string[];
290
}
291
292
/**
293
* Build log event data
294
*/
295
interface BuildLog {
296
/** Build identifier */
297
buildId: number;
298
/** Log messages */
299
messages: string[];
300
/** Build progress (0-1) */
301
progress: number;
302
}
303
```
304
305
### WebSocket Client
306
307
Client-side WebSocket API for communicating with the dev server.
308
309
```typescript { .api }
310
/**
311
* WebSocket message types from dev server
312
*/
313
interface DevServerMessage {
314
/** Message type */
315
type: 'hmr-update' | 'build-start' | 'build-finish' | 'build-log' | 'reload';
316
/** Message data */
317
data?: any;
318
}
319
320
/**
321
* HMR update message data
322
*/
323
interface HmrUpdateMessage {
324
/** HMR data */
325
hmr: HotModuleReplacement;
326
/** Build results */
327
buildResults: CompilerBuildResults;
328
}
329
```
330
331
**Usage Example - WebSocket Integration:**
332
333
```javascript
334
// Client-side WebSocket handling
335
if ('WebSocket' in window) {
336
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
337
const wsUrl = `${protocol}//${window.location.host}`;
338
const ws = new WebSocket(wsUrl);
339
340
ws.onmessage = (event) => {
341
const message = JSON.parse(event.data);
342
343
switch (message.type) {
344
case 'build-start':
345
console.log('Build started...');
346
showBuildStatus('Building...');
347
break;
348
349
case 'build-finish':
350
console.log('Build finished');
351
hideBuildStatus();
352
if (message.data.hasError) {
353
showBuildErrors(message.data.diagnostics);
354
}
355
break;
356
357
case 'hmr-update':
358
console.log('Hot module replacement update');
359
handleHmrUpdate(message.data.hmr);
360
break;
361
362
case 'reload':
363
console.log('Full page reload requested');
364
window.location.reload();
365
break;
366
367
case 'build-log':
368
console.log(`Build progress: ${message.data.progress * 100}%`);
369
updateBuildProgress(message.data.progress);
370
break;
371
}
372
};
373
374
ws.onopen = () => {
375
console.log('Connected to Stencil dev server');
376
};
377
378
ws.onclose = () => {
379
console.log('Disconnected from dev server');
380
setTimeout(() => {
381
// Attempt to reconnect
382
window.location.reload();
383
}, 1000);
384
};
385
}
386
```
387
388
### Performance Monitoring
389
390
Development server performance and timing utilities.
391
392
```typescript { .api }
393
/**
394
* Performance entry for dev server operations
395
*/
396
interface DevServerPerformanceEntry {
397
/** Operation name */
398
name: string;
399
/** Start time */
400
startTime: number;
401
/** Duration in milliseconds */
402
duration: number;
403
/** Additional details */
404
details?: { [key: string]: any };
405
}
406
407
/**
408
* Build timing information
409
*/
410
interface BuildTiming {
411
/** TypeScript compilation time */
412
tsc?: number;
413
/** Bundle generation time */
414
bundling?: number;
415
/** Asset processing time */
416
assets?: number;
417
/** Output generation time */
418
outputs?: number;
419
/** Total build time */
420
total: number;
421
}
422
```
423
424
### Editor Integration
425
426
Support for editor integrations and development tools.
427
428
```typescript { .api }
429
/**
430
* Editor configuration for development
431
*/
432
interface DevServerEditor {
433
/** Editor identifier */
434
id: string;
435
/** Display name */
436
name?: string;
437
/** Whether editor is supported */
438
supported?: boolean;
439
/** Priority for selection */
440
priority?: number;
441
}
442
443
/**
444
* Common editor configurations
445
*/
446
const EDITORS = {
447
VSCODE: { id: 'vscode', name: 'Visual Studio Code', priority: 1 },
448
WEBSTORM: { id: 'webstorm', name: 'WebStorm', priority: 2 },
449
SUBLIME: { id: 'sublime', name: 'Sublime Text', priority: 3 },
450
ATOM: { id: 'atom', name: 'Atom', priority: 4 }
451
};
452
```
453
454
**Usage Example - Advanced Dev Server Setup:**
455
456
```typescript
457
import { Config } from '@stencil/core';
458
459
export const config: Config = {
460
devServer: {
461
port: process.env.PORT ? parseInt(process.env.PORT) : 3333,
462
address: process.env.NODE_ENV === 'production' ? '0.0.0.0' : 'localhost',
463
openBrowser: process.env.CI !== 'true',
464
reloadStrategy: 'hmr',
465
466
// Advanced configuration
467
experimentalDevModules: true,
468
logRequests: process.env.DEBUG === 'true',
469
startupTimeout: 30000,
470
471
// Custom middleware for API mocking
472
requestListenerPath: './dev-middleware.js',
473
474
// HTTPS in development
475
https: process.env.HTTPS === 'true' ? {
476
key: './certificates/dev-key.pem',
477
cert: './certificates/dev-cert.pem'
478
} : undefined,
479
480
// Exclude certain patterns from HMR
481
excludeHmr: [
482
'**/test/**',
483
'**/*.spec.ts',
484
'**/*.e2e.ts'
485
]
486
},
487
488
// Watch additional directories
489
watchExternalDirs: [
490
'../shared-components/src',
491
'./design-tokens'
492
]
493
};
494
```