Vite 8.0.1中shared选项'define'在构建模式下未按文档生效的问题排查
看起来你遇到的核心问题是Vite的define静态替换在build模式下未生效,导致__APP_VERSION__变成undefined。结合你的描述和Vite的工作机制,我整理了几个最可能的原因和对应的解决办法:
1. 检查define的配置位置是否正确
Vite的define是顶级配置项,不属于任何子选项(比如你提到的shared)。如果之前你把它嵌套在了optimizeDeps.shared或其他配置节点里,这会导致build时Vite无法识别这个配置。
正确的vite.config.ts配置结构应该是这样的:
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; import packageJson from './package.json'; export default defineConfig({ plugins: [vue()], // 这里是顶级的define配置,直接写在配置根节点 define: { __APP_VERSION__: JSON.stringify(packageJson.version), }, });
2. 避免使用globalThis调用全局变量
Vite的静态替换逻辑是扫描代码中的直接标识符(比如__APP_VERSION__),而不是globalThis.__APP_VERSION__这种属性访问写法。在build阶段的代码压缩/混淆过程中,globalThis.__APP_VERSION__可能不会被识别为需要替换的目标,最终保留为原写法,导致运行时取值为undefined。
修改你的ApplicationStore.ts代码,直接使用标识符:
state: () => ({ // ...其他状态 appVersion: __APP_VERSION__, // 去掉globalThis }),
3. 验证是否存在多环境配置冲突
如果你有针对build环境的单独配置文件(比如vite.config.prod.ts),要确保这个文件里也包含了define配置,否则build时会加载这个专用配置,忽略默认的vite.config.ts。
可以在package.json的build命令里明确指定配置文件,避免歧义:
{ "scripts": { "build": "vite build --config vite.config.ts" } }
替代方案:使用Vite环境变量(更稳妥)
如果上述调整后问题依旧,推荐改用Vite原生支持的环境变量方案,这种方式在开发和build模式下都能稳定工作,且无需依赖静态替换逻辑:
- 在
package.json的build脚本中动态注入版本号:
{ "scripts": { "build": "VITE_APP_VERSION=$npm_package_version vite build" } }
(Windows环境可以用set VITE_APP_VERSION=%npm_package_version% && vite build)
- 在代码中直接使用环境变量:
// ApplicationStore.ts state: () => ({ appVersion: import.meta.env.VITE_APP_VERSION, }),
这种方式不需要额外的define配置,也不用声明全局变量,完全符合Vite的生态规范。
验证方法
修改后,运行npm run build,然后打开dist目录下的打包文件,搜索版本号(比如1.0.0),如果能找到说明替换成功;如果还是看到__APP_VERSION__或undefined,再检查配置位置和代码写法是否正确。
内容的提问来源于stack exchange,提问作者BbMajor




