vite项目为什么可以直接使用NODE_ENV?

news2024/11/25 18:53:19

背景

我们知道,在process.env中并没有NODE_ENV这个变量,但是我们却可以在项目的代码中使用process.env.NODE_ENV这个值来判断当前是development环境还是production环境,然后进行后续的逻辑操作。

这说明,在vite内部,对process.env.NODE_ENV有赋值的操作,但是在公司项目中,启动的时候不管是serve还是build,在在tailwind.config.js中打印process.env.NODE_ENV变量,NODE_ENV均为development,这就让人感觉很困惑。

当时为了简单处理,使用了行内npm scrips配置,即在启动服务的时候,设置process.env.NODE_ENV的值,如下所示:

"scripts": {"serve": "cross-env NODE_ENV=development vite","build": "cross-env NODE_ENV=prod vite build --mode prod","build-v1": "cross-env NODE_ENV=v1 vite build --mode v1",
}, 

后来一直觉得不妥,应该有更为简单合理的方式去判断当前项目所处的环境,毕竟vite中会有.env文件来让我们配置环境变量,应该跟process.env.NODE_ENV有些许关系。

于是,决定深入vite源码去剖析process.env.NODE_ENV赋值的逻辑,最后找到了更好的替代cross-env的方式去判断当前项目所处的环境。也是这篇文章的动机所在。

分析执行过程

首先,在一些需要的地方打上断点:

  • vite启动位置defineConfig
  • tailwind.config.js 文件开始位置
  • vite源码中,对process.env.NODE_ENV进行赋值的位置

然后在VSCode中,配置好launch.json后,启动调试。

由于我们执行的是npm run serve,所以首先会断在cli.js中,创建服务的位置,可以看到调用createServer创建本地服务。

继续F5,进入createServer,会执行resolveConfig,其中参数inlineConfig.mode 就是我们npm scrips中指定的mode,这里没有指定(执行的只是npm run serve: vite)mode,所以这里为undefined。

经过一次判断 mode === production,不成立,此时process.env.NODE_ENV还是undefined。

(在build 时候,由于我是手动指定mode为prod,导致prod ≠= production,所以process.env.NODE_ENV还是undefined。)

进入loadEnv方法,这里vite会读取.env文件,然后,如果是“VITE_”开头,会存入env变量中,如果是“NODE_ENV”变量,会设置process.env.VITE_USER_NODE_ENV = value; 即设置的NODE_ENV的值。(这个process.env.VITE_USER_NODE_ENV就可以为我们所用)

继续往下F5,loadEnv完后,继续一个判断:因为我们在.env文件中没有定义NODE_ENV变量,所以isProduction是false,所以这片代码过后,process.env.NODE_ENV还是undefined。

继续F5,然后会走到一个createContext函数,这个就是关键所在。由于我们的process.env.NODE_ENV在之前一直为undefined,所以ctx.env就是undefined,于是process.env.NODE_ENV被赋值为development。

我们继续,经过多次createContext函数的进进出出,最后终于到了tailwind文件中,可以看到NODE_ENV 的值为development。

这也是为什么不管是serve还是build,我们一直在tailwind.config.js中打印的NODE_ENV都是development的原因。

我之前还一直以为,是由于tailwind.config.js会在vite.config.js之前执行。

解决方案

之前也想在tailwind文件中使用import.meta.env来获取VITE_开头的环境变量,因为加载的.env中的环境变量也会通过 import.meta.env 以字符串形式暴露给客户端源码。

但是只要在tailwind中一引用就会报错。

最后通过查询才知道,import.meta 是一个内置在 ES 模块内部的对象(之前一直以为是vite暴露出来的)。而我们的tailwind文件是CommonJS模块,自然没有import.meta对象。

所以此路不通,得想其他的办法。

之前提到,在.env文件中定义的NODE_ENV,会在vite中被赋值给process.env.VITE_USER_NODE_ENV,我们可以用VITE_USER_NODE_ENV来作为我们项目环境的判断。

只需在.env文件中加上NODE_ENV变量:

NODE_ENV=prod 

然后在代码中使用VITE_USER_NODE_ENV来进行判断即可:

purge: {// 仅生产环境启用优化enabled: process.env.VITE_USER_NODE_ENV == 'prod',// 删除未使用的CSS tree-shake,减少打包后的体积content: ['./src/**/*.html', './src/**/*.vue', './src/**/*.jsx'],
}, 

最后

最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/167569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据面试题集锦-Hadoop面试题(二)-HDFS

你准备好面试了吗?这里有一些面试中可能会问到的问题以及相对应的答案。如果你需要更多的面试经验和面试题,关注一下"张飞的猪大数据分享"吧,公众号会不定时的分享相关的知识和资料。 1、 HDFS 中的 block 默认保存几份? 默认保存…

MacBook Pro外接显示器竖屏显示

📢📢📢📣📣📣哈喽!大家好,我是「奇点」,江湖人称 singularity。刚工作几年,想和大家一同进步🤝🤝一位上进心十足的【Java ToB端大厂领…

接口性能测试避坑 Django+Nginx+uwsgi接口性能调优postman Apifox ab

Django开发了个接口供外部调用,Django的并发性能弱早有所闻,所以采用DjangoNginxuwsgi架构来提高并发量。然后使用测试工具测试并发量。服务器配置:CPU 2,内存8G接口内容只有3句:request_data {"code":&quo…

MyBatis复习

本文章根据尚硅谷MyBatis教程整理而来 原视频地址:https://www.bilibili.com/video/BV1VP4y1c7j7 MyBatis简介 MyBatis历史 MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁 移到了Google Code。随着开发团队转投Goo…

力扣刷题记录——521. 最长特殊序列 Ⅰ、541. 反转字符串 II、557. 反转字符串中的单词 III

本专栏主要记录力扣的刷题记录,备战蓝桥杯,供复盘和优化算法使用,也希望给大家带来帮助,博主是算法小白,希望各位大佬不要见笑,今天要分享的是——《521. 最长特殊序列 Ⅰ、541. 反转字符串 II、557. 反转字…

PhotoZoom Pro8全新版本功能介绍及系统要求

PhotoZoom 2023(PhotoZoom 8)全新版本震撼来袭。 一款划时代的、技术上产生革命性影响的数码图片放大工具。 我们获取图片的方法,一般是从度娘图片和各个图库里找素材。但一般网上搜索到的很多图片像素都非常小,普通方法放大就像打…

修改配置文件的定时任务

1.问题背景 下发文件给下游系统设置的是定时任务,原本是每天的18:08定时发送,突然下游说要立马发送,于是只能去修改定时任务。 2.修改操作 查看权限—修改权限—备份–修改—重启 查看权限 进入配置文件目录:cd /…

分享77个HTMLCSS源码,总有一款适合您

HTML&CSS源码 分享77个HTML&CSS源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下...,大家下载后可以看到。 源码下载链接:https://pan.baidu.com/s/1QRSokzVy2ZAaSD6VR…

DataGear 4.4.0 发布,数据可视化分析平台

DataGear 4.4.0 发布,带来看板新特性,具体更新内容如下: 新增:看板新增dg-chart-manual-render属性,用于控制是否手动渲染图表;新增:看板dg-dashboard-code属性新增"instance"值&…

Linux——线程概念及私有数据和优缺点

目录 一.什么是线程 二.线程私有的数据 三.线程的优点 四.线程的缺点 五.线程与进程对比 一.什么是线程 线程是在进程内部运行,一个进程可以有多个线程。 打个比方,假如人是一个进程,那么走路、思考、吃饭、说话作为不同的线程。一个进…

《Linux Shell脚本攻略》学习笔记-第十章

10.1 Linux的生态系统由网络、硬件、负责分配资源的操作系统内核、接口模块、系统实用工具以及用户程序所组成的。 10.2 运行在计算机中的多个进程都被分配了一个被称为进程ID的唯一标识数字。进程属性包括拥有该进程的用户、进程使用的内存数量、进程占用的CPU时间。 ps命令默…

拉伯证券|年内第二大解禁周来袭

Wind数据显现,除掉新上市公司,本周A股共有54家公司限售股解禁,解禁数量270.57亿股,以最新收盘价计算(下同),解禁市值1752.90亿元,为年内第二大解禁周。 本周解禁市值超越10亿元的公司…

YOLOv8代码上线,官方宣布将发布论文,附精度速度初探和对比总结

【YOLOv8 注意事项】 1. YOLOv8 的官方仓库和代码已上线,文档教程网址也刚刚更新。 2. YOLOv8 代码集成在 ultralytics 项目中,目前看不会再单独创建叫做 YOLOv8 的项目。 3. YOLOv8 即将有论文了!要知道 YOLOv5 自从 2020 年发布以来&…

阿里云服务器安装图形界面

为了自动化流程安装图形界面,我的服务器是Centos7 1、yum安装gnome图形界面 yum groupinstall “GNOME Desktop” -y 2、安装远程桌面服务端 yum -y install tigervnc-server -y 3、启动远程桌面服务端(将桌面服务绑定到5903端口) vncserver :3 4、阿里控制台放开59…

SpringBoot+VUE前后端分离项目学习笔记 - 【23 权限菜单 续】

BUG1 : 路由跳转问题 访问错误路由: 已登录用户返回404,未登录用户返回登录页面 Route/index.js 路由守卫增加判断 router.beforeEach((to, from, next) > {localStorage.setItem("currentPathName", to.name) // 设置当前的路由名称s…

【墙角数枝梅,凌寒独自开】代码改变未来

墙角数枝梅,凌寒独自开 “墙角数枝梅,凌寒独自开。” 出自王安石的《梅花》 诗句是集语言中的精华,浓缩为七言、五言和四言等,寥寥几句道尽人生酸甜苦辣,儿女情长。 而我更愿把现代的程序员称作诗人,语言是…

ESP32设备驱动-TCS34725颜色传感器驱动

TCS34725颜色传感器驱动 文章目录 TCS34725颜色传感器驱动1、TCS34725介绍2、硬件准备3、软件准备4、驱动实现1、TCS34725介绍 TCS3472 器件提供红色、绿色、蓝色 (RGB) 和清晰光感应值的数字返回。 集成在芯片上并定位于颜色传感光电二极管的 IR 阻挡滤光片可最大限度地减少入…

并发场景使用SimpleDateFormat异常问题和解决

SimpleDateFormat类主要是负责日期的格式化与转换操作,因为它不是线程安全的,所以使用SimpleDateFormat时,务必确保同一个SimpleDateFormat对象不要与其他线程共享,否则并发情况下会出现问题 目录异常示例解决方案1:创…

Camera | 2.MIPI、CSI基础

瑞芯微专栏 上一篇我们讲解了camera的一些基础概念和知识。 我们说了,现在的手机由于高分辨率的要求,现在基本上都是基于MIPI、CSI协议来实现的, 本篇讲解MIPI、CSI的一些基础知识。 摄像头常用术语 下面这些术语是camera驱动中经常用到的…

9.6 容器适配器

文章目录定义一个适配器stack队列适配器queuepriority_queue 优先队列适配器是标准库的一个通用概念,容器、迭代器和函数等都有适配器。适配器是一种机制,接受一种已有容器类型。标准库有三个顺序容器适配器:stack,queue和priorit…