国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
1.如何讀取.env文件中定義的配置
1.3.1 vite使用cac定義命令
1.3.2 createServer
1.3.3 resolveConfig
1.3.4 loadEnv
2.如何將變量掛載到import.meta.env環(huán)境變量上
總結
首頁 web前端 Vue.js 深入探討vite是怎么解析.env文件的

深入探討vite是怎么解析.env文件的

Jan 24, 2023 am 05:30 AM
前端 vue.js vite

深入探討vite是怎么解析.env文件的

使用vue框架開發(fā)前端項目時,我們部署的時候都會部署多套環(huán)境,往往開發(fā)、測試以及線上環(huán)境調用的接口域名都是不一樣的。如何能做到區(qū)分呢?那就是使用環(huán)境變量和模式。

使用vite構建的vue3項目中,可以在根目錄下創(chuàng)建.env.[模式]文件定義一種或多種模式,并且在這個文件中定義的變量就是此模式的環(huán)境變量。定義了環(huán)境變量之后就可以通過import.meta.env.[變量名]的方式讀取環(huán)境變量了。【相關推薦:vuejs視頻教程、web前端開發(fā)

那么我們要來思考兩個問題:第一,vite如何讀取.env文件中定義的配置;第二,vite如何將.env文件中配置的環(huán)境變量掛載到import.meta.env環(huán)境變量上的。通過學習今天vite中的相關源代碼我們就能夠明白。歡迎閱讀本文學習,如果有錯誤的地方請不吝指正。

1.如何讀取.env文件中定義的配置

1.1 問題的著眼點是什么?

首先我們看一下vite如何讀取.env文件中定義的配置。如下圖所示,在項目根目錄下有.env.development,.env.fat,.env.uat,.env.pro四個模式文件,其中development模式是對應默認的開發(fā)環(huán)境用于本地開發(fā),fat模式對應的也是開發(fā)環(huán)境用于自測,uat模式對應的是預發(fā)布環(huán)境用于測試團隊測試,pro模式對應的是生產(chǎn)環(huán)境也叫線上環(huán)境用于客戶使用。

那么如何能夠讓vite知道我們要使用相關模式的文件呢?運行vite 或者vite build命令時可以通過--mode或者-m設置環(huán)境模式(詳見文檔),如下圖所示:

這就提示我們要了解vite如何讀取定義環(huán)境變量的模式文件則需要從vite命令或者vite build命令入手,接下來從vite命令入手研究一下。

1.2 vite的命令定義在何處?

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

當我們使用vite命令的時候,會執(zhí)行bin目錄下的vite.js文件,看一下這個文件(路徑:vite/packages/vite/bin/vite.js):

可以看到這段代碼的關鍵是執(zhí)行start方法,而start方法是導入打包后的cli.js文件,那么這個打包后的文件對應的原文件是哪個文件呢?vite打包的時候是使用rollup的,所以我們看一下rollup的配置文件(路徑:vite/packages/vite/rollup.config.ts):

如上代碼可以看出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(&#39;-m, --mode <mode>&#39;, `[string] set env mode`)
cli
  .command(&#39;[root]&#39;, &#39;start dev server&#39;) // default command
  .alias(&#39;serve&#39;) // the command is called &#39;serve&#39; in Vite&#39;s API
  .option(&#39;--port <port>&#39;, `[number] specify port`)
  .action(async (root: string, options: ServerOptions & GlobalCLIOptions) => {
    const { createServer } = await import(&#39;./server&#39;)
    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?):用于創(chuàng)建一個cac實例,name參數(shù)是可選的。

  • option(name, description, config): 用于設置配置項。

  • command(name, description, config?): 聲明cli命令,可以給命令設置獨立的配置項喝其配置后的執(zhí)行動作。

  • command.alias(name):給cli命令起別名。

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

可以看出,當運行vite命令的時候會執(zhí)行createServer方法,我們這里要注意參數(shù)mode就是我們運行命令時通過--mode 或者 -m指定的參數(shù),下面來研究createServer方法。

1.3.2 createServer

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

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

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

1.3.3 resolveConfig

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

import { loadEnv, resolveEnvPrefix } from &#39;./env&#39;
export async function resolveConfig(
  inlineConfig: InlineConfig,
  command: &#39;build&#39; | &#39;serve&#39;,
  defaultMode = &#39;development&#39;,
  defaultNodeEnv = &#39;development&#39;,
): 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 文件。

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

import { parse } from &#39;dotenv&#39;
import { arraify, lookupFile } from &#39;./utils&#39;

export function loadEnv(
  mode: string,
  envDir: string,
  prefixes: string | string[] = &#39;VITE_&#39;,
): Record<string, string> {
  prefixes = arraify(prefixes)
  const env: Record<string, string> = {}
  const envFiles = [
    /** default file */ `.env`,
    /** local file */ `.env.local`,
    /** mode file */ `.env.${mode}`,
    /** mode local file */ `.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 === &#39;NODE_ENV&#39; &&
      process.env.VITE_USER_NODE_ENV === undefined
    ) {
      // NODE_ENV override in .env file
      process.env.VITE_USER_NODE_ENV = value
    }
  }

  return env
}

如上代碼所示理解loadEnv方法注意以下幾個方面:

  • 該方法接收三個參數(shù),分別是模式、.env文件的路徑還有環(huán)境變量的前綴。

  • 使用遞歸方法lookupFile找到.env文件的路徑,使用fs.readFileSync讀取文件。

  • 使用dotenv提供的方法解析.env文件內(nèi)容。

關于dotenv可以學習川哥的文章,也可以看看筆者的源碼共讀語雀筆記。至此,我們了解了vite是如何讀取.env文件中定義的環(huán)境變量了。下面我們研究第二個問題vite如何將.env中配置的環(huán)境變量掛載到import.meta.env環(huán)境變量上。

2.如何將變量掛載到import.meta.env環(huán)境變量上

2.1 vite的環(huán)境變量和import.meta

Vite 在一個特殊的 import.meta.env 對象上暴露環(huán)境變量,有一些在所有情況下都可以使用的內(nèi)建變量:

import.meta.env.MODE: {string} 應用運行的模式。

import.meta.env.BASE_URL: {string} 部署應用時的基本 URL。他由base 配置項決定。

import.meta.env.PROD: {boolean} 應用是否運行在生產(chǎn)環(huán)境。

import.meta.env.DEV: {boolean} 應用是否運行在開發(fā)環(huán)境 (永遠與 import.meta.env.PROD相反)。

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

詳見環(huán)境變量。這里我們要解釋一下import.meta。它是一個給JavaScript模塊暴露特定上下文的元數(shù)據(jù)屬性的對象。它包含了這個模塊的信息,比如說這個模塊的URL。詳見import.meta 的MDN文檔。需要注意不可以在模塊的外部使用import.meta,如下圖所示:

2.2 resolveConfig

在上文中我們已經(jīng)研究了resolveConfig的代碼,我們再來看以下此方法中的另一段代碼(路徑:vite/packages/vite/src/node/config.ts):

import {resolvePlugins,} from &#39;./plugins&#39;

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

這里調用了resolvePlugins,接收resolved對象,此對象中含有開發(fā)者所指定的模式以及.env文件中的環(huán)境變量。我們接著看一下resolvePlugins方法。

2.3 resolvePlugins

節(jié)選resolvePlugins方法如下(路徑:vite/packages/vite/src/node/plugins/index.ts):

import { definePlugin } from &#39;./define&#39;

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, {
    &#39;import.meta.env.&#39;: `({}).`,
    &#39;import.meta.env&#39;: JSON.stringify(config.env),
    &#39;import.meta.hot&#39;: `false`,
  })
}

這段代碼的關鍵部分在于第8-10行的for循環(huán),將.env文件中定義的環(huán)境變量掛在到了import.meta.env上。至此,如何也了解了vite是如何將環(huán)境變量掛在到import.meta.env環(huán)境變量上。

總結

通過閱讀vite的源碼,我們了解到vite處理.env文件時涉及到的兩個關鍵問題:第一,vite如何讀取.env文件中定義的配置;第二,vite如何將.env文件中配置的環(huán)境變量掛載到import.meta.env環(huán)境變量上。

對于第一問題,我們了解到vite使用cac定義命令,當執(zhí)行vite命令并通過--mode或者-m選項指定模式的時候,vite會拿到mode, 然后vite會去項目目錄下查找對應.env.[模式]的文件并讀取其內(nèi)容,然后通過dotenv的parse方法解析文件內(nèi)容,將定義的環(huán)境變量整合到resolved中。

對于第二個問題,我們了解到vite的resolveConfig方法中會執(zhí)行插件解析的方法resolvePlugins,而此方法又會調用definePlugin方法,在definePlugin方法中會完成將.env文件中定義的變量掛載到import.meta.env環(huán)境變量上。

(學習視頻分享:vuejs入門教程、編程基礎視頻

以上是深入探討vite是怎么解析.env文件的的詳細內(nèi)容。更多信息請關注PHP中文網(wǎng)其他相關文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權歸原作者所有,本站不承擔相應法律責任。如您發(fā)現(xiàn)有涉嫌抄襲侵權的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅動的應用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1601
29
PHP教程
1502
276
PHP與Vue:完美搭檔的前端開發(fā)利器 PHP與Vue:完美搭檔的前端開發(fā)利器 Mar 16, 2024 pm 12:09 PM

PHP與Vue:完美搭檔的前端開發(fā)利器在當今互聯(lián)網(wǎng)高速發(fā)展的時代,前端開發(fā)變得愈發(fā)重要。隨著用戶對網(wǎng)站和應用的體驗要求越來越高,前端開發(fā)人員需要使用更加高效和靈活的工具來創(chuàng)建響應式和交互式的界面。PHP和Vue.js作為前端開發(fā)領域的兩個重要技術,搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結合,以及詳細的代碼示例,幫助讀者更好地理解和應用這兩

Go語言前端技術探秘:前端開發(fā)新視野 Go語言前端技術探秘:前端開發(fā)新視野 Mar 28, 2024 pm 01:06 PM

Go語言作為一種快速、高效的編程語言,在后端開發(fā)領域廣受歡迎。然而,很少有人將Go語言與前端開發(fā)聯(lián)系起來。事實上,使用Go語言進行前端開發(fā)不僅可以提高效率,還能為開發(fā)者帶來全新的視野。本文將探討使用Go語言進行前端開發(fā)的可能性,并提供具體的代碼示例,幫助讀者更好地了解這一領域。在傳統(tǒng)的前端開發(fā)中,通常會使用JavaScript、HTML和CSS來構建用戶界面

vue.js vs.反應:特定于項目的考慮因素 vue.js vs.反應:特定于項目的考慮因素 Apr 09, 2025 am 12:01 AM

Vue.js適合中小型項目和快速迭代,React適用于大型復雜應用。1)Vue.js易于上手,適用于團隊經(jīng)驗不足或項目規(guī)模較小的情況。2)React的生態(tài)系統(tǒng)更豐富,適合有高性能需求和復雜功能需求的項目。

前端面試官常問的問題 前端面試官常問的問題 Mar 19, 2024 pm 02:24 PM

在前端開發(fā)面試中,常見問題涵蓋廣泛,包括HTML/CSS基礎、JavaScript基礎、框架和庫、項目經(jīng)驗、算法和數(shù)據(jù)結構、性能優(yōu)化、跨域請求、前端工程化、設計模式以及新技術和趨勢。面試官的問題旨在評估候選人的技術技能、項目經(jīng)驗以及對行業(yè)趨勢的理解。因此,應試者應充分準備這些方面,以展現(xiàn)自己的能力和專業(yè)知識。

Golang與前端技術結合:探討Golang如何在前端領域發(fā)揮作用 Golang與前端技術結合:探討Golang如何在前端領域發(fā)揮作用 Mar 19, 2024 pm 06:15 PM

Golang與前端技術結合:探討Golang如何在前端領域發(fā)揮作用,需要具體代碼示例隨著互聯(lián)網(wǎng)和移動應用的快速發(fā)展,前端技術也愈發(fā)重要。而在這個領域中,Golang作為一門強大的后端編程語言,也可以發(fā)揮重要作用。本文將探討Golang如何與前端技術結合,以及通過具體的代碼示例來展示其在前端領域的潛力。Golang在前端領域的作用作為一門高效、簡潔且易于學習的

Vue.js很難學習嗎? Vue.js很難學習嗎? Apr 04, 2025 am 12:02 AM

Vue.js不難學,特別是對于有JavaScript基礎的開發(fā)者。1)其漸進式設計和響應式系統(tǒng)簡化了開發(fā)過程。2)組件化開發(fā)讓代碼管理更高效。3)使用示例展示了基本和高級用法。4)常見錯誤可以通過VueDevtools調試。5)性能優(yōu)化和最佳實踐如使用v-if/v-show和key屬性可提升應用效率。

VUE是用于前端還是后端? VUE是用于前端還是后端? Apr 03, 2025 am 12:07 AM

Vue.js主要用于前端開發(fā)。1)它是一個輕量級且靈活的JavaScript框架,專注于構建用戶界面和單頁面應用。2)Vue.js的核心是其響應式數(shù)據(jù)系統(tǒng),數(shù)據(jù)變化時視圖自動更新。3)它支持組件化開發(fā),UI可拆分為獨立、可復用的組件。

了解React的主要功能:前端視角 了解React的主要功能:前端視角 Apr 18, 2025 am 12:15 AM

React的主要功能包括組件化思想、狀態(tài)管理和虛擬DOM。1)組件化思想允許將UI拆分成可復用的部分,提高代碼可讀性和可維護性。2)狀態(tài)管理通過state和props管理動態(tài)數(shù)據(jù),變化觸發(fā)UI更新。3)虛擬DOM優(yōu)化性能,通過內(nèi)存中的DOM副本計算最小操作更新UI。

See all articles