Skip to content
Merged
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
141 changes: 84 additions & 57 deletions website/docs/en/api/javascript-api/dev-server-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,51 @@ const server = await rsbuild.createDevServer();
console.log('the server is ', server);
```

## API interface
## Example

### Integrate with custom server

Here is an example of integrating [express](https://expressjs.com/) with Rsbuild dev server:

```ts
import { createRsbuild } from '@rsbuild/core';
import express from 'express';

async function startDevServer() {
// Init Rsbuild
const rsbuild = await createRsbuild({
rsbuildConfig: {
server: {
middlewareMode: true,
},
},
});
const app = express();

// Create Rsbuild dev server instance
const rsbuildServer = await rsbuild.createDevServer();

// Apply Rsbuild's built-in middleware
app.use(rsbuildServer.middlewares);

const server = app.listen(rsbuildServer.port, async () => {
// Notify Rsbuild that the custom server has started
await rsbuildServer.afterListen();
});

rsbuildServer.connectWebSocket({ server });
}
```

For detailed usage, please refer to:

- [Example code](https://github.com/rspack-contrib/rstack-examples/blob/main/rsbuild/express/server.mjs).
- [rsbuild.createDevServer](/api/javascript-api/instance#rsbuildcreatedevserver)
- [server.middlewareMode](/config/server/middleware-mode)

## API

### Type definitions

```ts
type EnvironmentAPI = {
Expand Down Expand Up @@ -88,10 +132,12 @@ type RsbuildDevServer = {
*/
afterListen: () => Promise<void>;
/**
* Activate socket connection.
* Activates the WebSocket connection.
* This ensures that HMR works properly.
*/
connectWebSocket: (options: { server: HTTPServer }) => void;
connectWebSocket: (options: {
server: import('node:http').Server | import('node:http2').Http2SecureServer;
}) => void;
/**
* Close the Rsbuild server.
*/
Expand Down Expand Up @@ -134,81 +180,62 @@ function CreateDevServer(
): Promise<RsbuildDevServer>;
```

### sockWrite

- **Type:** `(type: 'static-changed') => void`

Sends some message to HMR client, and then the HMR client will take different actions depending on the message type.
### connectWebSocket

For example, if you send a `'static-changed'` message, the page will reload.
- **Type:**

```ts
const rsbuildServer = await rsbuild.createDevServer();
if (someCondition) {
rsbuildServer.sockWrite('static-changed');
}
type ConnectWebSocket = (options: {
server: import('node:http').Server | import('node:http2').Http2SecureServer;
}) => void;
```

> Sending `content-changed` and `static-changed` have the same effect. Since `content-changed` has been deprecated, please use `static-changed` instead.

## Example
Activates the WebSocket connection. This ensures that HMR works properly.

### Integrate with custom server
Rsbuild has a builtin WebSocket handler to support HMR:

Here is an example of integrating [express](https://expressjs.com/) with Rsbuild dev server:
1. When a user accesses a page through browser, a WebSocket connection request is automatically initiated to the server.
2. After the Rsbuild dev server detects the connection request, it instructs the builtin WebSocket handler to process it.
3. After the browser successfully establishes a connection with the Rsbuild WebSocket handler, real-time communication is possible.
4. The Rsbuild WebSocket handler notifies the browser after each recompilation is complete. The browser then sends a `hot-update.(js|json)` request to the dev server to load the new compiled module.

```ts
import { createRsbuild } from '@rsbuild/core';
import express from 'express';
When you use custom server, you may encounter HMR connection error problems. This is because the custom server does not forward WebSocket connection requests to Rsbuild's WebSocket handler.

async function startDevServer() {
// Init Rsbuild
const rsbuild = await createRsbuild({
rsbuildConfig: {
server: {
middlewareMode: true,
},
},
});
const app = express();
At this time, you need to use the `connectWebSocket` method to enable Rsbuild to sense and process the WebSocket connection request from the browser.

// Create Rsbuild dev server instance
const rsbuildServer = await rsbuild.createDevServer();
```ts
const rsbuildServer = await rsbuild.createDevServer();
const httpServer = app.listen(rsbuildServer.port);

// Apply Rsbuild's built-in middleware
app.use(rsbuildServer.middlewares);
rsbuildServer.connectWebSocket({ server: httpServer });
```

const server = app.listen(rsbuildServer.port, async () => {
// Notify Rsbuild that the custom server has started
await rsbuildServer.afterListen();
});
### environments

rsbuildServer.connectWebSocket({ server });
}
```
- **Type:** [EnvironmentAPI](/api/javascript-api/environment-api#environment-api)

For detailed usage, please refer to:
Provides Rsbuild's [environment API](/api/javascript-api/environment-api#environment-api), which allows you to get the build outputs information for a specific environment in the server side.

- [Example code](https://github.com/rspack-contrib/rstack-examples/blob/main/rsbuild/express/server.mjs).
- [rsbuild.createDevServer](/api/javascript-api/instance#rsbuildcreatedevserver)
- [server.middlewareMode](/config/server/middleware-mode)
```ts title="rsbuild.config.ts"
const rsbuildServer = await rsbuild.createDevServer();
const webStats = await rsbuildServer.environments.web.getStats();

### connectWebSocket
console.log(webStats.toJson({ all: false }));
```

Rsbuild has a builtin WebSocket handler to support HMR:
### sockWrite

1. When a user accesses a page through browser, a WebSocket connection request is automatically initiated to the server.
2. After the Rsbuild dev server detects the connection request, it instructs the builtin WebSocket handler to process it.
3. After the browser successfully establishes a connection with the Rsbuild WebSocket handler, real-time communication is possible.
4. The Rsbuild WebSocket handler notifies the browser after each recompilation is complete. The browser then sends a `hot-update.(js|json)` request to the dev server to load the new compiled module.
- **Type:** `(type: 'static-changed') => void`

When you use custom server, you may encounter HMR connection error problems. This is because the custom server does not forward WebSocket connection requests to Rsbuild's WebSocket handler.
Sends some message to HMR client, and then the HMR client will take different actions depending on the message type.

At this time, you need to use the `connectWebSocket` method to enable Rsbuild to sense and process the WebSocket connection request from the browser.
For example, if you send a `'static-changed'` message, the page will reload.

```ts
const rsbuildServer = await rsbuild.createDevServer();
const httpServer = app.listen(rsbuildServer.port);

rsbuildServer.connectWebSocket({ server: httpServer });
if (someCondition) {
rsbuildServer.sockWrite('static-changed');
}
```

> Sending `content-changed` and `static-changed` have the same effect. Since `content-changed` has been deprecated, please use `static-changed` instead.
34 changes: 15 additions & 19 deletions website/docs/en/config/dev/setup-middlewares.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,44 +56,40 @@ export default {

In the `setupMiddlewares` function, you can access the `server` object, which provides some server APIs.

### sockWrite
### environments

Sends some message to HMR client, see [Dev server API - sockWrite](/api/javascript-api/dev-server-api#sockwrite) for more details.

For example, if you send a `'static-changed'` message, the page will reload.
Provides Rsbuild's [environment API](/api/javascript-api/environment-api#environment-api), see [Dev server API - environments](/api/javascript-api/dev-server-api#environments) for more details.

```ts title="rsbuild.config.ts"
export default {
dev: {
setupMiddlewares: [
(middlewares, server) => {
if (someCondition) {
server.sockWrite('static-changed');
}
(middlewares, { environments }) => {
middlewares.unshift(async (req, _res, next) => {
const webStats = await environments.web.getStats();
console.log(webStats.toJson({ all: false }));
next();
});
},
],
},
};
```

### environments
### sockWrite

- **Type:** [EnvironmentAPI](/api/javascript-api/environment-api#environment-api)
Sends some message to HMR client, see [Dev server API - sockWrite](/api/javascript-api/dev-server-api#sockwrite) for more details.

`environments` includes Rsbuild's [environment API](/api/javascript-api/environment-api#environment-api), which allows you to get the build outputs information for a specific environment in the server side.
For example, if you send a `'static-changed'` message, the page will reload.

```ts title="rsbuild.config.ts"
export default {
dev: {
setupMiddlewares: [
(middlewares, server) => {
middlewares.unshift(async (req, _res, next) => {
const webStats = await server.environments.web.getStats();

console.log(webStats.toJson({ all: false }));

next();
});
(middlewares, { sockWrite }) => {
if (someCondition) {
sockWrite('static-changed');
}
},
],
},
Expand Down
Loading
Loading