Skip to content

Commit 6e57aba

Browse files
authored
feat: introduce RunnableDevEnvironment (#1569)
1 parent 900a789 commit 6e57aba

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

guide/api-environment.md

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,22 @@ interface TransformResult {
107107
}
108108
```
109109

110+
Vite は `ModuleRunner` インスタンスを公開する `DevEnvironment` を拡張した `RunnableDevEnvironment` もサポートしています。`isRunnableDevEnvironment` 関数を使用すると、実行可能な環境をガードできます。
111+
112+
:::warning
113+
`runner` は初めてアクセスされたときに、優先的に評価されます。Vite は、`process.setSourceMapsEnabled` を呼び出すことによって `runner` が作成されたとき、または、利用できない場合は `Error.prepareStackTrace` をオーバーライドすることによって、ソースマップのサポートを有効にすることに注意してください。
114+
:::
115+
116+
```ts
117+
export class RunnableDevEnvironment extends DevEnvironment {
118+
public readonly runner: ModuleRunnner
119+
}
120+
121+
if (isRunnableDevEnvironment(server.environments.ssr)) {
122+
await server.environments.ssr.runner.import('/entry-point.js')
123+
}
124+
```
125+
110126
Vite サーバーの環境インスタンスでは、`environment.transformRequest(url)` メソッドを使用して URL を処理できます。この関数はプラグインパイプラインを使用して `url` をモジュール `id` に解決し、(ファイルシステムからファイルを読み込むか、仮想モジュールを実装するプラグインを介して)モジュールをロードし、コードを変換します。モジュールを変換している間、インポートやその他のメタデータは、対応するモジュールノードを作成または更新することで、環境モジュールグラフに記録されます。処理が完了すると、変換結果もモジュールに保存されます。
111127

112128
しかし、モジュールが実行されるランタイムが Vite サーバーが実行されているランタイムと異なる可能性があるため、環境インスタンスはコード自体を実行することはできません。これはブラウザー環境の場合です。HTML がブラウザーに読み込まれると、そのスクリプトが実行され、静的モジュールグラフ全体の評価が開始されます。インポートされた各 URL は、モジュールコードを取得するために Vite サーバーへのリクエストを生成します。このリクエストは、`server.environment.client.transformRequest(url)` を呼び出すことによって、変換ミドルウェアによって処理されます。サーバーの環境インスタンスとブラウザーのモジュールランナー間の接続は、この場合 HTTP を通して行われます。
@@ -119,7 +135,7 @@ Vite サーバーの環境インスタンスでは、`environment.transformReque
119135
最初の提案では、コンシューマが `transport` オプションを使うことでランナー側でインポートを呼び出すことができる `run` メソッドがありました。テスト中に、この API を推奨するほど汎用的なものではないことがわかりました。私たちはフレームワークからのフィードバックに基づいて、リモート SSR 実装のための組み込みレイヤーを実装する予定です。それまでの間、Vite はランナー RPC の複雑さを隠すために [`RunnerTransport` API](#runnertransport) を公開しています。
120136
:::
121137

122-
デフォルトで Node で動作する `ssr` 環境では、Vite は開発サーバーと同じ JS ランタイムで動作される `new AsyncFunction` を使って評価を実装するモジュールランナーを作成します。このランナーは `ModuleRunner` のインスタンスで、次のように公開します:
138+
開発モードでは、デフォルトの `ssr` 環境は、開発サーバーと同じ JS ランタイムで実行される `new AsyncFunction` で評価したものを実装するモジュールランナーを備えた `RunnableDevEnvironment` です。このランナーは `ModuleRunner` のインスタンスで、次のように公開します:
123139

124140
```ts
125141
class ModuleRunner {
@@ -137,15 +153,10 @@ class ModuleRunner {
137153
v5.1 のランタイム API では `executeUrl` メソッドと `executeEntryPoint` メソッドがありましたが、現在は単一の `import` メソッドに統合されています。HMR のサポートを停止したい場合は、`hmr: false` フラグを付けてランナーを作成します。
138154
:::
139155
140-
デフォルトの SSR Node モジュールランナーは公開されていません。`createNodeEnvironment` API と `createServerModuleRunner` を一緒に使うことで、同じスレッドでコードを実行し、HMR をサポートし、SSR の実装と衝突しないランナーを作成できます(設定でオーバーライドされている場合)。[SSR セットアップガイド](/guide/ssr#setting-up-the-dev-server)で説明されているように、ミドルウェアモードに設定された Vite サーバーがあるとして、Environment API を使って SSR ミドルウェアを実装してみましょう。エラー処理は省略します。
156+
[SSR セットアップガイド](/guide/ssr#setting-up-the-dev-server)で説明されているように、ミドルウェアモードに設定された Vite サーバーがあるとして、Environment API を使って SSR ミドルウェアを実装してみましょう。エラー処理は省略します。
141157
142158
```js
143-
import {
144-
createServer,
145-
createServerHotChannel,
146-
createServerModuleRunner,
147-
createNodeDevEnvironment,
148-
} from 'vite'
159+
import { createServer, createRunnableDevEnvironment } from 'vite'
149160

150161
const server = await createServer({
151162
server: { middlewareMode: true },
@@ -156,16 +167,16 @@ const server = await createServer({
156167
// デフォルトの Vite SSR 環境はコンフィグで上書きできるので、
157168
// リクエストを受け取る前に Node 環境があることを確認してください。
158169
createEnvironment(name, config) {
159-
return createNodeDevEnvironment(name, config, {
160-
hot: createServerHotChannel(),
161-
})
170+
return createRunnableDevEnvironment(name, config)
162171
},
163172
},
164173
},
165174
},
166175
})
167176

168-
const runner = createServerModuleRunner(server.environments.node)
177+
// TypeScript では、これを RunnableDevEnvironment にキャストするか、ランナーへのアクセスを
178+
// 保護するために "isRunnableDevEnvironment" 関数を使用する必要があるかもしれません
179+
const environment = server.environments.node
169180

170181
app.use('*', async (req, res, next) => {
171182
const url = req.originalUrl
@@ -181,7 +192,7 @@ app.use('*', async (req, res, next) => {
181192
// 3. サーバーエントリをロードします。import(url) は、
182193
// ESM ソースコードを Node.js で使用できるように自動的に変換します。
183194
// バンドルは不要で、完全な HMR サポートを提供します。
184-
const { render } = await runner.import('/src/entry-server.js')
195+
const { render } = await environment.runner.import('/src/entry-server.js')
185196

186197
// 4. アプリの HTML をレンダリングします。これは、entry-server.js のエクスポートされた
187198
// `render` 関数が適切なフレームワーク SSR API を呼び出すことを前提としています。
@@ -310,7 +321,7 @@ function createWorkerdDevEnvironment(name: string, config: ResolvedConfig, conte
310321
...context.options,
311322
},
312323
hot,
313-
runner: {
324+
remoteRunner: {
314325
transport,
315326
},
316327
})
@@ -395,7 +406,7 @@ export default {
395406
dev: {
396407
createEnvironment(name, config, { watcher }) {
397408
// 開発時に 'rsc' と解決されたコンフィグで呼び出される
398-
return createNodeDevEnvironment(name, config, {
409+
return createRunnableDevEnvironment(name, config, {
399410
hot: customHotChannel(),
400411
watcher
401412
})
@@ -786,7 +797,7 @@ function createWorkerEnvironment(name, config, context) {
786797
const worker = new Worker('./worker.js')
787798
return new DevEnvironment(name, config, {
788799
hot: /* custom hot channel */,
789-
runner: {
800+
remoteRunner: {
790801
transport: new RemoteEnvironmentTransport({
791802
send: (data) => worker.postMessage(data),
792803
onMessage: (listener) => worker.on('message', listener),

0 commit comments

Comments
 (0)