Vite resolve.conditions 怎么选择 browser 和 development 条件导出
来源:17golang原创
时间:2026-11-05 16:01:23 431浏览 收藏
我在接入一个同时提供浏览器实现和调试实现的依赖时,最容易误判的不是 Vite 配置语法,而是把“平台条件”和“运行模式条件”混成了一件事。开发服务器拿到的文件可能带调试信息,生产构建则应拿到更轻的实现;如果只盯着 browser,就很难解释两次解析为什么不同。
官方地址:https://vite.dev/config/shared-options
先记住结论:浏览器项目通常保留 Vite 的客户端默认条件,再让 development|production 随模式替换。只有确实要支持额外条件时,才扩展列表;不要用一个自定义字符串去代替包本身声明的 import、browser 或 default。
为什么开发环境和生产构建会拿到不同文件
一个依赖可以在 package.json 的 exports 中声明多层条件。Vite 当前客户端默认值包含 module、browser 和特殊值 development|production;它会根据 process.env.NODE_ENV 把最后一个值替换成 development 或 production。import、require、default 在满足条件时也会参与解析。
{
"exports": {
".": {
"browser": {
"development": "./dist/browser-dev.js",
"production": "./dist/browser-prod.js"
},
"default": "./dist/universal.js"
}
}
}
这个结构先表达“浏览器平台”,再表达“开发或生产模式”。条件对象的键顺序有意义,越具体的分支越应该放在前面;default 是兜底,不要把它放到会提前命中的位置。图中用静态关系把五类条件和最终出口拆开,便于看出 browser 并不会自动等于 development。

先判断问题到底出在平台还是模式
我通常先把现象分成两类。若浏览器构建误拿了 Node 依赖,优先看 browser 分支和是否存在 default;若开发和生产只差调试开关、错误信息或日志,则看 development 与 production 的嵌套关系。
第二个判断是入口形式。Vite 的 resolve.conditions 是参与 Conditional Exports 的允许条件,不是把任意字符串写进 exports 就能让包自动切换。包必须先声明相同的条件名;否则配置加了也没有匹配对象。
import { defineConfig } from 'vite'
export default defineConfig(({ mode }) => ({
// 用 mode 记录当前构建意图,条件选择仍由 Vite 处理
define: {
__BUILD_MODE__: JSON.stringify(mode),
},
resolve: {
// 自定义条件要与依赖的 exports 键完全一致
conditions: ['module', 'browser', 'development|production'],
},
}))
这里没有额外条件,所以显式写出客户端默认值只是为了让配置意图清楚。真正需要扩展时,再把例如 worker 之类的包作者条件加进去,并确认它不会让同一个依赖在不同入口之间漂移。
resolve.conditions 应该怎么写
如果你的目标只是普通浏览器应用,优先采用默认行为,不要为了“保险”写一串重复条件。若项目确实有额外出口,可以把默认客户端条件和自定义条件放在同一份配置里:
import { defineConfig } from 'vite'
export default defineConfig({
resolve: {
// 保留客户端解析基础,再追加包作者明确声明的条件
conditions: [
'module',
'browser',
'development|production',
'worker',
],
},
})
这里的关键不是数组越长越好,而是每个条件都能在依赖的 exports 中找到对应分支。Node 文档还强调了嵌套条件和对象键顺序:先写更具体的组合,再写通用的 default。因此,条件命名和顺序应由包作者与消费方共同约定。

几个容易把判断带偏的边界
- 不要把 browser 当成 mainFields。
resolve.mainFields是查找 package.json 顶层字段的另一套机制;如果exports已经成功解析,它优先级更高。 - 不要省略 default。 包面向未知 JavaScript 环境时,通用回退能减少环境伪装带来的兼容问题。
- 留意 SSR。 客户端条件与 SSR 的目标不同,服务端构建不应机械复制浏览器条件;先看该构建的 resolve 配置和依赖出口。
- 检查 NODE_ENV 来源。 Vite 文档规定特殊值会根据
process.env.NODE_ENV替换,不要把“执行了 vite build”简单等同于所有自定义脚本都已设置同样环境变量。
最后用一张表收口
| 现象 | 优先查看 | 处理方向 |
|---|---|---|
| 浏览器拿到 Node 实现 | browser、default | 确认包声明了浏览器分支,并保留通用回退 |
| 开发和生产入口不同 | development|production | 检查 NODE_ENV 与嵌套条件顺序 |
| 新增条件完全不生效 | 条件名、exports 键顺序 | 让配置字符串与包声明逐字一致 |
所以,Vite 的 resolve.conditions 更像一张“允许参与匹配的条件清单”,不是切换文件的开关面板。先按平台、模式、模块形式拆分问题,再决定是否扩展配置,通常比不断增加条件更快找到真正的入口。
相关问题
只配置 browser,为什么开发和生产仍然不同?
因为模式条件可能仍然参与匹配;browser 只说明平台,不能替代 development 与 production 的分支。
自定义条件可以随便命名吗?
可以使用包作者和工具链约定的字符串,但消费方配置必须与 exports 中的键完全一致,并明确它的优先级与回退路径。
default 应该放在哪里?
在同一条件对象中通常放在更具体分支之后,作为未知环境仍能使用的通用入口。
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
420 收藏
-
164 收藏
-
258 收藏
-
251 收藏
-
121 收藏
-
237 收藏
-
219 收藏
-
204 收藏
-
251 收藏
-
文章 · 前端 | 12小时前 | 前端 · ReadableStream WebTransport HTTP/3 QUIC WritableStream WebTransport datagrams331 收藏
-
500 收藏
-
489 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习