コンテンツにスキップ

Environment インスタンスの使用

実験的

環境APIは実験的です。エコシステムがこれを試用して構築できるように、Vite 6の間はAPIを安定した状態に保ちます。Vite 7では、これらの新しいAPIを安定させる予定ですが、破壊的な変更の可能性があります。

リソース

フィードバックをお寄せください。

環境へのアクセス

開発中は、開発サーバーで使用可能な環境には `server.environments` を使用してアクセスできます。

js
// create the server, or get it from the configureServer hook
const server = await createServer(/* options */)

const environment = server.environments.client
environment.transformRequest(url)
console.log(server.environments.ssr.moduleGraph)

プラグインから現在の環境にアクセスすることもできます。詳細は、プラグインの環境APIを参照してください。

DevEnvironment クラス

開発中は、各環境は `DevEnvironment` クラスのインスタンスです。

ts
class DevEnvironment {
  /**
   * Unique identifier for the environment in a Vite server.
   * By default Vite exposes 'client' and 'ssr' environments.
   */
  name: string
  /**
   * Communication channel to send and receive messages from the
   * associated module runner in the target runtime.
   */
  hot: NormalizedHotChannel
  /**
   * Graph of module nodes, with the imported relationship between
   * processed modules and the cached result of the processed code.
   */
  moduleGraph: EnvironmentModuleGraph
  /**
   * Resolved plugins for this environment, including the ones
   * created using the per-environment `create` hook
   */
  plugins: Plugin[]
  /**
   * Allows to resolve, load, and transform code through the
   * environment plugins pipeline
   */
  pluginContainer: EnvironmentPluginContainer
  /**
   * Resolved config options for this environment. Options at the server
   * global scope are taken as defaults for all environments, and can
   * be overridden (resolve conditions, external, optimizedDeps)
   */
  config: ResolvedConfig & ResolvedDevEnvironmentOptions

  constructor(
    name: string,
    config: ResolvedConfig,
    context: DevEnvironmentContext,
  )

  /**
   * Resolve the URL to an id, load it, and process the code using the
   * plugins pipeline. The module graph is also updated.
   */
  async transformRequest(url: string): Promise<TransformResult | null>

  /**
   * Register a request to be processed with low priority. This is useful
   * to avoid waterfalls. The Vite server has information about the
   * imported modules by other requests, so it can warmup the module graph
   * so the modules are already processed when they are requested.
   */
  async warmupRequest(url: string): Promise<void>
}

ここで、`DevEnvironmentContext` は

ts
interface DevEnvironmentContext {
  hot: boolean
  transport?: HotChannel | WebSocketServer
  options?: EnvironmentOptions
  remoteRunner?: {
    inlineSourceMap?: boolean
  }
  depsOptimizer?: DepsOptimizer
}

`TransformResult` は

ts
interface TransformResult {
  code: string
  map: SourceMap | { mappings: '' } | null
  etag?: string
  deps?: string[]
  dynamicDeps?: string[]
}

Viteサーバーの環境インスタンスでは、`environment.transformRequest(url)` メソッドを使用してURLを処理できます。この関数は、プラグインパイプラインを使用して `url` をモジュール `id` に解決し、それをロードし(ファイルシステムから、または仮想モジュールを実装するプラグインを介してファイルを読み取ります)、コードを変換します。モジュールの変換中に、対応するモジュールノードを作成または更新することにより、インポートとその他のメタデータが環境モジュールグラフに記録されます。処理が完了すると、変換結果もモジュールに格納されます。

transformRequest の命名

この提案の現在のバージョンでは、`transformRequest(url)` と `warmupRequest(url)` を使用しているため、Viteの現在のAPIに慣れているユーザーにとって議論や理解が容易になります。リリース前に、これらの名前も見直すことができます。たとえば、Rollupのプラグインフックの `context.load(id)` からヒントを得て、`environment.processModule(url)` または `environment.loadModule(url)` という名前にすることができます。現時点では、現在の名前を維持し、この議論を遅らせる方が良いと考えています。

個別のモジュールグラフ

各環境には、隔離されたモジュールグラフがあります。すべてのモジュールグラフは同じシグネチャを持つため、環境に依存せずにグラフをクロールまたはクエリするための汎用アルゴリズムを実装できます。`hotUpdate` は良い例です。ファイルが変更されると、各環境のモジュールグラフを使用して、影響を受けるモジュールが検出され、各環境に対して個別にHMRが実行されます。

情報

Vite v5には、クライアントとSSRのモジュールグラフが混在していました。処理されていないノードまたは無効化されたノードが与えられた場合、それがクライアント、SSR、または両方の環境に対応するかどうかを知ることはできません。モジュールノードには、`clientImportedModules` や `ssrImportedModules`(および両方の和集合を返す `importedModules`)のように、プレフィックスが付いたプロパティがいくつかあります。`importers` には、各モジュールノードのクライアント環境とSSR環境の両方のすべてのインポーターが含まれています。モジュールノードには、`transformResult` と `ssrTransformResult` もあります。下位互換性レイヤーにより、エコシステムは非推奨の `server.moduleGraph` から移行できます。

各モジュールは、`EnvironmentModuleNode` インスタンスによって表されます。モジュールは、まだ処理されていない状態でグラフに登録される場合があります(その場合、`transformResult` は `null` になります)。`importers` と `importedModules` も、モジュールの処理後に更新されます。

ts
class EnvironmentModuleNode {
  environment: string

  url: string
  id: string | null = null
  file: string | null = null

  type: 'js' | 'css'

  importers = new Set<EnvironmentModuleNode>()
  importedModules = new Set<EnvironmentModuleNode>()
  importedBindings: Map<string, Set<string>> | null = null

  info?: ModuleInfo
  meta?: Record<string, any>
  transformResult: TransformResult | null = null

  acceptedHmrDeps = new Set<EnvironmentModuleNode>()
  acceptedHmrExports: Set<string> | null = null
  isSelfAccepting?: boolean
  lastHMRTimestamp = 0
  lastInvalidationTimestamp = 0
}

`environment.moduleGraph` は `EnvironmentModuleGraph` のインスタンスです。

ts
export class EnvironmentModuleGraph {
  environment: string

  urlToModuleMap = new Map<string, EnvironmentModuleNode>()
  idToModuleMap = new Map<string, EnvironmentModuleNode>()
  etagToModuleMap = new Map<string, EnvironmentModuleNode>()
  fileToModulesMap = new Map<string, Set<EnvironmentModuleNode>>()

  constructor(
    environment: string,
    resolveId: (url: string) => Promise<PartialResolvedId | null>,
  )

  async getModuleByUrl(
    rawUrl: string,
  ): Promise<EnvironmentModuleNode | undefined>

  getModuleById(id: string): EnvironmentModuleNode | undefined

  getModulesByFile(file: string): Set<EnvironmentModuleNode> | undefined

  onFileChange(file: string): void

  onFileDelete(file: string): void

  invalidateModule(
    mod: EnvironmentModuleNode,
    seen: Set<EnvironmentModuleNode> = new Set(),
    timestamp: number = Date.now(),
    isHmr: boolean = false,
  ): void

  invalidateAll(): void

  async ensureEntryFromUrl(
    rawUrl: string,
    setIsSelfAccepting = true,
  ): Promise<EnvironmentModuleNode>

  createFileOnlyEntry(file: string): EnvironmentModuleNode

  async resolveUrl(url: string): Promise<ResolvedUrl>

  updateModuleTransformResult(
    mod: EnvironmentModuleNode,
    result: TransformResult | null,
  ): void

  getModuleByEtag(etag: string): EnvironmentModuleNode | undefined
}

MITライセンスでリリースされています。(ccee3d7c)