Vue配置:环境变量
一、process.env 与核心环境变量基础概念
1.1 process.env 的定义与本质
process.env 是 Node.js 运行时提供的一个全局环境对象,其本质是存储当前系统环境变量信息的键值对集合。
核心特性:
- 属于 Node.js 原生 API,仅在 Node.js 环境(如项目构建过程、后端服务)中可直接访问,浏览器环境本身不内置此对象。
- 包含系统级环境变量(如操作系统的 PATH、用户信息等)和项目自定义环境变量(如通过 .env 文件配置的变量)。
访问方式:
- 在 Node.js 终端中,可直接输入
node进入交互模式,再输入process.env查看所有环境变量;也可通过process.env.变量名单独获取某个变量(如process.env.PATH)。 - 在 Vue 项目中,通过 webpack 的
DefinePlugin插件(Vue CLI 自动集成),部分变量(如NODE_ENV、VUE_APP_*前缀变量)会被注入到客户端代码中,因此在前端 JS/Vue 组件中可直接通过process.env.变量名访问。
- 在 Node.js 终端中,可直接输入
1.2 NODE_ENV 变量的作用与默认行为
NODE_ENV 是一个约定俗成的环境变量,主要用于标识当前项目运行的环境(如开发、测试、生产),并影响构建工具的行为。
核心作用:
- 指导构建工具优化:在
production模式下,webpack 会自动开启代码压缩、Tree-Shaking、删除调试信息等优化;在development模式下,会保留源码格式、启用热重载和详细错误提示。 - 控制业务逻辑:开发者可根据
NODE_ENV的值动态切换业务行为(如开发环境使用模拟数据,生产环境调用真实 API)。
- 指导构建工具优化:在
默认行为:
- Node.js 本身不自带 NODE_ENV 变量,需手动设置或由框架自动配置。
- Vue CLI 会根据运行模式自动设置 NODE_ENV:
- 执行
vue-cli-service serve时,默认设为'development'; - 执行
vue-cli-service build时,默认设为'production'; - 执行
vue-cli-service test:unit时,默认设为'test'。
- 执行
- 若需自定义,可在 .env 配置文件中显式声明(如
NODE_ENV='staging'),或通过命令行临时设置(如NODE_ENV=production npm run build)。
1.3 Vue CLI 的环境模式(Mode)体系
Vue CLI 中的“模式”是一套环境配置方案,用于区分不同场景(如开发、测试、生产)的环境变量和构建行为,每个模式对应一套专属配置。
1.3.1 默认三种模式及对应场景
Vue CLI 内置三种默认模式,分别对应不同的开发阶段:
development(开发模式):
- 触发命令:
vue-cli-service serve(即npm run serve或npm run dev)。 - 场景:本地开发调试,启用热重载(HMR)、源码映射(source map)、详细错误日志,优先加载
.env.development配置文件。
- 触发命令:
production(生产模式):
- 触发命令:
vue-cli-service build(打包生产环境代码)、vue-cli-service test:e2e(端到端测试)。 - 场景:项目上线部署,自动开启代码压缩、优化依赖打包、禁用调试工具,优先加载
.env.production配置文件。
- 触发命令:
test(测试模式):
- 触发命令:
vue-cli-service test:unit(单元测试)。 - 场景:单元测试执行,环境配置需适配测试框架(如 Jest),禁用部分开发工具,优先加载
.env.test配置文件。
- 触发命令:
1.3.2 模式与 NODE_ENV 的关联规则
模式与 NODE_ENV 紧密关联,但模式的范围更广(可包含更多环境变量),具体关联规则如下:
- 模式名称直接决定 NODE_ENV:执行命令时通过
--mode指定模式名称后,NODE_ENV 会默认被设为该模式名称(如vue-cli-service serve --mode staging会使NODE_ENV='staging')。 - 默认映射关系:若未显式指定 NODE_ENV,三种默认模式会自动映射:
development模式 →NODE_ENV='development';production模式 →NODE_ENV='production';test模式 →NODE_ENV='test'。
- 显式覆盖:可在模式对应的配置文件(如
.env.staging)中通过NODE_ENV='production'显式指定 NODE_ENV,覆盖默认映射(例如让staging模式使用production级别的构建优化)。 - 灵活性:模式支持自定义(如
staging、sit等),一个 NODE_ENV 可对应多个模式(如production.sit、production.uat模式均使用NODE_ENV='production'),满足多环境部署需求。
二、Vue 环境配置文件(.env 系列)详解
2.1 .env 系列文件的类型与用途
.env 系列文件是 Vue 项目中管理环境变量的核心载体,根据适用范围和模式可分为全局配置文件和模式专属配置文件,各自承担不同场景的配置需求:
2.1.1 全局配置文件
.env:所有环境通用的基础配置文件,无论项目运行在何种模式(开发、生产、测试等),都会优先加载该文件中的变量。适合存放所有环境共用的配置(如通用的 API 路径前缀、静态资源域名等)。
例:若所有环境的静态图片域名均为https://static.example.com,可在.env中配置VUE_APP_STATIC_DOMAIN='https://static.example.com'。.env.local:作用域与
.env一致(所有环境通用),但会被 Git 自动忽略(需确保.gitignore中包含该文件)。专门用于存储私有或敏感配置(如本地开发的密钥、个人测试账号等),避免提交到代码仓库泄露信息。
例:本地开发时连接私有数据库的密码DB_PASSWORD='123456',可放在.env.local中。
2.1.2 模式专属配置文件
.env.[mode]:仅在指定模式(
mode)下加载的配置文件,用于区分不同环境的特有配置。模式由 Vue CLI 的命令或--mode参数指定(如development、production、staging等)。
例:开发环境需启用 mock 服务,可在.env.development中配置VUE_APP_USE_MOCK=true;生产环境关闭 mock,在.env.production中配置VUE_APP_USE_MOCK=false。.env.[mode].local:仅在指定模式下加载,且同样被 Git 忽略。用于存储特定模式下的私有配置,优先级高于同模式的
.env.[mode]。
例:测试环境(staging模式)的私有 API 密钥,可在.env.staging.local中配置VUE_APP_STAGING_KEY='xxx'。
2.2 配置文件的命名规则与约束
.env 系列文件的命名有严格规范,需与 Vue CLI 的模式机制严格匹配,否则会导致配置无法加载:
- 文件名固定不可自定义:默认模式(
development、production、test)对应的配置文件必须严格命名为.env.development、.env.production、.env.test,不可简写(如.env.dev、.env.prod均不被识别)。 - 自定义模式需匹配文件名:若通过
--mode [modeName]指定自定义模式(如--mode sit),则必须创建对应的.env.[modeName]文件(如.env.sit),否则 Vue CLI 无法加载该模式的配置。 - 区分大小写:文件名中的模式部分(
[mode])大小写敏感,例如.env.Staging与.env.staging会被视为不同文件,需与命令中--mode指定的模式名称完全一致。
2.3 配置文件的加载优先级
Vue CLI 加载 .env 系列文件时,会按照“模式专属 > 全局、local 后缀 > 非 local 后缀”的规则确定变量优先级,具体顺序如下(优先级从高到低):
- 系统环境变量:优先级最高,若系统中已存在同名环境变量(如操作系统设置的
NODE_ENV),会直接覆盖配置文件中的变量。 - 模式专属 local 文件:
.env.[mode].local(如.env.development.local),仅在指定模式生效,且为私有配置。 - 模式专属文件:
.env.[mode](如.env.development),仅在指定模式生效,非私有配置。 - 全局 local 文件:
.env.local,所有模式通用,私有配置。 - 全局文件:
.env,所有模式通用,非私有配置。
示例:若同时存在 .env(配置 VUE_APP_API='common')和 .env.development(配置 VUE_APP_API='dev'),在 development 模式下,最终生效的是 .env.development 中的 VUE_APP_API='dev';若再存在 .env.development.local(配置 VUE_APP_API='dev-local'),则优先使用 dev-local。
2.4 配置文件的语法规则
.env 系列文件的语法需遵循特定格式,否则变量可能无法被正确解析或嵌入客户端代码:
2.4.1 基础键值对格式
- 变量需以
KEY=VALUE格式定义,等号前后不可有空格(若 VALUE 含空格,需用单引号或双引号包裹)。
正确示例:VUE_APP_TITLE='My App'、PORT=8080;
错误示例:VUE_APP_TITLE = 'My App'(等号后有空格)、PORT =8080(等号前有空格)。 - 支持注释:以
#开头的行视为注释,不会被解析。例如:# 开发环境 API 地址 VUE_APP_BASE_API='/api'
2.4.2 VUE_APP_ 前缀变量的特殊意义
Vue CLI 通过 webpack.DefinePlugin 将环境变量嵌入客户端代码(浏览器可访问),但仅支持以下变量:
- 内置变量:
NODE_ENV(环境标识)、BASE_URL(应用部署基础路径,与vue.config.js中publicPath一致)。 - 自定义变量:必须以
VUE_APP_为前缀(如VUE_APP_API_KEY、VUE_APP_UPLOAD_URL),否则无法在客户端(如 Vue 组件、JS 文件)中通过process.env访问。
注意:非 VUE_APP_ 前缀的变量(如 PORT、DB_HOST)仅在 Node 环境(如 vue.config.js、构建脚本)中生效,客户端无法访问。
2.4.3 特殊内置变量
NODE_ENV:用于标识当前环境,由模式自动或手动配置。
- 若未手动指定,模式与
NODE_ENV自动映射(development模式 →NODE_ENV=development,production模式 →NODE_ENV=production)。 - 可在配置文件中手动修改(如
.env.staging中配置NODE_ENV='staging'),但不建议覆盖默认模式的映射(可能影响构建优化,如生产模式的代码压缩)。
- 若未手动指定,模式与
BASE_URL:对应应用部署的基础路径,默认值为
/,与vue.config.js中的publicPath保持一致。- 若在配置文件中修改
BASE_URL(如BASE_URL='/admin/'),需确保vue.config.js中publicPath: process.env.BASE_URL,否则可能导致静态资源路径错误。 - 常用于多环境部署(如开发环境部署在根路径
/,生产环境部署在子路径/admin/)。
- 若在配置文件中修改
三、Vue CLI 命令与环境模式的关联配置
3.1 默认 CLI 命令对应的环境模式
Vue CLI 内置了多条核心命令,每条命令默认绑定特定的环境模式(Mode),并自动加载对应模式的配置文件,从而实现不同环境下的参数隔离。
3.1.1 开发环境命令
- 核心命令:
npm run serve(或npm run dev,取决于package.json中scripts配置),本质执行vue-cli-service serve。 - 默认模式:
development(开发模式)。 - 配置文件加载:自动加载全局配置文件(
.env、.env.local)和开发模式专属文件(.env.development、.env.development.local)。 - NODE_ENV 默认值:
'development'(由模式自动映射)。 - 适用场景:本地开发调试,支持热重载(HMR),代码未压缩,包含详细的错误提示。
3.1.2 生产环境命令
- 核心命令:
npm run build,本质执行vue-cli-service build。 - 默认模式:
production(生产模式)。 - 配置文件加载:自动加载全局配置文件(
.env、.env.local)和生产模式专属文件(.env.production、.env.production.local)。 - NODE_ENV 默认值:
'production'(由模式自动映射)。 - 特性与场景:代码会被压缩、混淆和优化(如 tree-shaking),生成可直接部署的
dist目录;适用于正式环境上线前的打包。
3.1.3 测试环境命令
Vue CLI 针对不同测试类型绑定了不同模式:
单元测试:命令为
vue-cli-service test:unit(通常配置为npm run test:unit)。- 默认模式:
test(测试模式)。 - 配置文件加载:加载
.env、.env.local、.env.test、.env.test.local。 - 场景:用于 Jest 或 Mocha 等框架的单元测试,环境配置需适配测试工具(如禁用部分生产环境优化)。
- 默认模式:
端到端测试:命令为
vue-cli-service test:e2e(通常配置为npm run test:e2e)。- 默认模式:
production(生产模式)。 - 原因:端到端测试模拟真实用户操作,需基于接近生产环境的打包结果(代码已优化),因此复用生产模式配置。
- 默认模式:
3.2 自定义环境模式与 --mode 参数
当默认的development、production、test模式无法满足需求(如多测试环境:SIT、UAT 等)时,可通过自定义模式扩展,并通过--mode参数指定。
3.2.1 自定义模式配置文件创建
命名规则:需创建与模式名匹配的配置文件,格式为
.env.[modeName](公开配置)或.env.[modeName].local(私有配置,被 git 忽略)。文件内容:需包含模式相关的环境变量,其中:
- 自定义业务变量必须以
VUE_APP_为前缀(如VUE_APP_API_URL='http://sit-api.example.com'); - 可显式指定
NODE_ENV(如NODE_ENV='staging'),若不指定则默认与模式名一致(如--mode sit对应NODE_ENV='sit')。
- 自定义业务变量必须以
示例:创建测试环境(SIT)配置文件
.env.sit:NODE_ENV='sit' VUE_APP_BASE_API='/sit-api' BASE_URL_REAR='http://192.168.1.100:8080' # 后端服务地址(仅 Node 环境可见)
3.2.2 命令中指定模式
- 语法格式:
vue-cli-service [command] --mode [modeName],通过--mode参数强制指定当前模式。 - 执行逻辑:
- 忽略命令默认模式,优先加载
[modeName]对应的配置文件(如--mode sit加载.env.sit); - 配置文件加载顺序仍遵循“模式专属文件 > 全局文件”“带.local 后缀 > 不带”(见 2.3 节);
- 系统环境变量优先级最高,不会被配置文件覆盖。
- 忽略命令默认模式,优先加载
- 示例:
- 开发环境使用自定义模式:
vue-cli-service serve --mode sit(加载.env.sit,用于本地模拟 SIT 环境调试); - 打包测试环境:
vue-cli-service build --mode uat(加载.env.uat,生成 UAT 环境部署包)。
- 开发环境使用自定义模式:
3.3 package.json 中 scripts 的配置优化
通过在package.json的scripts中预定义关联模式的命令,可简化开发流程,避免重复输入--mode参数,同时明确命令对应的环境。
配置原则
- 为不同环境的命令添加清晰的后缀(如
build:prod、serve:sit),直观区分环境; - 将
vue-cli-service命令与--mode参数绑定,固化模式与命令的关联。
示例配置与解析
"scripts": {
"serve": "vue-cli-service serve", // 默认开发模式(development)
"serve:sit": "vue-cli-service serve --mode sit", // 开发模式运行 SIT 环境配置
"build:prod": "vue-cli-service build --mode production", // 生产环境打包
"build:sit": "vue-cli-service build --mode sit", // SIT 环境打包
"test:unit": "vue-cli-service test:unit", // 默认测试模式(test)
"test:e2e:prod": "vue-cli-service test:e2e --mode production" // 生产模式下端到端测试
}- 优势:
- 简化命令:开发者直接执行
npm run build:sit即可打包 SIT 环境,无需记忆--mode参数; - 环境明确:通过命令后缀(如
:prod、:sit)直观区分目标环境,减少配置错误; - 团队协作:统一命令规范,避免因模式输入不一致导致的环境问题。
- 简化命令:开发者直接执行
跨平台兼容补充
若需在命令中直接设置环境变量(如临时覆盖NODE_ENV),需借助cross-env工具解决 Windows 与 Unix 系统的语法差异:
- 安装:
npm install --save-dev cross-env; - 配置示例:
"serve:debug": "cross-env NODE_ENV=debug vue-cli-service serve --mode debug",确保不同系统均可正常解析变量。
四、环境变量在 Vue 项目中的实际应用
4.1 环境变量的访问方式
环境变量在 Vue 项目中可在不同场景下访问,核心是通过 process.env 对象获取,但需遵循一定规则,具体场景如下:
4.1.1 JS 文件中访问
在 JavaScript 文件(如工具函数、路由配置、状态管理文件等)中,可直接通过 process.env.变量名 访问环境变量,适用于初始化配置、逻辑判断等场景。
工具函数:例如封装日期格式化工具时,根据环境决定是否输出调试信息
// utils/date.js export function formatDate(date) { // 开发环境打印原始日期数据 if (process.env.NODE_ENV === 'development') { console.log('原始日期:', date); } // 格式化逻辑... }路由配置:根据环境动态配置路由(如开发环境添加测试路由)
// router/index.js import VueRouter from 'vue-router'; const routes = [ { path: '/home', component: Home } ]; // 开发环境添加测试路由 if (process.env.NODE_ENV === 'development') { routes.push({ path: '/test', component: Test }); } export default new VueRouter({ routes });状态管理(Vuex):在 store 中根据环境初始化状态
// store/index.js import Vuex from 'vuex'; export default new Vuex.Store({ state: { // 开发环境默认开启调试模式 debugMode: process.env.NODE_ENV === 'development' } });
4.1.2 Vue 组件中访问
在 Vue 组件的模板或脚本中访问环境变量时,需注意模板语法的限制(不能直接使用 process.env),需通过组件实例属性间接引用。
- Script 部分:在
data、computed或methods中直接使用process.envexport default { data() { return { // 从环境变量获取 API 地址 apiUrl: process.env.VUE_APP_BASE_API, // 根据环境显示不同标题 pageTitle: process.env.NODE_ENV === 'production' ? '正式系统' : '测试系统' }; }, computed: { // 计算属性中使用环境变量 isDebug() { return process.env.VUE_APP_DEBUG === 'true'; } } }; - Template 部分:需通过组件实例属性(如
data或computed定义的变量)访问,不能直接写process.env<template> <div> <!-- 正确:使用 data 中定义的变量 --> <p>API 地址:{{ apiUrl }}</p> <!-- 错误:模板中不能直接使用 process.env --> <!-- <p>错误示例:{{ process.env.VUE_APP_BASE_API }}</p> --> <!-- 使用 computed 属性控制显示 --> <button v-if="isDebug">调试按钮</button> </div> </template>
4.2 特殊变量的应用场景
Vue 中存在两类特殊环境变量:NODE_ENV 和 BASE_URL,它们有固定用途和关联规则,具体应用如下:
4.2.1 NODE_ENV 用于环境判断
NODE_ENV 由 Vue CLI 根据模式自动设置(如 development/production/自定义模式名),主要用于区分环境并执行差异化逻辑,常见场景包括:
- API 地址切换:开发环境使用本地代理,生产环境使用正式接口
let baseURL; switch (process.env.NODE_ENV) { case 'development': baseURL = '/api'; // 开发环境:配合 devServer.proxy 转发 break; case 'production': baseURL = 'https://api.example.com'; // 生产环境:正式接口 break; case 'staging': baseURL = 'https://staging.api.example.com'; // 测试环境:预发布接口 break; } - 日志输出控制:开发环境打印详细日志,生产环境关闭日志以优化性能
function log(message) { if (process.env.NODE_ENV !== 'production') { console.log('[日志]', message); } } - 功能开关:仅在开发/测试环境启用调试功能(如 Vue Devtools 提示、数据模拟)
// main.js if (process.env.NODE_ENV === 'development') { console.log('当前为开发环境,启用 Vue Devtools'); Vue.config.devtools = true; // 强制开启 Devtools }
4.2.2 BASE_URL 与部署路径配置
BASE_URL 与 vue.config.js 中的 publicPath 一致,代表应用部署的基础路径,主要用于:
- 静态资源引用:在 HTML 或组件中引用静态资源时,使用
BASE_URL确保路径正确<!-- public/index.html 中引用 favicon --> <link rel="icon" href="<%= BASE_URL %>favicon.ico"><!-- 组件中引用图片 --> <template> <img :src="`${BASE_URL}images/logo.png`" alt="logo"> </template> <script> export default { data() { return { BASE_URL: process.env.BASE_URL }; } }; </script> - 适配多环境部署路径:不同环境的部署路径可能不同(如开发环境根目录
/,生产环境子目录/admin/),通过publicPath与BASE_URL联动配置// vue.config.js module.exports = { publicPath: process.env.BASE_URL || '/' // 读取环境变量中的 BASE_URL };# .env.production(生产环境部署到 /admin/ 目录) BASE_URL=/admin/
4.3 网络请求中的环境变量应用(axios 封装)
在网络请求(尤其是 axios)中,环境变量常用于动态配置请求基础地址、超时时间、拦截器逻辑等,实现多环境请求适配。
4.3.1 动态设置 axios baseURL
通过环境变量 VUE_APP_BASE_API 动态指定请求基础地址,避免硬编码,简化多环境切换。
- 基础封装:
// utils/request.js import axios from 'axios'; const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // 从环境变量获取基础地址 timeout: process.env.VUE_APP_TIMEOUT ? Number(process.env.VUE_APP_TIMEOUT) : 5000 // 动态超时时间 }); export default service; - 多环境配置示例:
# .env.development(开发环境:使用代理路径) VUE_APP_BASE_API=/api VUE_APP_TIMEOUT=10000 # 开发环境超时时间更长 # .env.production(生产环境:正式接口地址) VUE_APP_BASE_API=https://api.example.com VUE_APP_TIMEOUT=5000
4.3.2 拦截器中的环境变量应用
在 axios 拦截器中结合环境变量实现差异化逻辑(如错误处理、请求头附加环境标识)。
- 响应拦截器:开发环境显示详细错误,生产环境统一提示
// utils/request.js service.interceptors.response.use( response => response.data, error => { if (process.env.NODE_ENV === 'development') { // 开发环境:打印完整错误信息 console.error('请求错误:', error); } else { // 生产环境:显示用户友好提示 alert('网络异常,请稍后重试'); } return Promise.reject(error); } ); - 请求拦截器:附加环境标识供后端区分
service.interceptors.request.use(config => { // 向后端传递当前环境(如用于日志区分) config.headers['X-Env'] = process.env.NODE_ENV; return config; });
4.3.3 跨域代理与环境变量结合
开发环境通常通过 devServer.proxy 解决跨域,结合环境变量动态配置代理目标,避免硬编码后端地址。
// vue.config.js
module.exports = {
devServer: {
proxy: {
// 以 VUE_APP_BASE_API 为代理标识(如 /api)
[process.env.VUE_APP_BASE_API]: {
target: process.env.VUE_APP_PROXY_TARGET, // 代理目标地址(从环境变量获取)
changeOrigin: true, // 开启跨域
pathRewrite: {
[`^${process.env.VUE_APP_BASE_API}`]: '' // 移除路径中的代理标识
}
}
}
}
};# .env.development
VUE_APP_BASE_API=/api
VUE_APP_PROXY_TARGET=http://192.168.1.100:8080 # 开发环境后端地址五、基于环境变量的跨域配置与部署
5.1 跨域场景的环境变量配置思路
跨域问题的本质是浏览器的“同源策略”限制(协议、域名、端口任一不同即视为跨域),而前后端分离架构中,开发、测试、生产等环境的服务地址往往不同(如开发环境用本地后端服务,生产环境用线上服务器),需针对不同环境配置跨域解决方案。
环境变量在此场景中的核心价值是实现跨域配置的“环境隔离”与“动态切换”,具体思路如下:
- 统一配置入口:将不同环境的后端服务地址(如开发环境
http://192.168.3.100、测试环境http://test-api.example.com、生产环境http://prod-api.example.com)定义在对应环境的.env文件中(如BASE_URL_REAR变量),避免硬编码在代码中。 - 区分环境策略:
- 开发环境:通常通过前端本地服务器(如
vue-cli-service serve启动的服务)配置代理(devServer.proxy),转发请求至后端服务,规避跨域限制。 - 生产环境:若前后端部署在同源地址(同域名+端口),无需额外配置;若不同源,需依赖后端通过CORS(跨域资源共享)配置允许前端域名访问,此时前端直接使用生产环境的后端地址即可。
- 开发环境:通常通过前端本地服务器(如
- 减少配置修改成本:通过环境变量关联跨域相关参数(如代理路径、目标地址),切换环境时仅需修改
.env文件或通过--mode指定模式,无需改动核心代码(如vue.config.js或请求封装逻辑)。
5.2 代理配置与环境变量结合
vue.config.js中的devServer.proxy用于配置开发环境的请求代理,而环境变量可使其配置更灵活,适配不同环境的后端服务。具体结合方式如下:
5.2.1 代理路径配置
代理路径即需要被代理的请求前缀(如/api),通常通过VUE_APP_BASE_API环境变量定义,原因是:
- 该变量会被注入客户端代码,可同时用于前端请求封装(如axios的
baseURL)和代理路径匹配,确保前后端请求路径一致。 - 示例:在
.env.development中配置VUE_APP_BASE_API='/api',则所有以/api开头的请求(如/api/user/login)会被代理。
5.2.2 代理目标配置
代理目标即后端服务的实际地址(如http://127.0.0.1:8080),通过自定义环境变量(如BASE_URL_REAR)定义,优势是:
- 不同环境的目标地址可在对应
.env文件中独立配置(如开发环境BASE_URL_REAR='http://192.168.3.100',测试环境BASE_URL_REAR='http://test-api.example.com')。 - 无需修改
vue.config.js即可切换代理目标,降低配置维护成本。
5.2.3 完整配置示例与解析
// vue.config.js
module.exports = {
devServer: {
proxy: {
// 以VUE_APP_BASE_API为代理路径(如'/api')
[process.env.VUE_APP_BASE_API]: {
target: process.env.BASE_URL_REAR, // 代理目标地址(从环境变量获取)
changeOrigin: true, // 开启跨域:修改请求头中的Host为目标地址,避免后端校验域名
pathRewrite: {
// 去除请求路径中的代理前缀(如将'/api/user'重写为'/user',匹配后端实际接口路径)
['^' + process.env.VUE_APP_BASE_API]: ''
}
}
}
}
};- 核心逻辑:当前端发起
/api/user请求时,代理服务器会将其转发至BASE_URL_REAR/user,同时隐藏前端真实域名,使后端认为请求来自同源,从而规避跨域限制。
5.3 不同环境的跨域部署实例
不同环境的网络架构和跨域需求不同,结合环境变量的部署配置实例如下:
5.3.1 开发环境(本地开发)
- 场景:前端运行在
http://localhost:8080,后端运行在http://192.168.3.100:7001(不同IP,跨域)。 - 环境变量配置(
.env.development):VUE_APP_BASE_API='/api' # 前端请求前缀,用于匹配代理 BASE_URL_REAR='http://192.168.3.100:7001' # 后端服务地址 - 跨域处理:通过
vue.config.js的devServer.proxy配置代理,如5.2.3示例,前端请求/api/user会被转发至http://192.168.3.100:7001/user,实现跨域通信。
5.3.2 生产环境(线上部署)
- 场景:前端部署在
https://www.example.com,后端部署在https://api.example.com(不同子域名,跨域)。 - 环境变量配置(
.env.production):VUE_APP_BASE_API='https://api.example.com' # 直接使用后端完整地址,无需代理 - 跨域处理:后端通过CORS配置允许
https://www.example.com访问(如设置响应头Access-Control-Allow-Origin: https://www.example.com),前端直接请求https://api.example.com/user,浏览器认可跨域请求。
5.3.3 测试环境(服务器部署)
- 场景:前端部署在测试服务器
http://test-web.example.com,后端部署在http://test-api.example.com(跨域)。 - 环境变量配置(
.env.staging):VUE_APP_BASE_API='/api' # 若测试服务器支持代理,可保留前缀 BASE_URL_REAR='http://test-api.example.com' # 测试后端地址 - 跨域处理:若测试服务器(如Nginx)配置了代理,可沿用开发环境的代理逻辑;若未配置代理,需后端开启CORS,前端直接使用
VUE_APP_BASE_API='http://test-api.example.com'。
通过环境变量与跨域配置的结合,可实现“一套代码,多环境适配”,大幅降低不同环境下的配置成本和出错概率。
六、NODE_ENV 的进阶配置与兼容
6.1 系统级 NODE_ENV 配置
系统级 NODE_ENV 配置是指在操作系统层面直接设置环境变量,其作用范围覆盖当前系统中所有运行的 Node.js 程序,优先级高于项目内的 .env 配置文件(根据环境变量加载规则,系统级环境变量优先级最高)。以下是不同系统的具体操作及注意事项:
6.1.1 Windows 系统
Windows 系统中,环境变量的操作需区分终端类型(CMD、PowerShell),具体方式如下:
- 查看 NODE_ENV:
- CMD 终端:
set NODE_ENV(若已设置,会显示NODE_ENV=xxx;未设置则无输出)。 - PowerShell 终端:
$env:NODE_ENV(直接返回当前值,未设置则返回空)。
- CMD 终端:
- 设置 NODE_ENV:
- CMD 终端:
set NODE_ENV=production(临时生效,关闭终端后失效)。 - PowerShell 终端:
$env:NODE_ENV = "production"(临时生效,语法需用双引号包裹值)。 - 永久生效:通过“控制面板→系统→高级系统设置→环境变量”,在“用户变量”或“系统变量”中添加
NODE_ENV键值对(需重启终端生效)。
- CMD 终端:
- 删除 NODE_ENV:
- CMD 终端:
set NODE_ENV=(清空变量值)。 - PowerShell 终端:
Remove-Item Env:NODE_ENV(彻底删除变量)。
- CMD 终端:
注意:Windows 系统中,设置环境变量时等号前后不能有空格(如set NODE_ENV = production会导致值包含空格,引发错误)。
6.1.2 Linux/macOS 系统
Linux 和 macOS 基于 Unix 内核,终端(如 bash、zsh)操作环境变量的语法一致:
- 查看 NODE_ENV:
echo $NODE_ENV(未设置则输出空行)。 - 设置 NODE_ENV:
- 临时生效:
export NODE_ENV=production(当前终端会话有效,关闭后失效)。 - 永久生效:
- 对当前用户生效:在
~/.bashrc、~/.bash_profile或~/.zshrc(根据终端类型)中添加export NODE_ENV=production,执行source ~/.bashrc(或对应文件)立即生效。 - 对所有用户生效:在
/etc/profile中添加上述命令(需管理员权限)。
- 对当前用户生效:在
- 临时生效:
- 删除 NODE_ENV:
unset NODE_ENV(彻底删除变量)。
注意:Unix 系统中,变量值若包含空格需用单引号包裹(如export NODE_ENV='production test')。
6.2 webpack.DefinePlugin 手动配置
webpack.DefinePlugin 是 webpack 内置的插件,用于在编译阶段将自定义变量注入到客户端代码中(即前端 JS 可直接访问)。在非 Vue CLI 项目(如原生 webpack 配置项目)中,需手动通过该插件配置 NODE_ENV 等变量,确保前端代码能根据环境执行不同逻辑。
核心作用
- 将 Node.js 环境的变量(如
process.env.NODE_ENV)“注入”到前端代码中,使得浏览器环境中可直接使用process.env.NODE_ENV判断环境。 - 示例场景:开发环境启用日志打印,生产环境关闭;根据环境切换 API 地址等。
配置示例与解析
// webpack.config.js
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.DefinePlugin({
// 注意:值必须用 JSON.stringify 处理,否则会被当作变量而非字符串
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'), // 默认为 development
VUE_APP_CUSTOM: JSON.stringify('自定义变量') // 支持自定义变量
}
})
]
};关键说明:
JSON.stringify必要性:若直接写NODE_ENV: process.env.NODE_ENV,webpack 会将其替换为变量引用(如production),而前端代码中会解析为process.env.NODE_ENV = production(缺少引号,导致语法错误);用JSON.stringify处理后,会被替换为'production'(正确的字符串格式)。- 适用场景:原生 webpack 项目、需要深度自定义 webpack 配置的场景(Vue CLI 项目通常无需手动配置,因 CLI 已自动处理)。
6.3 cross-env 解决跨平台兼容
不同操作系统(Windows、Linux、macOS)在 npm 脚本中设置环境变量的语法存在差异,导致跨平台开发时脚本执行报错。cross-env 是一个 Node.js 工具,可统一环境变量的设置语法,屏蔽系统差异。
问题背景
- Windows(CMD)中设置环境变量:
set NODE_ENV=production && webpack。 - Unix 系统(Linux/macOS)中设置环境变量:
NODE_ENV=production webpack。 - 直接在
package.json中写 Unix 语法的脚本(如"build": "NODE_ENV=production webpack"),在 Windows 上会报错(无法识别NODE_ENV=production命令)。
解决方案:使用 cross-env
安装:作为开发依赖安装(仅需在开发环境使用)
npm install --save-dev cross-env配置 npm 脚本:在脚本中用
cross-env包裹环境变量设置,语法统一为cross-env NODE_ENV=xxx 命令// package.json "scripts": { "dev": "cross-env NODE_ENV=development webpack-dev-server", "build": "cross-env NODE_ENV=production webpack" }原理:
cross-env在 Node.js 层面解析环境变量设置,根据当前操作系统自动转换为对应语法(如 Windows 下转为set命令,Unix 下转为export命令),确保脚本在所有系统中正常运行。
6.4 Vue CLI 3 + 的自动配置机制
Vue CLI 3 及以上版本对 NODE_ENV 及环境变量的处理进行了封装,大幅简化了配置流程,开发者无需手动操作 webpack.DefinePlugin 或跨平台兼容,核心机制如下:
自动关联模式与 NODE_ENV
- Vue CLI 通过“模式(Mode)”自动设置
NODE_ENV:- 运行
vue-cli-service serve时,默认模式为development,NODE_ENV自动设为'development'。 - 运行
vue-cli-service build时,默认模式为production,NODE_ENV自动设为'production'。 - 自定义模式(如
--mode staging)时,NODE_ENV自动设为模式名称(即'staging'),除非在.env.staging中显式配置NODE_ENV=xxx覆盖。
- 运行
自动注入环境变量到客户端
Vue CLI 会自动通过 webpack.DefinePlugin 将以下变量注入到客户端代码(前端可直接访问 process.env.xxx):
NODE_ENV:由模式自动设置(或在.env文件中显式配置)。BASE_URL:与vue.config.js中的publicPath一致,用于配置应用部署路径。- 所有以
VUE_APP_为前缀的变量(如VUE_APP_BASE_API):自定义业务变量需遵循此命名规则,否则无法在客户端访问。
对打包优化的影响
NODE_ENV 的值会直接影响 Vue CLI 的打包行为:
production模式:启用代码压缩(TerserPlugin)、Tree-Shaking(删除未使用代码)、Scope Hoisting(减少代码体积)等优化,生成最小化的生产环境代码。development模式:关闭压缩,保留源代码映射(source map),便于开发调试。
注意事项
- 无需手动在
webpack.config.js中配置DefinePlugin,Vue CLI 已内置处理逻辑,手动配置可能导致冲突。 - 若需扩展 webpack 配置(如添加自定义变量),可在
vue.config.js中通过configureWebpack或chainWebpack实现,例如:// vue.config.js module.exports = { configureWebpack: { plugins: [ new webpack.DefinePlugin({ 'process.env.CUSTOM_VAR': JSON.stringify('自定义值') }) ] } };
七、Vue 环境配置实战案例
7.1 多环境 axios baseURL 封装
该案例的核心是通过 process.env.NODE_ENV 区分不同环境,动态设置 axios 的基础请求路径(baseURL),避免硬编码导致的环境切换维护成本,是前端网络请求适配多环境的经典方案。
1. 实现原理
NODE_ENV由 Vue CLI 的环境模式(Mode)自动决定,不同模式对应不同的.env配置文件(如development模式对应.env.development),其值会被嵌入客户端代码中,可直接在 JS 中通过process.env.NODE_ENV访问。- 基于
NODE_ENV的不同取值(如development、production、testing),为 axios 分配不同的baseURL,实现“开发用代理、生产用真实接口、测试用测试服务器”的自动切换。
2. 详细步骤
步骤1:创建
baseURL.js配置文件
集中管理不同环境的baseURL,通过switch语句根据NODE_ENV分支判断:// src/utils/baseURL.js let baseURL = ''; switch (process.env.NODE_ENV) { case 'development': // 开发环境:通常配置为 '/api',配合 vue.config.js 的代理转发解决跨域 baseURL = '/api'; break; case 'production': // 生产环境:使用后端真实接口地址(如线上服务器域名) baseURL = 'https://api.example.com'; break; case 'testing': // 测试环境:使用测试服务器接口地址 baseURL = 'https://test.api.example.com'; break; default: // 默认 fallback 到开发环境配置 baseURL = '/api'; } export default baseURL;步骤2:在 axios 实例中引入
baseURL
在 axios 封装时直接使用上述配置,确保所有请求自动适配当前环境:// src/utils/request.js import axios from 'axios'; import baseURL from './baseURL'; // 导入环境对应的 baseURL const service = axios.create({ baseURL: baseURL, // 动态注入环境对应的基础路径 timeout: 5000 // 超时配置 }); // 可添加请求/响应拦截器(如 token 携带、错误处理等) service.interceptors.request.use( config => { // 示例:添加 token 到请求头 config.headers.Authorization = localStorage.getItem('token'); return config; }, error => Promise.reject(error) ); export default service;步骤3:在业务代码中使用封装的 axios
直接导入封装好的service发起请求,无需关心环境差异:// src/api/user.js import service from '@/utils/request'; // 登录接口(自动适配当前环境的 baseURL) export const login = (data) => { return service.post('/user/login', data); };
3. 关键注意事项
- 环境变量生效条件:
NODE_ENV的值由运行/打包命令的模式决定(如npm run serve对应development,npm run build对应production,npm run build:test需手动配置testing模式)。 - 代理配合:开发环境的
baseURL: '/api'需与vue.config.js的devServer.proxy配置匹配,确保请求被转发到后端服务:// vue.config.js module.exports = { devServer: { proxy: { '/api': { // 匹配 baseURL 中的 '/api' target: 'http://localhost:3000', // 后端开发服务器地址 changeOrigin: true, // 开启跨域代理 pathRewrite: { '^/api': '' } // 移除请求路径中的 '/api' 前缀 } } } };
7.2 自定义环境(.env.itmei)实战
当默认的 development、production、test 三种模式无法满足需求(如需要“预发布”“演示环境”等)时,可通过自定义模式(Mode)扩展环境配置,该案例以 itmei 模式为例展示完整流程。
1. 自定义环境的核心价值
- 解决多场景环境隔离问题:例如区分“生产正式环境”“生产测试环境”“内部演示环境”等,每个环境可独立配置接口地址、端口、功能开关等参数。
- 配置集中化:所有环境相关参数(如接口前缀、代理目标、端口)统一维护在
.env文件中,避免代码中分散判断。
2. 详细步骤
步骤1:创建自定义环境配置文件
新建.env.itmei文件(文件名必须为.env.[mode],其中mode为自定义模式名称itmei),配置环境变量:# .env.itmei # 模式标识(非必须,用于业务逻辑判断) ENV='itmei' # 开发服务器端口(仅在 Node 环境生效,如 vue.config.js) port=8088 # 客户端可访问的接口基础路径(需带 VUE_APP_ 前缀) VUE_APP_BASE_API='/itmei-api' # 代理目标地址(后端服务地址,仅在 Node 环境生效) BASE_URL_REAR='http://127.0.0.1:8080/'步骤2:在
package.json中配置运行脚本
通过--mode参数指定自定义模式,简化命令输入:// package.json "scripts": { "dev:itmei": "vue-cli-service serve --mode itmei" // 运行该命令时,会加载 .env.itmei 配置 }步骤3:在项目中使用自定义环境变量
客户端代码中访问(需
VUE_APP_前缀):
在 Vue 组件或 JS 文件中,通过process.env.VUE_APP_BASE_API获取接口前缀:// src/utils/request.js const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // 自动获取 '/itmei-api' timeout: 5000 });Node 环境中访问(如
vue.config.js):
非VUE_APP_前缀的变量(如port、BASE_URL_REAR)可在 Node 环境配置中使用:// vue.config.js module.exports = { devServer: { port: process.env.port, // 使用 .env.itmei 中的 8088 端口 proxy: { [process.env.VUE_APP_BASE_API]: { // 匹配 '/itmei-api' target: process.env.BASE_URL_REAR, // 代理到 'http://127.0.0.1:8080/' changeOrigin: true, pathRewrite: { ['^' + process.env.VUE_APP_BASE_API]: '' } } } } };
步骤4:运行自定义环境
执行npm run dev:itmei,项目会以itmei模式启动:- 开发服务器端口为 8088(而非默认的 8080);
- 接口请求路径前缀为
/itmei-api; - 所有请求会被代理到
http://127.0.0.1:8080/。
3. 关键注意事项
.local文件的使用:若需存储私有配置(如密钥、测试账号),可创建.env.itmei.local,该文件会被 Git 忽略(需确保.gitignore中包含.local规则)。- 变量作用域:
- 带
VUE_APP_前缀的变量可在客户端代码(组件、JS 文件)中访问; - 其他变量(如
port、BASE_URL_REAR)仅在 Node 环境(vue.config.js、构建脚本)中生效。
- 带
7.3 打包后 dist 文件预览
Vue 项目通过 npm run build 打包后会生成 dist 目录,直接双击 index.html 打开会因路径解析问题报错,需通过服务器环境预览,验证打包结果是否符合预期。
1. 直接打开 dist/index.html 报错的原因
- 路径解析问题:打包后的资源(JS、CSS、图片)路径默认基于
publicPath配置(默认值为'/'),在本地文件协议(file://)下,绝对路径会被解析为本地文件系统路径(如file:///css/app.css),导致资源加载失败。 - 路由模式影响:若使用
vue-router的history模式,直接打开index.html会因浏览器无法识别路由路径而返回 404。
2. 有效的预览方法
方法1:使用 VS Code Live Server 插件
- 安装插件:在 VS Code 扩展商店搜索 “Live Server” 并安装。
- 启动预览:右键
dist/index.html,选择 “Open with Live Server”,插件会自动启动本地服务器(默认端口 5500),并在浏览器中打开http://127.0.0.1:5500/dist/index.html。 - 原理:通过 HTTP 协议访问资源,路径解析符合
publicPath配置,避免本地文件协议的限制。
方法2:使用
serve工具(推荐)- 安装工具:全局安装
serve(基于 Node.js 的轻量服务器):npm install -g serve - 启动服务:在项目根目录执行以下命令,
serve会将dist目录作为静态资源根目录:serve -s dist - 访问预览:根据终端提示的地址(如
http://localhost:3000)在浏览器中打开,支持history路由模式。
- 安装工具:全局安装
3. 预览的核心目的
- 验证资源加载:检查 JS、CSS、图片等静态资源是否正确引入,避免打包时路径配置错误(如
publicPath设置不当)。 - 测试路由跳转:确认
vue-router在生产环境下的跳转逻辑是否正常(尤其是history模式)。 - 验证环境变量:检查打包后的代码是否正确注入了目标环境的变量(如生产环境的
VUE_APP_BASE_API是否为真实接口地址)。
4. 注意事项
publicPath配置适配:若项目需部署到服务器子目录(如https://example.com/admin/),需在vue.config.js中设置publicPath: '/admin/',打包后预览时需确保服务器路径与之一致。- 接口跨域验证:预览时若涉及接口请求,需确保生产环境的接口已配置跨域允许(或通过服务器代理),避免因跨域导致请求失败。
八、注意事项与常见问题详细说明
8.1 环境文件修改后需重启服务
- 核心原因:Vue CLI 在启动命令(如
npm run serve)执行时,会一次性读取所有环境配置文件(.env 系列)并将变量注入到process.env中,此过程为“启动时加载”,而非“实时监测”。 - 现象:若修改了 .env 文件(如调整
VUE_APP_BASE_API地址),未重启服务的情况下,客户端代码中访问的process.env仍为修改前的旧值,新配置不会生效。 - 解决方式:修改环境文件后,必须通过
ctrl + c终止当前服务,再重新运行npm run serve(或对应模式的启动命令,如npm run dev:itmei),使新配置被重新加载。 - 常见误区:部分开发者误以为环境变量像代码热更新一样实时生效,实则因环境变量属于项目启动时的“全局注入配置”,不支持动态更新。
8.2 .env.local 的 git 忽略规则
- 设计目的:
.env.local及.env.[mode].local文件用于存储私有/敏感配置(如 API 密钥、数据库密码、第三方服务令牌等),这类信息不应提交到代码仓库(避免泄露)。 - git 忽略配置:Vue 项目默认的
.gitignore文件已包含对.local后缀文件的忽略规则(如*.local),但需确保项目中已正确配置,若未包含需手动添加:# 忽略所有 .local 环境文件 .env.local .env.*.local - 风险提示:若误将
.env.local提交到仓库,需立即从版本库中删除(使用git rm --cached .env.local),并及时更新敏感信息(如重新生成密钥),避免安全漏洞。 - 使用场景:同一团队不同开发者的本地个性化配置(如本地代理目标地址)、生产环境的私有部署参数等,适合放在
.local文件中。
8.3 模式不存在的错误处理
- 错误场景:当通过
--mode指定不存在的模式(如vue-cli-service serve --mode test01,但未创建.env.test01文件)时,会触发配置加载异常。 - 加载逻辑:Vue CLI 会按优先级尝试加载配置文件,顺序为:
不存在的模式文件 → 全局文件(.env→.env.local)→ 系统环境变量。
若全局文件(.env或.env.local)也不存在,则无任何环境变量被加载,可能导致依赖环境变量的代码报错。 - 错误表现:常见错误如
TypeError: Cannot read property 'upgrade' of undefined(多因代理配置依赖未加载的环境变量),或客户端代码中process.env.VUE_APP_XXX为undefined。 - 解决方式:
- 检查模式名称拼写(如
staging误写为stage); - 为指定模式创建对应配置文件(如
--mode test01需创建.env.test01); - 若暂时无需专属配置,可在
.env中定义通用变量作为兜底。
- 检查模式名称拼写(如
8.4 非 VUE_APP_前缀变量无法嵌入客户端
- 底层原理:Vue CLI 通过 webpack 的
DefinePlugin将环境变量注入客户端代码,但仅对特定变量生效:- 内置变量:
NODE_ENV(环境标识)、BASE_URL(部署基础路径); - 自定义变量:必须以
VUE_APP_为前缀(如VUE_APP_API_KEY)。
非前缀变量(如port=8081、DB_PASSWORD=123)仅在 Node 环境(如vue.config.js)中可访问,不会被注入客户端代码。
- 内置变量:
- 环境差异:
- Node 环境(如
vue.config.js):可访问所有环境变量(包括非前缀变量),例如process.env.port可用于配置 devServer 端口; - 客户端环境(组件、JS 业务文件):仅能访问
NODE_ENV、BASE_URL和VUE_APP_*变量,非前缀变量会被解析为undefined。
- Node 环境(如
- 常见错误:若在 Vue 组件中使用
process.env.port,会返回undefined,需改为VUE_APP_PORT=8081并通过process.env.VUE_APP_PORT访问。
8.5 打包后路径问题
- 问题根源:Vue 项目打包(
npm run build)后生成的dist文件夹中,index.html引用的 CSS、JS 等资源路径依赖publicPath配置(与BASE_URL一致)。若直接本地打开index.html(通过file://协议),路径解析会因缺乏服务器环境而失效。 - 具体表现:
- 浏览器控制台报错“Failed to load resource: net::ERR_FILE_NOT_FOUND”;
- 页面空白,无样式或交互效果。
- 解决方式:
- 调整
publicPath配置:在vue.config.js中设置publicPath: './'(相对路径),适合本地预览或部署到非根目录场景; - 使用服务器预览:通过 VS Code 的 Live Server 插件、
serve工具(npx serve dist)或本地服务器(如 Nginx)访问,确保资源通过http://或https://协议加载; - 生产环境部署:根据实际部署路径设置
publicPath(如部署到/admin/目录则设为'/admin/'),并确保服务器配置正确映射路径。
- 调整
- 注意事项:
publicPath需与环境变量BASE_URL保持一致(Vue CLI 会自动关联),避免因路径不匹配导致资源加载失败。