在最近的 uniapp/Vue3 项目开发中,写下了这样一段代码:
// 获取热门推荐数据 const getHotRecommendData = async () => { const res = await getHotRecommendAPI(currHotMap!.url, { // 技巧:环境变量,开发环境,修改初始页面方便测试分页结束 page: import.meta.env.DEV ? 30 : 1, pageSize: 10, }) bannerPicture.value = res.result.bannerPicture subTypes.value = res.result.subTypes }其中import.meta.env.DEV ? 30 : 1这行代码想记下来解析。为什么在开发环境下要把页码写死成 30?这背后涉及到现代前端构建工具(尤其是 Vite)中非常重要的一个知识点:环境变量与模式。
一、import.meta:ES 模块的“自我认知”
要理解import.meta.env,首先得认识import.meta。
在早期的 JavaScript 开发中,我们往往无法在代码内部知道当前模块文件的具体信息(比如它的绝对路径是什么)。为了解决这个问题,ES2020 引入了import.meta这个语法。
import.meta是一个对象,它包含了当前模块的元数据。它的具体内容并不是由 ECMAScript 规范严格规定的,而是由宿主环境(比如浏览器、Node.js 或构建工具)来实现的。
比如,在浏览器原生 ES Module 中,import.meta.url会返回当前模块的绝对 URL 地址。
二、 Vite 的魔法:import.meta.env
当我们在 Vite 项目中编写代码时,Vite 作为构建工具接管了模块的解析。Vite 在import.meta上扩展了一个非常实用的属性:env。
import.meta.env是一个对象,包含了当前运行环境的信息。Vite 会在打包构建时,将import.meta.env对象进行静态替换。这意味着它不仅仅是运行时读取的一个变量,而是在编译阶段就被替换成了具体的值。
Vite 内置的环境变量
Vite 默认提供了几个非常实用的内置环境变量:
import.meta.env.MODE:应用运行的模式。默认情况下,开发环境(vite或vite dev)下它的值是'development',生产构建(vite build)下是'production'。import.meta.env.BASE_URL:部署应用时的基本 URL。由vite.config.js中的base配置项决定,常用于部署在非根目录下的应用。import.meta.env.PROD:布尔值,当前是否是生产环境。import.meta.env.SSR:布尔值,当前是否是服务端渲染环境。import.meta.env.DEV:布尔值,当前是否是开发环境(始终与import.meta.env.PROD相反)。
这就是我们代码中import.meta.env.DEV的来源。
三、 实战解析:为什么要在开发环境写死 page=30?
回到我们开头的代码:
page: import.meta.env.DEV ? 30 : 1,这段代码的作用是:如果当前是开发环境,请求接口时直接传 page=30;如果是生产环境,就传 page=1(正常从第一页开始请求)。
为什么要这么做?
在实际开发列表分页功能时,我们往往需要测试“没有更多数据”、“加载到底”的边界情况。如果每次都从第一页开始,我们需要在模拟器或浏览器里手动一直往下拉,触发多次onReachBottom,直到滑到第 30 页才能看到“没有更多数据”的 UI 提示。这在开发调试时极其耗时。
通过import.meta.env.DEV,我们在开发环境下“作弊”,直接让接口请求第 30 页的数据。这样一进入页面,就能瞬间触发到底逻辑,方便我们快速调整 UI 和调试逻辑。
而当项目运行vite build打包发布到线上时,由于DEV变为false,代码会被编译成page: 1,完全不影响真实用户的体验。
这其实是前端工程化中“开发体验优化(DX, Developer Experience)”的一个极佳体现。
四、 进阶:如何自定义环境变量?
除了内置变量,我们在实际开发中经常需要配置诸如 API 接口地址、第三方 SDK 的 AppKey 等环境相关的变量。Vite 同样支持自定义环境变量。
1. 使用.env文件
Vite 支持在项目根目录下创建以下文件来定义环境变量:
.env:所有环境都会加载的默认配置。.env.local:所有环境都会加载,但会被 git 忽略。.env.[mode]:只有在指定模式下才会加载(如.env.development,.env.production)。
2. 必须添加VITE_前缀
为了防止意外将敏感信息暴露给客户端,Vite 规定:只有以VITE_开头的环境变量才会被暴露给客户端代码。
假设我们在.env.development文件中写入:
VITE_API_BASE_URL=http://localhost:3000/api VITE_APP_TITLE=我的测试应用然后在代码中就可以这样使用:
console.log(import.meta.env.VITE_API_BASE_URL) // http://localhost:3000/api console.log(import.meta.env.VITE_APP_TITLE) // 我的测试应用3. TypeScript 类型提示
在 TypeScript 项目中,直接访问import.meta.env.VITE_XXX可能会报类型错误。为了获得完美的代码提示,我们需要在src/vite-env.d.ts(如果没有则新建)中扩展ImportMetaEnv接口:
/// <reference types="vite/client" /> interface ImportMetaEnv { readonly VITE_API_BASE_URL: string readonly VITE_APP_TITLE: string // 还可以添加其他自定义变量 } interface ImportMeta { readonly env: ImportMetaEnv }配置完成后,在业务代码中输入import.meta.env.时,IDE 就会自动提示你定义的变量,大幅提升开发效率和代码安全性。
总结
import.meta.env是现代前端构建工具提供的一把利器,它完美桥接了代码与运行环境。
通过合理使用import.meta.env.DEV以及自定义的VITE_变量,我们不仅能轻松区分开发/生产环境的 API 配置,还能像本文开头那样,编写出提升开发体验的“小技巧”代码。
其他:
【前端知识点总结】为何及如何为Axios需要区分环境?https://blog.csdn.net/weixin_52047874/article/details/156098360?ops_request_misc=elastic_search_misc&request_id=e5aea2c535594438a3f89fd1b2e63775&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~ElasticSearch~search_v3-1-156098360-null-null.541^v3^pc_search_result_blog1&utm_term=%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83&spm=1018.2226.3001.4450