使用 Environment
实例
实验性
环境 API 是实验性的。我们仍将在主版本发布之间的 API 中保持稳定性,以允许生态系统进行实验和构建。我们计划在未来的主版本中稳定这些新 API(可能包含重大更改),以便下游项目有时间试验新功能并验证它们。
资源
请与我们分享您的反馈。
访问环境
在开发过程中,可以使用 server.environments
访问开发服务器中可用的环境
// create the server, or get it from the configureServer hook
const server = await createServer(/* options */)
const clientEnvironment = server.environments.client
clientEnvironment.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 有一个混合的 Client 和 SSR 模块图。给定一个未处理或无效的节点,不可能知道它对应于 Client、SSR 还是两个环境。模块节点有一些带有前缀的属性,例如 clientImportedModules
和 ssrImportedModules
(以及 importedModules
,它返回两者的并集)。 importers
包含每个模块节点来自 Client 和 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 = monotonicDateNow(),
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
}