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…...

如何在react中使用react-monaco-editor渲染出一个编辑器
一、效果展示 二、基于vite配置 1.首先安装react-monaco-editor和monaco-editor包 npm add react-monaco-editor npm i monaco-editor 2.其次创建一个单独的文件(此处是tsx、直接用app或者jsx也行) import { useState, useEffect } from react impo…...

【Linux】Github 仓库克隆速度慢/无法克隆的一种解决方法,利用 Gitee 克隆 Github 仓库
Github 经常由于 DNS 域名污染以及其他因素克隆不顺利。 一种办法是修改 hosts sudo gedit /etc/hosts加上一行 XXX.XXX.XXX.XXX github.comXXX 位置的 IP 可以通过网站查询 IP/服务器github.com的信息-站长工具 这种方法比较适合本身可以克隆,但是速度很慢的…...

HarmonyOS Next 组件或页面之间的所有通信(传参)方法总结
系列文章目录 【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器(上) 【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器(下) 【鸿蒙】HarmonyOS NEXT应用开发快速入门教程之布局篇(上) 【…...

单片机学习笔记 1. 点亮一个LED灯
把基础的东西都过一下,用来学习记录一下。 目录 1、Keil工程 2、Keil实现代码 3、烧录程序 0、实现的功能 点亮一个LED灯 1、Keil工程 打开Keil,Project----New uVision Project,工程文件命名----OK 选择单片机类型AT89C52,和…...

Poetry 完整安装与项目环境搭建指南
Poetry 完整安装与项目环境搭建指南 1. Poetry 安装方式 1.1 pip 安装(推荐新手使用) # 使用 pip 安装 pip install poetry# 验证安装 poetry --version# 如果需要升级 pip install --upgrade poetry1.2 官方安装脚本 # Windows PowerShell (Invoke-…...

【MyBatis源码】MapperRegistry详解
🎮 作者主页:点击 🎁 完整专栏和代码:点击 🏡 博客主页:点击 文章目录 MapperRegistry 的作用核心字段解析整体工作流程addMapper方法MapperAnnotationBuilder#parse流程详解MapperAnnotationBuilder#parse…...

Java项目实战II基于Spring Boot的工作流程管理系统设计与实现(开发文档+数据库+源码)
目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。 一、前言 在当今快节奏的商业环境中,…...

flink StreamGraph 构造flink任务
文章目录 背景主要步骤代码 背景 通常使用flink 提供的高级算子来编写flink 任务,对底层不是很了解,尤其是如何生成作业图的细节 下面通过构造一个有向无环图,来实际看一下 主要步骤 1.增加source 2.增加operator 3. 增加一条边࿰…...

【51单片机】LCD1602液晶显示屏
学习使用的开发板:STC89C52RC/LE52RC 编程软件:Keil5 烧录软件:stc-isp 开发板实图: 文章目录 LCD1602存储结构时序结构 编码 —— 显示字符、数字 LCD1602 LCD1602(Liquid Crystal Display)液晶显示屏是…...

理解 HTML5 Canvas 中逻辑像素与物理像素的关系
理解 HTML5 Canvas 中逻辑像素与物理像素的关系 在使用 HTML5 Canvas 时,开发者经常会遇到一个困惑:为什么鼠标的 offsetX 和 offsetY 和我绘制的图形坐标对不上?这通常是因为 Canvas 的逻辑像素大小和物理像素大小不一致。本文将详细解释这…...