中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

dotenv怎么從.env文件中讀取環境變量

發布時間:2022-12-27 16:22:36 來源:億速云 閱讀:234 作者:iii 欄目:開發技術

這篇文章主要講解了“dotenv怎么從.env文件中讀取環境變量”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“dotenv怎么從.env文件中讀取環境變量”吧!

    引言

    dotenv.env文件中讀取環境變量,然后將其添加到process.env中。這是一個非常簡單的庫,但是它在開發中非常有用,因為它允許你在.env文件中存儲敏感信息,而不是將其存儲在代碼中。

    現在很多庫都支持.env文件,例如create-react-appvue-clinext.js等。

    使用

    根據READMEdotenv只有兩個方法:

    • config:讀取.env文件并將其添加到process.env中。

    • parse:解析一段包含環境變量的字符串或Buffer,并返回一個對象。

    const dotenv = require('dotenv')
    // 讀取.env文件并將其添加到process.env中
    dotenv.config()
    // 解析一段包含環境變量的字符串或Buffer,返回一個對象
    const config1 = dotenv.parse('FOO=bar\nBAR=foo')
    console.log(config1) // { FOO: 'bar', BAR: 'foo' }
    const buffer = Buffer.from('FOO=bar\nBAR=foo')
    const config2 = dotenv.parse(buffer)
    console.log(config2) // { FOO: 'bar', BAR: 'foo' }

    可以看到,dotenv的使用非常簡單,通常我們只需要調用config方法即可。

    還有一種方法是預加載,直接通過node -r dotenv/config來運行腳本,這樣就不需要在腳本中引入dotenv了。

    源碼

    源碼在lib/main.js中,先來看一下全部的代碼:

    const fs = require('fs')
    const path = require('path')
    const os = require('os')
    const packageJson = require('../package.json')
    const version = packageJson.version
    const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\'|[^'])*'|\s*"(?:\"|[^"])*"|\s*`(?:\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg
    // Parser src into an Object
    function parse (src) {
      const obj = {}
      // Convert buffer to string
      let lines = src.toString()
      // Convert line breaks to same format
      lines = lines.replace(/\r\n?/mg, '\n')
      let match
      while ((match = LINE.exec(lines)) != null) {
        const key = match[1]
        // Default undefined or null to empty string
        let value = (match[2] || '')
        // Remove whitespace
        value = value.trim()
        // Check if double quoted
        const maybeQuote = value[0]
        // Remove surrounding quotes
        value = value.replace(/^(['"`])([\s\S]*)\1$/mg, '$2')
        // Expand newlines if double quoted
        if (maybeQuote === '"') {
          value = value.replace(/\n/g, '\n')
          value = value.replace(/\r/g, '\r')
        }
        // Add to object
        obj[key] = value
      }
      return obj
    }
    function _log (message) {
      console.log(`[dotenv@${version}][DEBUG] ${message}`)
    }
    function _resolveHome (envPath) {
      return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath
    }
    // Populates process.env from .env file
    function config (options) {
      let dotenvPath = path.resolve(process.cwd(), '.env')
      let encoding = 'utf8'
      const debug = Boolean(options && options.debug)
      const override = Boolean(options && options.override)
      if (options) {
        if (options.path != null) {
          dotenvPath = _resolveHome(options.path)
        }
        if (options.encoding != null) {
          encoding = options.encoding
        }
      }
      try {
        // Specifying an encoding returns a string instead of a buffer
        const parsed = DotenvModule.parse(fs.readFileSync(dotenvPath, { encoding }))
        Object.keys(parsed).forEach(function (key) {
          if (!Object.prototype.hasOwnProperty.call(process.env, key)) {
            process.env[key] = parsed[key]
          } else {
            if (override === true) {
              process.env[key] = parsed[key]
            }
            if (debug) {
              if (override === true) {
                _log(`"${key}" is already defined in `process.env` and WAS overwritten`)
              } else {
                _log(`"${key}" is already defined in `process.env` and was NOT overwritten`)
              }
            }
          }
        })
        return { parsed }
      } catch (e) {
        if (debug) {
          _log(`Failed to load ${dotenvPath} ${e.message}`)
        }
        return { error: e }
      }
    }
    const DotenvModule = {
      config,
      parse
    }
    module.exports.config = DotenvModule.config
    module.exports.parse = DotenvModule.parse
    module.exports = DotenvModule

    可以看到最后導出的是一個對象,包含了configparse兩個方法。

    config

    config方法的作用是讀取.env文件,并將其添加到process.env中。

    function config (options) {
      let dotenvPath = path.resolve(process.cwd(), '.env')
      let encoding = 'utf8'
      const debug = Boolean(options && options.debug)
      const override = Boolean(options && options.override)
    }

    首先定義了一些變量:

    • dotenvPath.env文件的路徑

    • encoding是文件的編碼

    • debugoverride分別表示是否開啟調試模式和是否覆蓋已有的環境變量。

    if (options) {
      if (options.path != null) {
        dotenvPath = _resolveHome(options.path)
      }
      if (options.encoding != null) {
        encoding = options.encoding
      }
    }

    然后判斷了一下options是否存在,如果存在的話,就會根據options的值來修改dotenvPathencoding的值。

    const parsed = DotenvModule.parse(fs.readFileSync(dotenvPath, { encoding }))

    然后是調用parse方法來解析.env文件,parse方法的實現在下面會講到。

    這里是只用fs.readFileSync來讀取.env文件,然后將其傳入parse方法中,接著往下:

    Object.keys(parsed).forEach(function (key) {
        if (!Object.prototype.hasOwnProperty.call(process.env, key)) {
            process.env[key] = parsed[key]
        } else {
            if (override === true) {
                process.env[key] = parsed[key]
            }
            if (debug) {
                if (override === true) {
                    _log(`"${key}" is already defined in `process.env` and WAS overwritten`)
                } else {
                    _log(`"${key}" is already defined in `process.env` and was NOT overwritten`)
                }
            }
        }
    })

    這里是遍歷parsed對象,然后將其添加到process.env中,如果process.env中已經存在了該環境變量,那么就會根據override的值來決定是否覆蓋。

    debug的值表示是否開啟調試模式,如果開啟了調試模式,那么就會打印一些日志。

    最后就是直接返回parsed對象。

    parse

    parse方法的作用是解析.env文件,將其轉換為一個對象。

    const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\'|[^'])*'|\s*"(?:\"|[^"])*"|\s*`(?:\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg
    function parse (src) {
      const obj = {}
      // Convert buffer to string
      let lines = src.toString()
      // Convert line breaks to same format
      lines = lines.replace(/\r\n?/mg, '\n')
      let match
      while ((match = LINE.exec(lines)) != null) {
        const key = match[1]
        // Default undefined or null to empty string
        let value = (match[2] || '')
        // Remove whitespace
        value = value.trim()
        // Check if double quoted
        const maybeQuote = value[0]
        // Remove surrounding quotes
        value = value.replace(/^(['"`])([\s\S]*)\1$/mg, '$2')
        // Expand newlines if double quoted
        if (maybeQuote === '"') {
          value = value.replace(/\n/g, '\n')
          value = value.replace(/\r/g, '\r')
        }
        // Add to object
        obj[key] = value
      }
      return obj
    }

    首先定義了一個正則表達式LINE,用來匹配.env文件中的每一行。

    然后是將src轉換為字符串,然后將換行符統一為\n

    接著就是核心,通過正則表達式的特性通過while循環來匹配每一行。

    這個正則著實有點復雜,我是正則渣渣,可以在regex101查看一下。

    dotenv怎么從.env文件中讀取環境變量

    這個正則上面標出了三種顏色,和下面的匹配的值的顏色相互對應,然后右邊會展示匹配的值。

    這里我不過多解讀,可以自己去看一下,然后輸入不同的值對比一下結果。

    通過上面的截圖可以看到匹配會捕獲兩個值,第一個是環境變量的名稱,第二個是環境變量的值。

    然后對值進行處理,首先去掉首尾的空格,然后通過正則去掉首尾的引號,最后再將轉義的換行符轉換還原。

    經過上面的處理,就可以將每一行的環境變量添加到obj對象中了,最后返回obj對象。

    感謝各位的閱讀,以上就是“dotenv怎么從.env文件中讀取環境變量”的內容了,經過本文的學習后,相信大家對dotenv怎么從.env文件中讀取環境變量這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    西和县| 新宁县| 偏关县| 灌阳县| 桃园县| 南岸区| 霞浦县| 阿图什市| 洱源县| 托克托县| 河源市| 特克斯县| 广宗县| 红安县| 永胜县| 昭苏县| 宝坻区| 中卫市| 盖州市| 新绛县| 尉犁县| 雷波县| 余江县| 集安市| 屯门区| 汕尾市| 兴国县| 西安市| 洞口县| 肃北| 柘城县| 浮山县| 华阴市| 瑞昌市| 西丰县| 林州市| 青铜峡市| 甘南县| 双桥区| 璧山县| 西安市|