Vue 项目打包后环境变量丢失问题(清除缓存),区分.env和.env.*文件
Vue 项目打包后环境变量丢失问题(清除缓存),区分.env和.env.*文件
问题背景
今天在导报项目的时候遇到一个问题问题:在开发环境中一切正常,但在打包后的生产环境中,某些环境变量(如 VUE_APP_BASE_API)无法正确读取,导致出现 VUE_APP_BASE_API 不存在 的错误。

下面就解决这个问题,让环境变量在打包后的生产环境中能够正常使用,进行了进一步的思考衍生。
知识储备
要解决上面的问题需要,了解一下下面的内容
在开发 Vue 项目的过程中,使用环境变量来管理不同环境下的配置(例如 API 地址、密钥等)。
文件.env
开发环境和生产环境公用的一些配置
//.env
VUE_APP_NAME=red润
VUE_APP_BASE_API=/api2
VUE_APP_API_BASE_URL=https://本地开发地址.com
文件.env.productioin
生产环境单独使用的配置,如果和.env内容相同,.env.production将会覆盖.env里面的内容
VUE_APP_API_BASE_URL=https://线上域名.com
VUE_APP_BASE_API=/api
在 Vue CLI 中,环境变量的加载是有优先级的。当你运行构建命令时(如 npm run build),Vue CLI 会按以下顺序加载环境变量:
.env:基础的环境变量文件,通常包含开发、生产和测试等环境共享的变量。.env.local:如果存在,它会覆盖.env中的变量,适用于本地开发环境(注意:此文件通常不会提交到版本控制中)。.env.development或.env.production:这些文件用于特定环境(开发环境、生产环境等),会覆盖.env和.env.local中的相同变量。.env.development.local或.env.production.local:这些是针对特定环境的本地配置文件,会覆盖上述所有文件中的变量。
所以,在你的情况下,如果 .env.production 和 .env 中有相同的环境变量,process.env.VUE_APP_BASE_API 的值会使用 .env.production 中的值,而 .env 中的配置会被覆盖。
问题描述
在本地开发时,使用以下代码来引用环境变量:
const version = `${process.env.VUE_APP_BASE_API}`;
在开发环境下,process.env.VUE_APP_BASE_API 正常返回预期的值。
但是,当进行打包构建时,线上环境却出现了 VUE_APP_BASE_API 不存在 的错误,导致 API 请求无法正常发起。

问题原因
这个问题通常发生在 Vue CLI 构建项目时,它会自动根据不同环境加载不同的 .env 文件。如果 .env.production 或 .env 中没有正确配置环境变量,或者构建过程没有正确读取到这些变量,线上就无法获取到相应的环境变量。
解决方案
以下是几种常见的解决方法,我们可以逐一排查。
1. 确保 .env 文件配置正确
首先,确保你已经在项目根目录下创建了 .env 或 .env.production 文件,并且在文件中定义了所需要的环境变量。例如:
VUE_APP_BASE_API=https://your-api-endpoint.com
注意:Vue CLI 会自动加载以 VUE_APP_ 为前缀的环境变量。如果你的环境变量没有以 VUE_APP_ 开头,它将不会被嵌入到最终的构建中。
2. 清除缓存并重新打包(这是我的解决方案ok)
有时候旧的构建缓存可能导致环境变量没有被更新。为了确保环境变量被正确加载,可以尝试在打包时加上 --no-cache 标志:
enpm run build --no-cache
这将确保构建过程从头开始,而不会使用任何缓存文件。
3. 打包时检查环境变量
你可以在构建过程中使用 console.log(process.env) 来检查环境变量是否正确加载。可以在 src/main.js 或 src/App.vue 中添加以下代码来调试:
console.log(process.env); // 打印所有环境变量
这将帮助你确认构建后的代码中是否包含了你设置的 VUE_APP_BASE_API 变量。
4. 使用 webpack 的 DefinePlugin 明确注入环境变量(究极方案)
如果以上方法都没有解决问题,可以尝试通过 webpack 的 DefinePlugin 来显式地将环境变量注入到构建代码中:
// vue.config.js
const webpack = require('webpack');module.exports = {configureWebpack: {plugins: [new webpack.DefinePlugin({'process.env.VUE_APP_BASE_API': JSON.stringify(process.env.VUE_APP_BASE_API)})]}
}
这样,VUE_APP_BASE_API 将被直接注入到打包后的代码中,确保在生产环境中能够正常使用。
webpack.DefinePlugin用于在打包时,静态地将代码中的指定字符串替换为给定的值。它会查找代码中的匹配项,并将其替换为我们提供的值。这是一种预处理机制,允许你在构建时动态替换代码中的常量值。
在 Node.js 中,
process.env是一个包含所有环境变量的对象。在 Vue CLI 中,process.env主要用于访问不同的环境变量。像VUE_APP_BASE_API这样的变量通常在.env文件中定义,并通过process.env.VUE_APP_BASE_API来访问。
然而,
process.env只是 Node.js 的一个对象,Webpack 在构建过程中并不会自动注入这些环境变量。因此,使用DefinePlugin插件,可以手动将这些环境变量注入到构建代码中。
在
webpack.DefinePlugin中,值需要以字符串的形式提供,因为 Webpack 会在构建时进行替换。直接传递 JavaScript 的对象或变量是无效的,因此必须使用JSON.stringify()将process.env.VUE_APP_BASE_API的值转换为一个字符串,这样 Webpack 才能正确地将它嵌入到构建后的代码中。
例如,如果
.env中的VUE_APP_BASE_API为https://api.example.com,JSON.stringify()会将其转换为字符串'https://api.example.com',然后 Webpack 会将代码中所有process.env.VUE_APP_BASE_API的引用替换为这个字符串。
通过这种方式,Webpack 会在构建时查找代码中所有的
process.env.VUE_APP_BASE_API,并将其替换为https://api.example.com(或其他.env文件中定义的值)。
举个例子,假设你在 Vue 组件中使用以下代码:
const apiUrl = process.env.VUE_APP_BASE_API;
在构建时,Webpack 会将 process.env.VUE_APP_BASE_API 替换为你在 webpack.DefinePlugin 中定义的值,即:
const apiUrl = 'https://api.example.com';
5. 检查部署环境的环境变量配置
如果你使用 CI/CD 进行自动化构建,确保部署环境(例如 Docker、云平台等)中也已经配置了正确的环境变量。在一些部署平台中,你可能需要手动设置环境变量,以便构建过程能正确读取。
总结
通过上述方法,我们可以有效地解决 Vue 项目在打包后,环境变量丢失的问题。我们解决思路如下:
- 确保
.env文件正确配置。 - 清除缓存并重新打包。
- 使用
console.log(process.env)检查环境变量是否正常加载。 - 使用 webpack
DefinePlugin明确注入环境变量。 - 确保部署环境配置了正确的环境变量。
Happy coding!
😄
相关文章:
Vue 项目打包后环境变量丢失问题(清除缓存),区分.env和.env.*文件
Vue 项目打包后环境变量丢失问题(清除缓存),区分.env和.env.*文件 问题背景 今天在导报项目的时候遇到一个问题问题:在开发环境中一切正常,但在打包后的生产环境中,某些环境变量(如 VUE_APP_B…...
创建vue+electron项目流程
一个vue3和electron最基本的环境搭建步骤如下:// 安装 vite vue3 vite-plugin-vue-setup-extend less normalize.css mitt pinia vue-router npm create vuelatest npm i vite-plugin-vue-setup-extend -D npm i less -D npm i normalize.css -S ࿰…...
3. 用Ruby on Rails创建一个在线商城
哎呀,你这是想要我写一篇超长篇的Ruby on Rails教程啊!好吧,既然你这么热情,那我就勉为其难地给你来一篇生动有趣、充满比喻夸张讽刺修辞手法的教程吧! 1. 准备工作 1.1. 安装Ruby和Rails 1.1.1 安装Ruby 下载Ruby…...
jmeter常用配置元件介绍总结之配置元件
系列文章目录 1.windows、linux安装jmeter及设置中文显示 2.jmeter常用配置元件介绍总结之安装插件 3.jmeter常用配置元件介绍总结之线程组 4.jmeter常用配置元件介绍总结之函数助手 5.jmeter常用配置元件介绍总结之取样器 6.jmeter常用配置元件介绍总结之jsr223执行pytho…...
SpringBoot获取请求参数
spring boot获取请求参数 文章目录 spring boot获取请求参数一、简单参数二、实体参数三、数组集合参数四、日期参数五、Json参数六、路径参数 开头概述 在Spring Boot框架中,处理HTTP请求并获取请求参数是开发Web应用程序中的一项基本任务。无论是简单的GET请求还是…...
【数据结构】树——顺序存储二叉树
写在前面 在学习数据结构前,我们早就听说大名鼎鼎的树,例如什么什么手撕红黑树大佬呀,那这篇笔记不才就深入浅出的介绍二叉树。 文章目录 写在前面一、树的概念及结构1.1、数的相关概念1.2、数的表示1.3 树在实际中的运用(表示文…...
Android中perform和handle方法的区别——以handleLaunchActivity与performLaunchActivity为例
在Android系统中,perform和handle方法经常出现在关键流程中,分别承担不同的职责。这种命名约定反映了框架设计中的分层思想,帮助开发者区分任务的调度与实现。本文通过handleLaunchActivity和performLaunchActivity这两个典型方法的源码分析&…...
聊聊依赖性测试
在软件测试中,我们常常面临一个挑战:多个模块之间高度耦合,任何一个模块的异常都可能导致整个系统崩溃。如何确保这些模块之间的协作无缝衔接?这就需要依赖性测试的助力! 什么是依赖性测试?它与功能测试、…...
C++11————线程库
thread 类的简单介绍 在 c11 之前,涉及到多线程问题,都是和平台相关的,比如 windows 和 linux 下各自有自己的接口,这使得代码的可移植性比较差。在 c11 中引入了线程库,使得 c在编程时不需要依赖第三方库了 函数名 …...
Java 动态代理初步
动态代理初步 package ReflectExercise;import ReflectExercise.pojo.BigStar; import ReflectExercise.pojo.ProxyUtil; import ReflectExercise.pojo.Star;/*** 动态代理* 无侵入的给方法增强功能*/ public class ReflectExercise {public static void main(String[] args) {…...
应用系统开发(10) 钢轨缺陷的检测系统
涡流检测系统框图 其中信号发生器为一定频率的正弦信号作为激励信号,这个激励信号同时输入给交流电桥中的两个检测线圈,将两个线圈输出的电压差值作为差分信号引出至差分放大电路进行放大,经过放大后信号变为低频的缺陷信号叠加在高频载波上…...
理解 \r、\n、\r\n 和 \n\r:换行符的区别和用法
\r(回车,Carriage Return): ASCII 码 13,对应的控制字符是 CR,将光标回到当前行的行首(而不会换到下一行),之后的输出会把之前的输出覆盖。\n(换行,Line Feed)…...
【jvm】StringTable为什么要调整
目录 1. 永久代内存限制与回收效率2. 堆内存的优势3. JDK版本的演进4. 实际应用的考虑 1. 永久代内存限制与回收效率 1.内存限制:在JDK 6及之前的版本中,StringTable位于永久代(PermGen space)中。然而,永久代的内存空…...
AI 驱动低代码平台:开创智能化用户体验新纪元
一、引言 人工智能技术如汹涌浪潮般迅猛发展,在各个行业掀起了颠覆性的变革风暴。于软件开发领域而言,AI 辅助编程与低代码平台的完美结合已然成为关键趋势,极大地提高了开发效率。然而,低代码平台的使命绝非仅仅局限于简化开发流…...
谈一谈QThread::CurrentThread和this->thread
QThread::CurrentThread是指的当前函数调用者者所在的线程 this->thread是指的当前对象所在的线程(对象创建出来的时候所在的线程) Qt文档说明 CurrentThread返回一个指向管理当前执行线程的QThread的指针 thread返回对象所在的线程 这两个函数所…...
ThriveX 博客管理系统前后端项目部署教程
前端 前端项目地址:https://github.com/LiuYuYang01/ThriveX-Blog 控制端项目地址:https://github.com/LiuYuYang01/ThriveX-Admin Vercel 首先以 Vercel 进行部署,两种方式部署都是一样的,我们以前端项目进行演示 首先我们先…...
STM32单片机设计防儿童人员误锁/滞留车内警报系统
目录 目录 前言 一、本设计主要实现哪些很“开门”功能? 二、电路设计原理图 1.电路图采用Altium Designer进行设计: 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 近年来在车辆逐渐普及的情况下,由于家长的疏忽,将…...
可认证数据资产合约标准协议(CMIDA-1)意见征集
标准背景 数据资产具备多维度的属性,涵盖行业特性、状态信息、资产类型、存储格式等。数据资产在不同流通主体之间可理解、可流通、可追溯、可信任的重要前提之一是存在统一的标准,缺失统一的标准,数据混乱冲突、一数多源、多样多类等问题将…...
Cyberchef配合Wireshark提取并解析HTTP/TLS流量数据包中的文件
本文将介绍一种手动的轻量级的方式,还原HTTP/TLS协议中传输的文件,为流量数据包中的文件分析提供帮助。 如果捕获的数据包中存在非文本类文件,例如png,jpg等图片文件,或者word,Excel等office文件异或是其他类型的二进…...
MYSQL- 展示事件信息 EVENTS 语句(十八)
13.7.5.18 SHOW EVENTS 语句 SHOW EVENTS[{FROM | IN} schema_name][LIKE pattern | WHERE expr]此语句显示有关事件管理器事件的信息,这些信息在第23.4节“使用事件调度器”中进行了讨论。它要求显示事件的数据库具有EVENT权限。 以最简单的形式,SHOW…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...
二叉树-144.二叉树的前序遍历-力扣(LeetCode)
一、题目解析 对于递归方法的前序遍历十分简单,但对于一位合格的程序猿而言,需要掌握将递归转化为非递归的能力,毕竟递归调用的时候会调用大量的栈帧,存在栈溢出风险。 二、算法原理 递归调用本质是系统建立栈帧,而非…...
Python打卡训练营学习记录Day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
