当前位置: 首页 > news >正文

不同打包工具下的环境变量配置方式对比

本文作者为 360 奇舞团前端开发工程师 天明

前言

在现代的JavaScript应用程序开发中,环境变量的配置是至关重要的。不同的应用场景和部署环境可能需要不同的配置,例如开发、测试和生产环境。最常见的需求是根据不同的环境,配置如是否开启sourceMapAPI请求地址的切换、是否压缩代码等逻辑。本文主要介绍利用不同的工具:WebpackViteRollup打包项目的环境变量的配置方式。

process.env.NODE_ENV

process.env.NODE_ENV应该是我们最熟悉的环境变量了,我们知道在Node环境中process是一个全局变量,无需require引入。process.env属性返回一个包含用户环境信息的对象,当我们打印process.env时,发现它并没有NODE_ENV这一个属性。实际上process.env.NODE_ENV是在package.jsonscripts命令中注入的,可以通过以下方式进行设置:

{"scripts": {"dev": "NODE_ENV=development webpack --config webpack.dev.config.js","prod": "NODE_ENV=production webpack --config webpack.prod.config.js"}
}

当运行npm run devnpm run prod命令时,设置了NODE_ENV的不同值,项目中访问到的process.env.NODE_ENV值也会根据执行脚本的不同而分别取值:developmentproduction. 我们可以根据这个值的不同而分别进行不同的配置,这就是配置环境变量的基本逻辑.

Webpack项目环境变量配置方式
使用DefinePlugin插件

前面提到,在scripts命令中注入的NODE_ENV只能被Webpack的构建脚本访问,而被Webpack打包的源码中是无法访问到的,此时可以借助WebpackDefinePlugin插件,创建全局变量。

const webpack = require('webpack');module.exports = {//.....其他配置plugins: [new webpack.DefinePlugin({'process.env.API_URL': JSON.stringify('https://api.example.com'),'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),}),],
};

在上面的示例中,我们定义了两个环境变量:API_URLNODE_ENV,并且使用JSON.stringify将值转换为字符串。这样就可以在代码中使用process.env.API_URLprocess.env.NODE_ENV来访问这两个环境变量的值了。

Windows平台配置的注意点

Windows平台下直接设置NODE_ENV =XXX是会报错的, 解决办法也很简单,可以使用cross-env这个npm包来进行配置,cross-env能够提供一个设置环境变量的scripts,这样我们就能够以unix方式设置环境变量,然后在windows上也能够兼容

  • 安装

npm install cross-env --save
  • 使用

"scripts": {"dev": "cross-env NODE_ENV=development webpack","prod": "cross-env NODE_ENV=production webpack"
}

可以看到直接在NODE_ENV=XXX前面添加cross-env就可以了。

使用dotenv插件

假如我们项目的环境变量有很多,全部设置plugins中既不美观也不容易维护,此时将环境变量配置在.env文件中,然后使用dotenv插件来加载.env配置文件。

  • 安装

npm install dotenv-webpack --save-dev
  • 创建环境变量文件 在项目根目录下创建一个.env文件,如果有多种不同的环境,可以针对不同的环境创建不同的配置文件,例如可以使用.env.development.env.test.env.production在文件来分别表示:开发、测试、生产环境的环境变量。在文件中配置每个环境对应的变量:

// .env.development
API_URL=http://development.example.com
DEBUG=true
// .env.test
API_URL=http://test.example.com
DEBUG=true
// .env.production
API_URL=http://production.example.com
DEBUG=false
  • 加载.env配置 在webpack.config.js加载.env配置:

require('dotenv').config({ path: path.resolve(__dirname, '.env.' + process.env.NODE_ENV) })
  • 设置scriptsscripts命令中设置NODE_ENV

"scripts": {"dev": "cross-env NODE_ENV=development webpack","dev": "cross-env NODE_ENV=test webpack","prod": "cross-env NODE_ENV=production webpack"
}
Rollup项目环境变量配置方式

Rollup是一个现代化的JavaScript模块打包工具,专注于构建JavaScript库和组件。下面是Rollup中配置环境变量的几种常见方式:

使用rollup-plugin-replace

Rolluprollup-plugin-replace插件允许我们在打包过程中替换代码中的字符串。我们常用该插件来定义环境变量。

  • 安装:

npm install rollup-plugin-replace --save-dev
  • rollup.config.js中配置

const isProduction = process.env.NODE_ENV === 'production';
export default [{//.....其他配置plugins: [replace({'process.env.API_URL': JSON.stringify(isProduction ? 'https://prod.example.cn' : 'https://dev.example.cn')'process.env.NODE_ENV': JSON.stringify(isProduction? 'production' : 'development')})]}
]

在上面的例子中,我们首先获取到当前组件库的环境变量,并根据它的值设置不同的API_URLNODE_ENV.

之所以在组件库中使用rollup-plugin-replace 替换 process.env.NODE_ENV 的原因是为了在打包时,将代码中的环境变量替换为实际的值,以便在不同的环境中正确地运行组件库。这样就避免了宿主工程中的环境变量process.env.NODE_ENV,对组件库环境变量的影响。

Rollup使用dotenv插件

Webpack类似,在Rollup中使用dotenv插件进行环境变量的配置,可以按照以下步骤进行:

  • 安装dotenvrollup-plugin-replace

npm install dotenv rollup-plugin-replace --save-dev
  • 创建环境变量文件 与上面的Webpack创建环境变量文件类似,这里也可以创建多个环境配置文件.env.development.env.test.env.production

  • rollup.config.js加载.env配置

import { config } from 'dotenv'
config({ path: ".env."+ process.env.NODE_ENV }).parsed
export default {// ...plugins: [replace({process.env.API_URL: JSON.stringify(process.env.API_URL),process.env.DEBUG: JSON.stringify(process.env.DEBUG),}),// ...],
};

在上例中,我们首先通过dotenv.config()方法来加载.env文件中的环境变量。然后,使用@rollup/plugin-replace插件的replace方法,将环境变量注入到代码中。

  • package.json中设置scripts

"scripts": {"build:dev": "cross-env NODE_ENV=development rollup -c","build:prod": "cross-env NODE_ENV=production rollup -c","build:test": "cross-env NODE_ENV=test rollup -c","dev": "cross-env NODE_ENV=development rollup -c -w",}

执行对应的脚本命令后,在你的代码中,你可以通过process.env.XXX来访问已配置的环境变量.

Vite项目环境变量配置方式

与使用Webpack或是Rollup项目配置环境变量相比,Vite项目配置环境变量较为简单。

内建变量

Vite在一个特殊的import.meta.env对象上暴露环境变量

  • import.meta.env.MODE: 应用运行的模式。

  • import.meta.env.BASE_URL:部署应用时的基本 URL。他由base 配置项决定。

  • import.meta.env.PROD:应用是否运行在生产环境。

  • import.meta.env.DEV:应用是否运行在开发环境 (永远与 import.meta.env.PROD相反)。

  • import.meta.env.SSR:应用是否运行在 server 上。 这些变量可以直接在代码中访问

.env文件

同样在项目的根目录下,根据环境的不同创建不同的配置文件,不过文件的命名有些特殊性:

.env                # 所有情况下都会加载
.env.local          # 所有情况下都会加载,但会被 git 忽略
.env.[mode]         # 只在指定模式下加载
.env.[mode].local   # 只在指定模式下加载,但会被 git 忽略

加载的环境变量也会通过 import.meta.env 以字符串形式暴露给客户端源码。

注意:为了防止意外地将一些环境变量泄漏到客户端,只有以VITE_为前缀的变量才会暴露给经过vite处理的代码。

模式

默认情况下,开发服务器 dev命令 运行在 development模式,而build命令则运行在production模式。这意味着当执行vite build 时,它会自动加载.env.production中可能存在的环境变量.在某些情况下,若想在vite build时运行不同的模式,你可以通过传递 --mode 选项标志来覆盖命令使用的默认模式。

vite build --mode development

此时vite会使用.env.development文件下环境变量进行构建。

总结

通过对比发现虽然打包工具不同,但是配置环境变量的方式都大同小异,合理的使用环境变量,能够提高我们代码的灵活性、安全性、可维护性,并且将配置信息与代码分离是一种良好的开发实践,可以使应用程序更易于维护和管理。

参考:

https://cn.vitejs.dev/guide/env-and-mode.html

https://webpack.docschina.org/plugins/define-plugin/

https://cn.rollupjs.org/faqs/

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

0ce2e5fbfdeec724791bfedc63f98e92.png

相关文章:

不同打包工具下的环境变量配置方式对比

本文作者为 360 奇舞团前端开发工程师 天明 前言 在现代的JavaScript应用程序开发中,环境变量的配置是至关重要的。不同的应用场景和部署环境可能需要不同的配置,例如开发、测试和生产环境。最常见的需求是根据不同的环境,配置如是否开启sour…...

5个99%的人可能不知道的实用程序库!

前言 作为一名前端开发者,这些 JavaScript 库极大地提高了我的工作效率,如格式化日期、处理 URL 参数和调试移动网页。朋友们,我想和你们分享这些库。 1. 使用 “Day.js” 来格式化日期和时间 链接 作为开发者,我已经厌倦了在 JavaScript 中操作日期和时间,因为它太麻烦了。…...

shell脚本,ADB

Linux命令行命令是系统内置的命令或用户自定义的脚本(shell 脚本,.sh扩展名结尾),可以通过终端输入命令来执行。这些命令通常存储在Linux系统的/bin、/usr/bin、/sbin、/usr/sbin等目录下,也可以在$PATH环境变量中指定…...

微服务治理:微服务安全详解

微服务安全旨在保护微服务架构中每一个独立的服务。与传统单体应用程序不同,它们在单点应用安全措施,微服务由于其独立性,需要分布式安全方法。 为何关注微服务安全? 攻击面扩大: 更多服务暴露在外,意味着攻击者拥有…...

迅为RK3588开发板编译 Buildroot单独编译图形化界面三

第三步:编译 Recovery 首先在 linux 源码目录下输入以下命令进入编译的 UI 界面,进入之后如下所示: ./build.sh 然后将光标移动到第四个 recovery,点击回车即可开始 recovery 的编译,编译过程如下所示: 编…...

yum仓库及NFS共享

目录 一.yum仓库的基本原理 1.Yum概述: 2.Yum实现过程: 二. yum配置文件及命令: 1. 主配置文件: 2. 仓库设置文件: 3 .日志文件: ​编辑4.yum命令详解: 三. 搭建仓库的方式: …...

【Web】CTFSHOW PHP特性刷题记录(全)

知其然知其所以然,尽量把每种特性都详细讲明白。 目录 web89 web90 web91 web92 web93 web94 web95 web96 web97 web98 web99 web100 web101 web102 web103 web104 web105 web106 web107 web108 web109 web110 web111 web112 web113 web…...

[Docker] Docker为什么出现

Docker为什么出现 一款产品: 开发–上线 -->两套环境 | 应用配置 开发即运维! 环境配置十分麻烦,每一个机器都要部署环境(Redis, ES, Hadoop) 费时费力 项目带上配置环境安装打包。 传统: 开发jar&…...

小程序基础学习(页面跳转传参)

目录 正向传参 原理:直接在url里面拼接参数即可 接受参数 ​编辑 已经跳转到的页面用onLoad函数来接受即可然后写回页面展示即可 逆向传参 原理:通过使用 getCurrentPages()这个方法来获取返回页面列表,然后再用页面.setData&#xff…...

面试经典150题(85-87)

leetcode 150道题 计划花两个月时候刷完,今天(第四十三天)完成了3道(85-87)150: 85.(77. 组合)题目描述: 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可…...

【C++】“Hello World!“

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C ⚙️操作环境:Visual Studio 2022 ​ 2024.1.14 纪念一下自己编写的第一个C程序 #include<iostream>int main() {/*我的第一个C程序*/std::cout << "Hello world!:>" <<std::endl;ret…...

系统性学习vue-vue中的ajax

vue中的ajax 配置代理常用发送Ajax请求方式跨域方式一方式二 vue-resource插槽默认插槽具名插槽作用域插槽 配置代理 常用发送Ajax请求方式 xhr new XMLHttpRequest() 在真正开发中不常用&#xff0c;比较麻烦jQuery 封装了xhraxios 封装了xhr 与jQuery相比优势是&#xff1a…...

【PGSQL】date_trunc 函数

date_trunc 函数用于在 PostgreSQL 中将日期或时间戳值截断&#xff08;向下取整&#xff09;到指定的精度级别。当您想要忽略较小的时间单位&#xff08;例如&#xff0c;小时、分钟、秒&#xff09;&#xff0c;专注于较大的单位&#xff08;例如&#xff0c;天、月、年&…...

使用composer生成的DMG和PKG格式软件包有何区别

在使用Composer从包源构建软件包时候&#xff0c;有两种不同类型的包&#xff1a;PKG和DMG。你知道两者之间的区别吗? 以及如何选取吗&#xff1f; 每种格式都有各自的优势具体取决于软件包的预期用途以及用于部署软件包的工具。下面我们来了解一下PKG和DMG格式的区别和用途。…...

Linux 压缩解压

.tar &#xff08;注&#xff1a;tar是打包&#xff0c;不是压缩&#xff01;&#xff09; 解包&#xff1a;tar xvf FileName.tar -C DirName打包&#xff1a;tar cvf FileName.tar DirName .gz 解压1&#xff1a;gunzip FileName.gz解压2&#xff1a;gzip -d FileName.gz压…...

YUM仓库和NFS共享

目录 一、yum仓库 1. yum仓库介绍 1.1 简介 1.2 实现过程 1.3 实现安装服务 2. yum配置文件及命令 2.1 yum配置文件 2.1.1 yum主配置文件 2.1.2 仓库设置文件 2.1.3 日志文件 2.2 yum命令详解 2.2.1 查询 2.2.2 yum安装升级 2.2.3 软件卸载 3. 搭建仓库的方式 …...

Springboot中时间格式化

时间格式化方式 JsonFromat方式全局配置方式格式化工具方式 JsonFromat方式 前端传参或后端响应 yyyy-MM-dd HH:mm:ss 格式&#xff0c;直接属性字段上加注解 JsonFromat JsonFromat(pattern "yyyy-MM-dd HH:mm:ss", timezone "GMT8") private Date fi…...

蓝桥杯基础知识3 memset()

蓝桥杯基础知识3 memset() #include <bits/stdc.h> using namespace std;int main(){int a[5]; //随机数for(int i 0;i < 5; i)cout << a[i] << \n;cout << \n;memset(a, 0, sizeof a); //0for(int i 0;i < 5; i)cout << a[i] << …...

CentOS安装k8s单机/集群及一些命令

目录 前言 1. 安装docker 2. 安装要求 3.准备网络&#xff08;如果只装单机版可跳过此部&#xff09; 4. 准备工作 5. 安装 5.1. 配置阿里云yum k8s源 5.2 安装kubeadm、kubectl和kubelet 5.3 初始化&#xff0c;只在master执行&#xff0c;子节点不要执行 5.3.1 一些…...

iOS和安卓端个人踩坑史

本公司不提供测试机&#xff0c;借手机是开发测试中最麻烦的事 iOS可行组 1、iOS可以播放视频无声音&#xff0c;Andorid有声音 当时做了个远程视频连接项目&#xff0c;使用了jitsi第三方视频服务&#xff0c;iOS没有加dom.play()导致无法接收声音 2、iOS可以长按保存图片…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

基于Flask实现的医疗保险欺诈识别监测模型

基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施&#xff0c;由雇主和个人按一定比例缴纳保险费&#xff0c;建立社会医疗保险基金&#xff0c;支付雇员医疗费用的一种医疗保险制度&#xff0c; 它是促进社会文明和进步的…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

智能职业发展系统:AI驱动的职业规划平台技术解析

智能职业发展系统&#xff1a;AI驱动的职业规划平台技术解析 引言&#xff1a;数字时代的职业革命 在当今瞬息万变的就业市场中&#xff0c;传统的职业规划方法已无法满足个人和企业的需求。据统计&#xff0c;全球每年有超过2亿人面临职业转型困境&#xff0c;而企业也因此遭…...