首页
/ Vite 6 Environment API:形式化多环境配置,打通 Dev 与 Build 的运行时鸿沟

Vite 6 Environment API:形式化多环境配置,打通 Dev 与 Build 的运行时鸿沟

2026-09-06 10:04:24作者:宣聪麟

Environment API 是 Vite 6 引入的核心架构能力:它将原本隐含的 client / ssr 两个环境抽象为一等公民,让框架作者和运行时提供方可以注册任意多个、各自贴近生产运行时约束的环境实例。读完本文,你将理解 Environment API 的设计动机(如何缩小 dev 与 build 之间的行为差异)、environments 配置项的继承规则与选项结构、通过 createEnvironment 提供自定义环境实例的底层机制,以及 Vite 5 用户迁移时需要注意的向后兼容边界。

什么是 Environment API:Vite 6 对“环境”的形式化

根据官方文档 api-environment.md 的说明,Environment API 目前处于 Release Candidate(RC)阶段:Vite 会在主版本之间保持这些 API 的稳定,以便生态实验和基于其构建,但部分具体 API 仍被视为实验性(参见 changes 索引中的 Considering 列表)。Vite 计划在未来某个主版本中(可能伴随破坏性变更)最终稳定这些 API。

在 Vite 5 及之前,只有两个隐式环境:client 和可选的 ssr。Vite 6 将“环境(Environment)”概念形式化后,用户和框架作者可以创建尽可能多的环境,去精确映射应用在生产中的实际运行方式。文档明确指出,这一能力背后是一次大规模的代码内部重构,同时团队投入了大量精力保证向后兼容;Vite 6 的首要目标是让整个生态平滑迁移到新主版本,而非急于让所有用户立即采用新 API。

缩小 Build 与 Dev 之间的鸿沟

对 SPA/MPA 应用:行为完全不变。 对配置层面,Vite 6 没有为这类简单场景暴露任何环境相关的新 API——配置项内部被应用到 client 环境,但配置 Vite 时完全不需要知道这个概念的存在,Vite 5 的配置与行为可以无缝沿用。

对典型的 SSR 应用:两个环境。 典型服务端渲染应用会拥有两个环境:

  • client:在浏览器中运行应用;
  • ssr:在 Node(或其他服务端运行时)中运行,在页面发送给浏览器之前完成渲染。

Dev 模式下多环境并发运行的架构。 在开发阶段,Vite 过去是在与 dev server 相同的 Node 进程中执行服务端代码,这只是生产环境的一种近似。但服务端代码也可能运行在其他 JS 运行时中(例如 Cloudflare 的 workerd),这些运行时拥有不同的约束条件;现代应用甚至可能同时运行在浏览器、Node 服务器和边缘服务器三种环境里——Vite 5 无法正确表达这些环境。

Vite 6 的核心改进是:在 dev 和 build 两个阶段都可以配置应用的全部环境,并且单个 Vite dev server 现在可以并发运行多套不同环境的代码。具体而言,在共享的 HTTP server、中间件、已解析配置和插件管线之上,dev server 现在持有一组相互独立的 dev 环境实例;每个实例都被配置得尽可能贴近生产环境,并连接到一个 dev 运行时来执行代码(例如 workerd 环境的服务端代码可以在本地通过 miniflare 运行)。浏览器端由浏览器负责 import 并执行代码,其他环境则由 module runner 拉取并求值转换后的代码:

Vite Environments 架构图:dev server 在共享的 HTTP server、中间件与插件管线之上承载多个独立的 dev 环境,分别连接浏览器与各类 dev 运行时

从源码结构看,这一“非 client 环境连接 dev 运行时”的设计有明确落点:packages/vite/src/node/config.ts#L272-L274 中的 defaultCreateDevEnvironment 对所有非 client 环境调用 createRunnableDevEnvironment(即可运行的、通过 ModuleRunner 执行代码的环境),而 packages/vite/src/node/config.ts#L260-L270 中的 defaultCreateClientDevEnvironment 则创建带 HMR 通道、直接由浏览器 import 代码的标准 client 环境。

环境配置:environments 选项与继承规则

SPA/MPA 配置保持 Vite 5 形态

对 SPA/MPA 应用,配置与 Vite 5 类似——这些选项在内部用于配置 client 环境:

export default defineConfig({
  build: {
    sourcemap: false,
  },
  optimizeDeps: {
    include: ['lib'],
  },
})

文档强调这一设计的意义:保持 Vite 的低门槛(approachable),在确实需要之前不暴露新概念。

多环境应用通过 environments 显式声明

当应用由多个环境组成时,用 environments 配置项显式配置:

export default {
  build: {
    sourcemap: false,
  },
  optimizeDeps: {
    include: ['lib'],
  },
  environments: {
    server: {},
    edge: {
      resolve: {
        noExternal: true,
      },
    },
  },
}

选项继承规则

未在文档中特别说明的情况下,环境会继承顶层配置选项。上例中新建的 serveredge 环境都会继承 build.sourcemap: false。但有少数顶层选项只作用于 client 环境——例如 optimizeDeps,因为它作为服务端环境的默认值并不合理,这些选项在 配置参考 中带有 NonInherit 徽章。client 环境本身也可以通过 environments.client 显式配置,但官方推荐继续用顶层选项配置 client,这样在新增环境时 client 配置可以保持不变。

EnvironmentOptions 的完整结构

文档中给出的接口概览是:

interface EnvironmentOptions {
  define?: Record<string, any>
  resolve?: EnvironmentResolveOptions
  optimizeDeps: DepOptimizationOptions
  consumer?: 'client' | 'server'
  dev: DevOptions
  build: BuildOptions
}

结合源码可以看到更完整的划分。EnvironmentOptionspackages/vite/src/node/config.ts#L335-L344 中定义为 SharedEnvironmentOptions 加上 dev / build 两个分支。其中共用的 SharedEnvironmentOptions 还包括:

  • input:该环境的应用入口(相对项目根目录解析);
  • consumer:标记环境消费方,'client''server',非 client 环境默认按 'server' 处理;
  • keepProcessEnv:为 true 时代码中的 process.env 保留原样、在运行时求值,否则被静态替换为空对象;
  • isBundled(实验性):显式声明该环境是否产出 bundle 化输出——build 时所有环境默认为 true,serve 时仅当启用 experimental.bundledDev 时 client 环境为 true,其余为 false

dev 专属选项 DevEnvironmentOptions 包括:

  • warmup:待预转换的文件列表,支持 glob;
  • preTransformRequests:是否预转换已知直接依赖,client 环境默认 true,其余环境默认 false
  • sourcemap / sourcemapIgnoreList:dev 阶段 sourcemap 控制,以及生成 x_google_ignoreList 忽略列表的规则(默认排除 node_modules 路径);
  • createEnvironment低层钩子,自定义 Dev Environment 实例的创建(后文详述);
  • recoverable(实验性):对支持 full-reload 的环境(如 client),在重启服务器时可提前中断当前文件处理;
  • moduleRunnerTransform:标记该环境关联 module runner——client 默认 false,非 client 环境默认 true

build 专属选项 BuildEnvironmentOptions 定义在 packages/vite/src/node/build.ts#L92(如 outDir 等)。另外,optimizeDeps 虽只作用于 dev,但出于向后兼容保留了顶层位置,而非嵌套在 dev 下。

UserConfig 与环境生命周期

UserConfig 继承自 EnvironmentOptions,使顶层配置同时充当 client 配置和其他环境的默认值(通过 environments 选项覆盖):

interface UserConfig extends EnvironmentOptions {
  environments: Record<string, EnvironmentOptions>
  // other options
}

这一点在源码中得到印证:packages/vite/src/node/config.ts#L370UserConfig extends DefaultEnvironmentOptions,而配置解析阶段通过 packages/vite/src/node/config.ts#L1722-L1726 的循环对 config.environments 中的每个环境逐一调用 resolveEnvironmentOptions,产出 resolvedEnvironments 记录。

各阶段环境的存在规则:

  • dev 阶段client 和一个名为 ssr 的服务端环境始终存在,用于兼容 server.ssrLoadModule(url)server.moduleGraph
  • build 阶段client 环境始终存在;ssr 环境仅在显式配置时存在(通过 environments.ssr,或出于向后兼容通过 build.ssr)。应用并不必须叫 ssr,可以命名为 server 等任意名字。

注意:顶层 ssr 属性将在 Environment API 稳定后被弃用。它的作用与 environments 相同,但仅面向默认的 ssr 环境,且只允许配置一小部分选项。

自定义环境实例:供运行时提供方接入

对于运行时提供方(runtime providers),Vite 暴露了低层配置 API,使其能提供带有正确运行时默认值的环境。这些环境甚至可以在 dev 阶段派生其他进程或线程来运行模块,从而得到一个更接近生产环境的运行时。文档给出的例子是 Cloudflare Vite 插件:它使用 Environment API 在开发期间将代码运行在 Cloudflare Workers 运行时(workerd)中,通过运行时时提供方的 customEnvironment 助手完成注册:

import { customEnvironment } from 'vite-environment-provider'

export default {
  build: {
    outDir: '/dist/client',
  },
  environments: {
    ssr: customEnvironment({
      build: {
        outDir: '/dist/ssr',
      },
    }),
  },
}

在 Vite 内核侧,这一能力的落点是 dev.createEnvironment 选项:packages/vite/src/node/config.ts#L235-L242 中它接收 (name, config, context),可返回任意 Promise<DevEnvironment> | DevEnvironment。从源码结构看,Vite 内置了 defaultCreateClientDevEnvironmentdefaultCreateDevEnvironment 两条默认路径,运行时提供方则通过该钩子完全替换实例创建逻辑(customEnvironment 本身来自运行时时提供方的独立包,不在 Vite 仓库源码内)。

向后兼容性

官方文档明确列出了当前的兼容边界:

  • 当前 Vite server API 尚未弃用,与 Vite 5 向后兼容;
  • server.moduleGraph 返回 client 与 ssr 模块图的混合视图,其所有方法都会返回向后兼容的混合模块节点;传入 handleHotUpdate 的模块节点采用相同方案。

文档同时建议暂不迁移到 Environment API:目标是先让足够多的用户采用 Vite 6,避免插件需要维护两个版本的 API。关于未来弃用与升级路径,仓库中对应的 change 文档包括:

目标读者与配套指南

api-environment.md 面向最终用户讲解环境的基本概念;仓库中还按角色拆分为三份进阶指南:

  • 插件作者:Environment API for Plugins 介绍了统一的按环境 API——this.environment 上下文、configEnvironment / hotUpdate / applyToEnvironment 钩子,以及构建阶段的共享插件管线(sharedDuringBuild);
  • 框架作者:Environment API for Frameworks 讲解以编程方式暴露环境的框架侧用法;
  • 运行时提供方:Environment API for Runtimes 说明如何向框架和用户交付自定义环境。

小结与适用前提

Environment API 的本质,是把 Vite dev server 从“一个面向浏览器 + 一个近似 Node 的 SSR 环境”重构为“共享管线之上 N 个独立、可贴近生产的 dev 环境”。当前使用它的前提是接受 RC 阶段的定位:API 在主版本间保持稳定但个别部分仍实验性,顶层 ssr 选项未来会弃用,build 阶段各环境共享插件管线需通过 builder.sharedConfigBuild / sharedDuringBuild 显式开启。普通 SPA/MPA 项目可以完全无感;而构建多运行时应用(浏览器 + Node + 边缘)的团队,则应结合 api-environment.md 与三份角色指南,规划从 Vite 5 到 Environment API 的迁移路径。

登录后查看全文
热门项目推荐
相关项目推荐