Skip to content

Commit 2a407dd

Browse files
committed
feat: add vite client connect events
1 parent ae58e21 commit 2a407dd

File tree

2 files changed

+64
-7
lines changed

2 files changed

+64
-7
lines changed

guide/api-environment-plugins.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,43 @@ export default defineConfig({
228228
229229
`applyToEnvironment` フックは設定時に呼び出されます。エコシステム内のプロジェクトがプラグインを変更しているため、現在は `configResolved` の後に呼び出されています。環境プラグインの解決は、将来的には `configResolved` の前に移動される可能性があります。
230230
231+
## アプリケーション・プラグイン通信 {#application-plugin-communication}
232+
233+
`environment.hot` により、プラグインは指定された環境のアプリケーション側のコードと通信できます。これは[クライアント・サーバー通信機能](/guide/api-plugin#client-server-communication)と同等ですが、クライアント環境以外の環境もサポートします。
234+
235+
:::warning 注意
236+
237+
この機能は、HMR をサポートする環境でのみ使用可能です。
238+
239+
:::
240+
241+
### アプリケーションインスタンスの管理 {#managing-the-application-instances}
242+
243+
同じ環境で複数のアプリケーションインスタンスが実行されている可能性があることに注意してください。たとえば、ブラウザーで複数のタブを開いている場合、各タブは個別のアプリケーションインスタンスであり、サーバーへの個別の接続を持ちます。
244+
245+
新しい接続が確立されると、環境の `hot` インスタンスで `vite:client:connect` イベントが発生します。接続が閉じられると、`vite:client:disconnect` イベントが発生します。
246+
247+
各イベントハンドラーは、2 番目の引数として `NormalizedHotChannelClient` を受け取ります。クライアントは、特定のアプリケーションインスタンスにメッセージを送信するために使用できる `send` メソッドを持つオブジェクトです。クライアント参照は、同じ接続に対して常に同じであるため、接続を追跡するために保持できます。
248+
249+
### 使用例 {#example-usage}
250+
251+
プラグイン側:
252+
253+
```js
254+
configureServer(server) {
255+
server.environments.ssr.hot.on('my:greetings', (data, client) => {
256+
// データで何かを行い、
257+
// 必要に応じてそのアプリケーションインスタンスにレスポンスを送信
258+
client.send('my:foo:reply', `Hello from server! You said: ${data}`)
259+
})
260+
261+
// すべてのアプリケーションインスタンスにメッセージをブロードキャスト
262+
server.environments.ssr.hot.send('my:foo', 'Hello from server!')
263+
}
264+
```
265+
266+
アプリケーション側は、クライアント・サーバー通信機能と同じです。`import.meta.hot` オブジェクトを使用して、プラグインにメッセージを送信できます。
267+
231268
## ビルドフックの環境 {#environment-in-build-hooks}
232269
233270
開発時と同じように、プラグインフックもビルド時に環境インスタンスを受け取り、`ssr` ブール値を置き換えます。

guide/api-environment-runtimes.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -316,27 +316,45 @@ import { createServer, RemoteEnvironmentTransport, DevEnvironment } from 'vite'
316316
function createWorkerEnvironment(name, config, context) {
317317
const worker = new Worker('./worker.js')
318318
const handlerToWorkerListener = new WeakMap()
319+
const client = {
320+
send(payload: HotPayload) {
321+
worker.postMessage(payload)
322+
},
323+
}
319324

320325
const workerHotChannel = {
321326
send: (data) => worker.postMessage(data),
322327
on: (event, handler) => {
323-
if (event === 'connection') return
328+
// クライアントはすでに接続されています
329+
if (event === 'vite:client:connect') return
330+
if (event === 'vite:client:disconnect') {
331+
const listener = () => {
332+
handler(undefined, client)
333+
}
334+
handlerToWorkerListener.set(handler, listener)
335+
worker.on('exit', listener)
336+
return
337+
}
324338

325339
const listener = (value) => {
326340
if (value.type === 'custom' && value.event === event) {
327-
const client = {
328-
send(payload) {
329-
worker.postMessage(payload)
330-
},
331-
}
332341
handler(value.data, client)
333342
}
334343
}
335344
handlerToWorkerListener.set(handler, listener)
336345
worker.on('message', listener)
337346
},
338347
off: (event, handler) => {
339-
if (event === 'connection') return
348+
if (event === 'vite:client:connect') return
349+
if (event === 'vite:client:disconnect') {
350+
const listener = handlerToWorkerListener.get(handler)
351+
if (listener) {
352+
worker.off('exit', listener)
353+
handlerToWorkerListener.delete(handler)
354+
}
355+
return
356+
}
357+
340358
const listener = handlerToWorkerListener.get(handler)
341359
if (listener) {
342360
worker.off('message', listener)
@@ -363,6 +381,8 @@ await createServer({
363381

364382
:::
365383

384+
`on` / `off` メソッドが存在する場合は、それらのメソッドで `vite:client:connect` / `vite:client:disconnect` イベントを実装してください。`vite:client:connect` イベントは接続が確立されたときに発生し、`vite:client:disconnect` イベントは接続が閉じられたときに発生する必要があります。イベントハンドラーに渡される `HotChannelClient` オブジェクトは、同じ接続に対して同じ参照を持つ必要があります。
385+
366386
HTTP リクエストを使用してランナーとサーバー間で通信する別の例:
367387

368388
```ts

0 commit comments

Comments
 (0)