使用 Environment
實例
實驗性功能
環境 API 為實驗性功能。我們將在 Vite 6 期間保持 API 的穩定性,讓生態系統可以實驗並在其之上建構。我們計劃在 Vite 7 中穩定這些新的 API,並可能會有重大變更。
資源
請與我們分享您的回饋。
存取環境
在開發期間,開發伺服器中可用的環境可以使用 server.environments
存取
// 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
類別的實例
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
為
interface DevEnvironmentContext {
hot: boolean
transport?: HotChannel | WebSocketServer
options?: EnvironmentOptions
remoteRunner?: {
inlineSourceMap?: boolean
}
depsOptimizer?: DepsOptimizer
}
其中 TransformResult
為
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 的使用者來說,更容易討論和理解。在發佈之前,我們也可以藉此機會檢閱這些名稱。例如,它可以命名為 environment.processModule(url)
或 environment.loadModule(url)
,從 Rollup 在外掛鉤子中的 context.load(id)
中獲取靈感。目前,我們認為保留目前的名稱並延後此討論會比較好。
獨立的模組圖表
每個環境都有一個獨立的模組圖表。所有模組圖表都具有相同的簽名,因此可以實作泛型演算法來爬取或查詢圖表,而無需依賴環境。hotUpdate
就是一個很好的例子。當檔案被修改時,每個環境的模組圖表將用於發現受影響的模組,並為每個環境獨立執行 HMR。
資訊
Vite v5 有一個混合的客戶端和 SSR 模組圖表。給定一個未處理或失效的節點,不可能知道它對應於客戶端、SSR 或兩個環境。模組節點有一些帶有前綴的屬性,例如 clientImportedModules
和 ssrImportedModules
(以及返回兩者聯合的 importedModules
)。importers
包含每個模組節點來自客戶端和 SSR 環境的所有匯入器。模組節點也有 transformResult
和 ssrTransformResult
。一個向後相容層允許生態系統從已棄用的 server.moduleGraph
遷移。
每個模組都由一個 EnvironmentModuleNode
實例表示。模組可能會在未經處理的情況下註冊到圖表中(在這種情況下,transformResult
將為 null
)。importers
和 importedModules
也會在模組處理後更新。
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
的實例
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
}