【Vite指南】:环境文件系统

简介: 随着Vite在前端工具链中比重越来越大,但你了解Vite环境变量吗,这个模块对我们有什么用途,今天就来聊下。

网络异常,图片无法展示
|


本文为原创文章,引用请注明出处,欢迎大家收藏和分享💐💐

开篇

哈喽大家好,我是外卖仔,老久没静下心来卷文章了。随着Vite在前端工具链中比重越来越大,用的人也越来越多,打算出几期Vite的应用和机制研读,让小伙伴们用起来更得心应手。

文中对于Vite环境文件系统模块介绍主要分两块:

  • 功能理解与如何配置使用(贴点配置代码,搞一两个demo不就完事了😂😂😂)。。。
  • 项目中应用情景的拓展:用我可以,但如何合理使用,如何做到治理项目的效果。

配置Vite环境文件

定义和作用

为了更直观了解Vite的环境,先讲个笔者之前“修仙”时听到的故事:

  • 在「shi」山上,有个小和尚因友拜访而不知如何上山,便请教老和尚
  • 小和尚:上山的路崎岖交错,万一有外人来拜访,何以到庙
  • 老和尚:哈哈隔...
  • 小和尚:...
  • 一会后,老和尚笑着说:干哈呢,这是要到哪座庙?
  • 小和尚心里暗自困恼:好家伙,山上还有多少座庙,不要坑我啊!
  • 老和尚:淡定,我这有个随身听,另外山上每座庙藏宝阁有个U盘,你把U盘插到随身听上,就可播出山下到这座庙的路线了。这随身听我有好几个,给你一个便是。
  • 随后,小和尚接过老和尚的随身听,就跑到后面的屋子拿U盘捣鼓起来。只见开关一按下,随身听便发出声响,它说:

这个故事简单呈现了Vite的多环境功能,其中:

  • 每座庙:等同工程中每个开发环境,如我们所说的开发环境、测试环境;
  • 庙里面的U盘:相当于描述当前环境的配置文件。因为Vite启动服务或打包时支持开发者指定某个环境,并且导入该环境下所有变量做灵活的逻辑定制;
  • 随身听:很好理解,就是环境文件的读取器,告知服务该环境下所有的信息;

指定环境文件启动流程图:

网络异常,图片无法展示
|
参考: 《Vite环境与模式》

与环境相关的配置项

envDir#

  • Type:  string
  • Default:  root 设置读取环境文件的路径,默认是跟vite.config文件所在同目录。

envPrefix#

  • Type:  string | string[]
  • Default:  VITE_ 自定义环境变量前缀,默认为VITE_,符合该前缀的环境变量才会暴露在import.meta.env中。

另外官方有安全合规建议:

SECURITY NOTES

envPrefix should not be set as '', which will expose all your env variables and cause unexpected leaking of of sensitive information. Vite will throw error when detecting ''.

示例

🌰项目下有2个环境文件:

网络异常,图片无法展示
|
内容如下:

# .env.demo
# 透传客户端参数
VITE_NODE_ENV=demo
VITE_OWNER=Outer
VITE_POSITION=.env.demo
# 在envPrefix配置了的前缀参数也可以透传到客户端
MY_PARAM1=自定义参数1
YOUR_PARAM2=自定义参数2
# 私有参数,仅在vite server获取到,
# 假如你的项目包含此类敏感变量。应该将文件添加到你的 .gitignore 中,以避免它们被 git 检入。
MODE_KEY=PRIVATE_KEY_BETA
复制代码
# viteEnv/.env.demo
# 透传客户端参数
VITE_NODE_ENV=demo
VITE_OWNER=Inner
VITE_POSITION=viteEnv/.env.demo
# 在envPrefix配置了的前缀参数也可以透传到客户端
MY_PARAM1=自定义参数1
YOUR_PARAM2=自定义参数2
# 私有参数,仅在vite server获取到,
# 假如你的项目包含此类敏感变量。应该将文件添加到你的 .gitignore 中,以避免它们被 git 检入。
MODE_KEY=PRIVATE_KEY_BETA
复制代码

接下来是添加启动命令,在package.json设置:

{
  "scripts": {
    "dev:demo": "vite --mode demo",
  }
}
复制代码

--mode参数后面带要指定的环境文件,可以忽略文件名的.env.前缀。

❓到这里就有问题了,上面2个环境文件都叫demo,该命令启动后到底用哪一个?

这时候我们就可以通过envDir选项来指定了,因此我们还需要配置一下vite.config.ts:

export default defineConfig(async ({ command, mode }: ConfigEnv) => {
  return {
    envDir: './viteEnv',
    // or
    // envDir: './',
    envPrefix: ['VITE_', 'MY_', 'YOUR_'],
    // 其他配置 ...
  }
});
复制代码

控制台输出:

网络异常,图片无法展示
|

网络异常,图片无法展示
|

关于envPrefix配置项的用法在上面截图也可以看到了,指定的['VITE_', 'MY_', 'YOUR_']开头的变量都会expose到客户端。

再探源码

其实Vite在启动执行的createServer()方法中,关于读取环境文件这块会执行一个函数叫loadEnv,以下是它的定义。

loadEnv(mode: string, envDir: string, prefixes?: string | string[]): Record<string, string>;
复制代码

我们可以找到源码看下实现,源码路径packages/vite/src/node/config.ts

网络异常,图片无法展示
|
首先函数接受3个参数:mode名称(也就是启动命令传进去的文件名),和上面我们讲的2个配置项的值。进程会先生成4个默认文件路径保存到envFlies变量,2个mode和2个默认。

接下来会结合envDir寻找目标文件,找到后,使用fs配合prefixes变量前缀数组把对应的变量读取出来放置到env中,最后返回给主线程。

整个过程比较清晰,就是通过fs来取对应的文件变量,返回给进程使用。

环境变量获取

完成时调用

在服务启动后,客户端便可以通过import.meta.env来获取。 见:env variables

运行时调用

其实,我们也可以在Vite启动服务的RUNTIME时机获取环境变量,直接显式调用loadEnv方法即可:

import { defineConfig, ConfigEnv, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
import EnvironmentPlugin from 'vite-plugin-environment';
import { fetchEnv } from './server/envUitls';
// https://vitejs.dev/config/
export default defineConfig(({ command, mode }: ConfigEnv) => {
  const env = loadEnv(mode, path.resolve(__dirname, 'viteEnv'), [
    'VITE_',
    'MY_',
    'YOUR_'
  ]);
  console.log('env:', env);
  return {
    envDir: './viteEnv',
    // or
    // envDir: './',
    envPrefix: ['VITE_', 'MY_', 'YOUR_'],
    base: './',
    plugins: [
      vue(),
    ],
    resolve: {
      alias: [
        {
          find: '@',
          replacement: '/src'
        }
      ]
    }
  };
});
复制代码

控制台输出

网络异常,图片无法展示
|

通过插件透传环境变量

很多情况下,我们的环境变量不仅仅是简单的字符串,而是通过vite服务中二次计算才能得到最终结果,有点类似Vue中computed或React中useMemouseCallback的效果。 像这类非静态的环境变量,我们需要借助插件能力来让它们也能够返回客户端,插件很多,这里推荐vite-plugin-environment,使用大概是这样子的:

You can provide a list of environment variable names to expose to your client code:

import { defineConfig } from 'vite'
import EnvironmentPlugin from 'vite-plugin-environment'
export default defineConfig({
  plugins: [
    EnvironmentPlugin(['API_KEY', 'DEBUG']),
  ],
})
复制代码

And then use them as:

const apiKey = process.env.API_KEY
复制代码

在这个基础上,我们还能配合模式文件进行联合判断:

import { defineConfig, ConfigEnv, loadEnv } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'path';
import EnvironmentPlugin from 'vite-plugin-environment';
import { fetchEnv } from './server/envUitls';
// https://vitejs.dev/config/
export default defineConfig(({ command, mode }: ConfigEnv) => {
  const env = loadEnv(mode, __dirname);
  const { proxy } = fetchEnv(env.VITE_NODE_ENV); // 设置域名和端口
  return {
    base: './',
    plugins: [
      vue(),
      EnvironmentPlugin({
        PROXY: proxy
      })
    ]
  };
});
复制代码

const env = loadEnv(mode, __dirname);可以获取.env._local是所有非私密参数,接下来程序可以根据模式参数来计算最终的环境变量,通过插件返回到客户端。

fetchEnv方法可以理解成环境收集器,里面可以写逻辑让环境参数得到统一整合。

收笔

Vite的环境文件系统模块差不多讲到这里了,感谢大家阅览并欢迎纠错,欢迎大家关注本人公众号「是马非马」,一起玩耍起来!🌹🌹

项目传送门

vite-mul-env-learn

相关文章
|
1月前
|
存储 缓存 网络协议
Linux 基本组件与性能优化与根目录
内核:操作系统的核心,管理硬件资源和提供基本服务。 Shell: 用户与系统交互的命令行界面,例如 Bash 或 Zsh。 文件系统: 组织和存储数据的方式,例如 ext4、XFS。 进程: 正在运行的程序的实例,由内核管理。 用户界面: 提供图形用户界面(GUI)和命令行界面(CLI)两种方式。 系统工具: 用于系统管理的工具,例如 systemd、ps、top。 软件包管理器: 安装、更新和删除软件包的工具,如 apt、yum/dnf 网络协议和服务: 支持多种网络协议和提供网络服务的功能。
35 1
|
10月前
|
JavaScript 应用服务中间件 Apache
Linux--部署Vue项目
Linux--部署Vue项目
|
10月前
Ansible模块管理——磁盘管理模块、mount模块
Ansible模块管理——磁盘管理模块、mount模块
300 0
|
11月前
|
Ubuntu Linux 编译器
根文件系统移植:bulidroot根文件系统搭建详细步骤
根文件系统移植:bulidroot根文件系统搭建详细步骤
391 0
|
JavaScript 前端开发
在零配置的情况下,怎么启动、打包一个.vue文件?
在零配置的情况下,怎么启动、打包一个.vue文件?
172 0
在零配置的情况下,怎么启动、打包一个.vue文件?
|
算法 Java 开发工具
openHarmony系统打包应用程序
经过一段时间的学习,打包应用并安装应该是最激动人心的一环了,所以今天带大家完成openHarmony应用的安装,正文即将开始~~
349 0
openHarmony系统打包应用程序
|
测试技术
vue-cli3打包项目不同环境:开发环境、生产环境、测试环境
vue-cli3打包项目不同环境:开发环境、生产环境、测试环境
224 0
|
资源调度 前端开发
使用react脚手架快速搭建项目以及项目文件的介绍(目录文件的功能及作用)
本篇文章教大家使用脚手架搭建react的项目,对于新建的react项目,项目目录里的文件都是干什么的,有什么作用呢?
295 0
使用react脚手架快速搭建项目以及项目文件的介绍(目录文件的功能及作用)
|
JavaScript
Nodejs 文件系统(二)
Nodejs学习笔记
66 0
|
JavaScript Unix API
Nodejs 文件系统(一)
Nodejs学习笔记
84 0