返回顶部
首页 > 资讯 > 精选 >vite是如何解析.env文件的
  • 762
分享到

vite是如何解析.env文件的

2023-07-05 00:07:36 762人浏览 独家记忆
摘要

这篇文章主要介绍“vite是如何解析.env文件的”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vite是如何解析.env文件的”文章能帮助大家解决问题。使用vite构建的vue3项目中,可以在根目

这篇文章主要介绍“vite是如何解析.env文件的”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vite是如何解析.env文件的”文章能帮助大家解决问题。

使用vite构建的vue3项目中,可以在根目录下创建.env.[模式]文件定义一种或多种模式,并且在这个文件中定义的变量就是此模式的环境变量。定义了环境变量之后就可以通过import.meta.env.[变量名]的方式读取环境变量了。

那么我们要来思考两个问题:第一,vite如何读取.env文件中定义的配置;第二,vite如何将.env文件中配置的环境变量挂载到import.meta.env环境变量上的。

1.如何读取.env文件中定义的配置

1.1 问题的着眼点是什么?

首先我们看一下vite如何读取.env文件中定义的配置。如下图所示,在项目根目录下有.env.development,.env.fat,.env.uat,.env.pro四个模式文件,其中development模式是对应默认的开发环境用于本地开发,fat模式对应的也是开发环境用于自测,uat模式对应的是预发布环境用于测试团队测试,pro模式对应的是生产环境也叫线上环境用于客户使用。

vite是如何解析.env文件的

那么如何能够让vite知道我们要使用相关模式的文件呢?运行vite 或者vite build命令时可以通过--mode或者-m设置环境模式(详见文档),如下图所示:

vite是如何解析.env文件的

这就提示我们要了解vite如何读取定义环境变量的模式文件则需要从vite命令或者vite build命令入手,接下来从vite命令入手研究一下。

1.2 vite的命令定义在何处?

看一下vite的package.JSON文件(路径:vite/packages/vite/package.json):

vite是如何解析.env文件的

当我们使用vite命令的时候,会执行bin目录下的vite.js文件,看一下这个文件(路径:vite/packages/vite/bin/vite.js):

vite是如何解析.env文件的

可以看到这段代码的关键是执行start方法,而start方法是导入打包后的cli.js文件,那么这个打包后的文件对应的原文件是哪个文件呢?vite打包的时候是使用rollup的,所以我们看一下rollup的配置文件(路径:vite/packages/vite/rollup.config.ts):

vite是如何解析.env文件的

如上代码可以看出vite相关命令的定义在/src/node/cli.ts 这个文件当中。

1.3 vite的命令是如何定义的?

1.3.1 vite使用cac定义命令

我们来看一下vite的命令是如何定义的(路径:vite/packages/vite/src/node/cli.ts):

import { cac } from 'cac'const cli = cac('vite')cli  .option('-m, --mode <mode>', `[string] set env mode`)cli  .command('[root]', 'start dev server') // default command  .alias('serve') // the command is called 'serve' in Vite's api  .option('--port <port>', `[number] specify port`)  .action(async (root: string, options: ServerOptions & GlobalCLIOptions) => {    const { createServer } = await import('./server')    try {      const server = await createServer({        root,        base: options.base,        mode: options.mode,        configFile: options.config,        logLevel: options.logLevel,        clearScreen: options.clearScreen,        optimizeDeps: { force: options.force },        server: cleanOptions(options),      })  })

如上代码所示,vite主要是使用cac这个命令行工具库定义命令的,解释一下这里使用到的cac的相关API:

  • cac(name?):用于创建一个cac实例,name参数是可选的。

  • option(name, description, config): 用于设置配置项。

  • command(name, description, config?): 声明cli命令,可以给命令设置独立的配置项喝其配置后的执行动作。

  • command.alias(name):给cli命令起别名。

  • action(callback): 指定命令所执行的操作。

可以看出,当运行vite命令的时候会执行createServer方法,我们这里要注意参数mode就是我们运行命令时通过--mode 或者 -m指定的参数,下面来研究createServer方法。

1.3.2 createServer

看一下createServer方法(路径:createServervite/packages/vite/src/node/server/index.ts):

import { resolveConfig } from '../config'export async function createServer(  inlineConfig: InlineConfig = {},): Promise<ViteDevServer> {  const config = await resolveConfig(inlineConfig, 'serve')}

可以看到createServer方法调用的是resolveConfig方法,下面看一下resolveConfig方法。

1.3.3 resolveConfig

resolveConfig方法的代码如下(路径;vite/packages/vite/src/node/config.ts):

import { loadEnv, resolveEnvPrefix } from './env'export async function resolveConfig(  inlineConfig: InlineConfig,  command: 'build' | 'serve',  defaultMode = 'development',  defaultNodeEnv = 'development',): Promise<ResolvedConfig> {  const envDir = config.envDir    ? nORMalizePath(path.resolve(resolvedRoot, config.envDir))    : resolvedRoot  const userEnv =    inlineConfig.envFile !== false &&    loadEnv(mode, envDir, resolveEnvPrefix(config))  const resolvedConfig: ResolvedConfig = {    command,    mode,    env: {      ...userEnv,      BASE_URL,      MODE: mode,      DEV: !isProduction,      PROD: isProduction,    },  }  const resolved: ResolvedConfig = {    ...config,    ...resolvedConfig,  }  return resolved}

可以看到resolveConfig的主要工作:

  • 首先确定.env文件的路径

  • 然后调用loadEnv方法加载解析.env文件,将结果赋值给userEnv

  • 最后返回整个解析后的配置

我们看到这里的关键代码是loadEnv(mode, envDir, resolveEnvPrefix(config))下面我就重点看一下loadEnv方法。

1.3.4 loadEnv

loadEnv方法是vite中一个比较核心的方法,也作为vite对外提供的一个javascript API,用于加载 envDir 中的 .env 文件。

vite是如何解析.env文件的

我们看一下loadEnv方法(路径:vite/packages/vite/src/node/env.ts):

import { parse } from 'dotenv'import { arraify, lookupFile } from './utils'export function loadEnv(  mode: string,  envDir: string,  prefixes: string | string[] = 'VITE_',): Record<string, string> {  prefixes = arraify(prefixes)  const env: Record<string, string> = {}  const envFiles = [     `.env`,     `.env.local`,     `.env.${mode}`,     `.env.${mode}.local`,  ]  const parsed = Object.fromEntries(    envFiles.flatMap((file) => {      const path = lookupFile(envDir, [file], {        pathOnly: true,        rootDir: envDir,      })      if (!path) return []      return Object.entries(parse(fs.readFileSync(path)))    }),  )  // only keys that start with prefix are exposed to client  for (const [key, value] of Object.entries(parsed)) {    if (prefixes.some((prefix) => key.startsWith(prefix))) {      env[key] = value    } else if (      key === 'NODE_ENV' &&      process.env.VITE_USER_NODE_ENV === undefined    ) {      // NODE_ENV override in .env file      process.env.VITE_USER_NODE_ENV = value    }  }  return env}

如上代码所示理解loadEnv方法注意以下几个方面:

  • 该方法接收三个参数,分别是模式、.env文件的路径还有环境变量的前缀。

  • 使用递归方法lookupFile找到.env文件的路径,使用fs.readFileSync读取文件。

  • 使用dotenv提供的方法解析.env文件内容。

关于dotenv可以学习川哥的文章,也可以看看笔者的源码共读语雀笔记。至此,我们了解了vite是如何读取.env文件中定义的环境变量了。下面我们研究第二个问题vite如何将.env中配置的环境变量挂载到import.meta.env环境变量上。

2.如何将变量挂载到import.meta.env环境变量上

2.1 vite的环境变量和import.meta

Vite 在一个特殊的 import.meta.env 对象上暴露环境变量,有一些在所有情况下都可以使用的内建变量:

import.meta.env.MODE: {string} 应用运行的模式。

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

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

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

import.meta.env.SSR: {boolean} 应用是否运行在 server 上。

详见环境变量。这里我们要解释一下import.meta。它是一个给JavaScript模块暴露特定上下文的元数据属性的对象。它包含了这个模块的信息,比如说这个模块的URL。详见import.meta 的MDN文档。需要注意不可以在模块的外部使用import.meta,如下图所示:

vite是如何解析.env文件的

2.2 resolveConfig

在上文中我们已经研究了resolveConfig的代码,我们再来看以下此方法中的另一段代码(路径:vite/packages/vite/src/node/config.ts):

import {resolvePlugins,} from './plugins'export async function resolveConfig(  inlineConfig: InlineConfig,  command: 'build' | 'serve',  defaultMode = 'development',  defaultNodeEnv = 'development',): Promise<ResolvedConfig> {  (resolved.plugins as Plugin[]) = await resolvePlugins(    resolved,    prePlugins,    normalPlugins,    postPlugins,  )}

这里调用了resolvePlugins,接收resolved对象,此对象中含有开发者所指定的模式以及.env文件中的环境变量。我们接着看一下resolvePlugins方法。

2.3 resolvePlugins

节选resolvePlugins方法如下(路径:vite/packages/vite/src/node/plugins/index.ts):

import { definePlugin } from './define'export async function resolvePlugins(  config: ResolvedConfig,  prePlugins: Plugin[],  normalPlugins: Plugin[],  postPlugins: Plugin[],): Promise<Plugin[]> {  return [    //...    definePlugin(config),    //...  ].filter(Boolean) as Plugin[]}

resolvePlugins负责解析插件,这里面调用了definePlugin方法,我们看一下。

2.4 definePlugin

definePlugin的代码如下(路径:vite/packages/vite/src/node/plugins/define.ts):

const importMetaKeys: Record<string, string> = {}const importMetaFallbackKeys: Record<string, string> = {}if (isBuild) {  const env: Record<string, any> = {    ...config.env,    SSR: !!config.build.ssr,  }  for (const key in env) {    importMetaKeys[`import.meta.env.${key}`] = JSON.stringify(env[key])  }  Object.assign(importMetaFallbackKeys, {    'import.meta.env.': `({}).`,    'import.meta.env': JSON.stringify(config.env),    'import.meta.hot': `false`,  })}

这段代码的关键部分在于第8-10行的for循环,将.env文件中定义的环境变量挂在到了import.meta.env上。至此,如何也了解了vite是如何将环境变量挂在到import.meta.env环境变量上。

关于“vite是如何解析.env文件的”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网精选频道,小编每天都会为大家更新不同的知识点。

--结束END--

本文标题: vite是如何解析.env文件的

本文链接: https://lsjlt.com/news/348780.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • vite是如何解析.env文件的
    这篇文章主要介绍“vite是如何解析.env文件的”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vite是如何解析.env文件的”文章能帮助大家解决问题。使用vite构建的vue3项目中,可以在根目...
    99+
    2023-07-05
  • 深入探讨vite是怎么解析.env文件的
    使用vue框架开发前端项目时,我们部署的时候都会部署多套环境,往往开发、测试以及线上环境调用的接口域名都是不一样的。如何能做到区分呢?那就是使用环境变量和模式。使用vite构建的vue3项目中,可以在根目录下创建.env.[模式]文件定义一...
    99+
    2023-05-14
    前端 Vite Vue.js
  • 如何在vite里获取env环境变量浅析
    目录.env环境配置文件在cli项目中我们可以是配置.env.[mode]文件来配置环境变量在cli项目中使用.env.[mode]在vite中使用.env文件总结.env环境配置文...
    99+
    2022-11-13
    vite 环境变量 vite env环境变量 env查看环境变量
  • 项目中常用的.env文件原理源码解析
    目录前言如何使用源码解析读取文件解析文件赋值操作总结前言 dotenv 是一个用于加载环境变量的库,在 Node.js 应用程序中可以使用它来简化对环境变量的访问。在日常开发中起到了...
    99+
    2022-12-25
    .env 文件原理 .env 文件
  • .env在mode文件中如何添加注释详解
    目录前言问题分析解决(dotenv)使用测试前言 Vue-Cli 允许我们在项目根目录创建.env.[mode]文件来设置一些打包编译的启动参数,通过执行脚本的时候加mode参数,指...
    99+
    2024-04-02
  • Mybatis是如何解析配置文件的
    本篇内容主要讲解“Mybatis是如何解析配置文件的”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Mybatis是如何解析配置文件的”吧!在以前文章中,我们把M...
    99+
    2024-04-02
  • 如何用.env文件为NodeJS加载环境变量
    这篇文章主要讲解了“如何用.env文件为NodeJS加载环境变量”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何用.env文件为NodeJS加载环境变量”...
    99+
    2024-04-02
  • 如何解析memory.dmp文件
    要解析memory.dmp文件,您可以使用以下方法:1. 使用Windows调试工具:您可以使用Windows调试工具来解析memo...
    99+
    2023-09-26
    解析
  • java如何解析wsdl文件
    在Java中,可以使用JAX-WS来解析和处理WSDL文件。以下是解析WSDL文件的简单步骤:1. 导入必要的类和库:import ...
    99+
    2023-10-18
    java
  • PHP 如何解析 CSV 文件
    CSV 是一种文件类型。它表示逗号分隔的值 - Comma Separated Values 的首字母缩写。通常在其他软件(例如 Excel)中使用。这样可以将数据以表格格式保存,扩展名为 .csv。要使用...
    99+
    2024-02-27
  • 一文详解如何在Vue3+Vite中使用JSX
    目录JSX介绍在 Vue3 中使用 JSX安装插件(@vitejs/plugin-vue-jsx)新建 jsx 文件语法补充知识:注意事项总结JSX介绍 JSX(JavaScript...
    99+
    2023-02-16
    vue3 vite使用jsx vue3+vite 前端 vite搭建vue3
  • 如何解析HDFS的写文件流程
    这篇文章给大家分享的是有关如何解析HDFS的写文件流程的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。文件是如何写入HDFS的 ?下面我们来先看看下面的“写”流程图:    ...
    99+
    2023-06-03
  • 如何解析Linux文件链接
    今天给大家介绍一下如何解析Linux文件链接。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。在Linux系统中链接分为两种:软连接、硬链接,可以使用 ls -l...
    99+
    2023-06-28
  • mysql中sock文件如何解析
    MySQL中的sock文件是指用于本地连接的套接字文件,是一种特殊类型的文件用于进程间通信,要解析MySQL中的sock文件,可以按照以下步骤进行:1、打开MySQL配置文件 my.cnf;2、在配置文件中找到 [mysqld] ...
    99+
    2024-01-29
    sock文件 mysql
  • iis不解析php文件如何解决
    这篇文章主要介绍了iis不解析php文件如何解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇iis不解析php文件如何解决文章都会有所收获,下面我们一起来看看吧。iis不解析php文件的解决办法:1、安装ii...
    99+
    2023-07-04
  • 如何解析 Linux 中“一切都是文件”概念和相应的文件类型
    今天就跟大家聊聊有关如何解析 Linux 中“一切都是文件”概念和相应的文件类型,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在 Unix 和它衍生的比如 Linux  系...
    99+
    2023-06-16
  • 如何解析Java虚拟机的Class文件
    这篇文章给大家介绍如何解析Java虚拟机的Class文件,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前面发了几篇学习笔记,但是看这些东西总是感觉很"玄乎",来一篇实战的东西来揭一下"JV...
    99+
    2023-06-17
  • 如何在python中解析json文件
    本篇文章为大家展示了如何在python中解析json文件,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。python可以做什么Python是一种编程语言,内置了许多有效的工具,Python几乎无所不能...
    99+
    2023-06-14
  • 如何解析Python 源文件性质
    本篇文章给大家分享的是有关如何解析Python 源文件性质,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。对于Python 源文件的学习,个人认为先要从Python的概念学起,其...
    99+
    2023-06-17
  • Boost PropertyTree该如何解析INI文件
    Boost PropertyTree该如何解析INI文件,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。前言PropertyTree是一个非常牛叉的东西...
    99+
    2023-06-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作