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

目錄
1.如何讀取.env檔案中定義的設定
1.3.2 createServer
1.3.3 resolveConfig
1.3.4 loadEnv
2.如何將變量掛載到import.meta.env環(huán)境變量上
總結(jié)
首頁 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)境呼叫的介面網(wǎng)域都是不一樣的。如何能做到區(qū)分呢?那就是使用環(huán)境變數(shù)和模式。

使用vite建構的vue3專案中,可以在根目錄下建立.env.[模式]檔案定義一種或多種模式,並且在這個檔案中定義的變數(shù)就是此模式的環(huán)境變數(shù)。定義了環(huán)境變數(shù)之後就可以透過import.meta.env.[變數(shù)名]的方式讀取環(huán)境變數(shù)了。 【相關推薦:vuejs影片教學web前端開發(fā)

那麼我們要來思考兩個問題:第一,vite如何讀取.env檔中定義的配置;第二,vite如何將.env檔案中配置的環(huán)境變數(shù)掛載到import.meta.env環(huán)境變數(shù)上的。透過學習今天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知道我們要使用相關模式的檔案呢?執(zhí)行vite 或vite build指令時可以透過--mode或-m設定環(huán)境模式(詳見文件),如下圖所示:

##這就提示我們要了解vite如何讀取定義環(huán)境變數(shù)的模式檔則需要從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?):用來建立一個cac實例,name參數(shù)是可選的。
  • option(name, description, config): 用來設定組態(tài)項目。
  • 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方法調(diào)用的是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文件的路徑

  • 然后調(diào)用loadEnv方法加載解析.env文件,將結(jié)果賦值給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,
  )
}

這里調(diào)用了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負責解析插件,這里面調(diào)用了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)境變量上。

總結(jié)

通過閱讀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,而此方法又會調(diào)用definePlugin方法,在definePlugin方法中會完成將.env文件中定義的變量掛載到import.meta.env環(huán)境變量上。

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

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

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

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動的應用程序,用於創(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ā)利器在當今網(wǎng)路快速發(fā)展的時代,前端開發(fā)變得愈發(fā)重要。隨著使用者對網(wǎng)站和應用的體驗要求越來越高,前端開發(fā)人員需要使用更有效率和靈活的工具來創(chuàng)建響應式和互動式的介面。 PHP和Vue.js作為前端開發(fā)領域的兩個重要技術,搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結(jié)合,以及詳細的程式碼範例,幫助讀者更好地理解和應用這兩

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)驗、演算法和資料結(jié)構、效能最佳化、跨域請求、前端工程化、設計模式以及新技術和趨勢。面試官的問題旨在評估候選人的技術技能、專案經(jīng)驗以及對行業(yè)趨勢的理解。因此,應試者應充分準備這些方面,以展現(xiàn)自己的能力和專業(yè)知識。

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

Golang與前端技術結(jié)合:探討Golang如何在前端領域發(fā)揮作用,需要具體程式碼範例隨著互聯(lián)網(wǎng)和行動應用的快速發(fā)展,前端技術也愈發(fā)重要。而在這個領域中,Golang作為一門強大的後端程式語言,也可以發(fā)揮重要作用。本文將探討Golang如何與前端技術結(jié)合,以及透過具體的程式碼範例來展示其在前端領域的潛力。 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調(diào)試。 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