<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          每天閱讀一個npm 包源碼:dotenv的作用,項目中.env文件是干嘛的?

          共 4619字,需瀏覽 10分鐘

           ·

          2021-12-16 04:38

          點擊上方 前端陽光,關(guān)注公眾號

          回復(fù)加群,加入技術(shù)交流群交流群


          .env文件 的作用

          ?? 加載 .env 文件中的變量到 process.env

          .env 文件是用來自定義配置的一個簡單方法。我們可以將一些不能在代碼中存儲的 敏感信息 / 賬號數(shù)據(jù) 從代碼中剝離出來,作為環(huán)境變量存儲在 .env 文件中。

          .env 的使用方法

          .env 文件通常不包含在版本控制內(nèi),因為它可能包含敏感的 API Key 或 密碼。所有需要環(huán)境變量定義的項目都可以創(chuàng)建一個 .env.example 文件。項目合作開發(fā)者可以獨立的復(fù)制 .env.example 并重命名為 .env,同時將其修改為正確的本地環(huán)境配置:API Key 或者其他必要的值。在這個使用方法中 .env 文件應(yīng)該添加到 .gitignore 文件中保證永遠(yuǎn)不會出現(xiàn)在 git 中。

          1. 在根目錄下添加 .env 文件,eg:
          DB_HOST=127.0.0.1
          DB_NAME=timeseriesmonitor
          DB_PORT=5432
          DB_USER=tsm
          DB_UNSECURE=true
          1. 引入 dotenv:npm install dotenv
          const dotenv = require('dotenv');

          dotenv.config('./env');  // .env 中的環(huán)境變量被加載到 `process.env` 中

          console.log(`process.env`);
          1. 打印log如下:
          {

            ...
            DB_HOST: '127.0.0.1',
            DB_NAME: 'timeseriesmonitor',
            DB_PORT: '5432',
            DB_UNSECURE: 'true',
            DB_USER: 'tsm',
            ...
          }

          .env 源碼解讀

          核心代碼邏輯在 lib/main.js 中,可以看到剛開始先初始化了幾個正則表達(dá)式

          正則表達(dá)式

          const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/
          const RE_NEWLINES = /\\n/g
          const NEWLINES_MATCH = /\r\n|\n|\r/

          我們可以通過 regexr.com 來交互式查看表達(dá)式各部分的含義:

          • const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/ 匹配 .env 文件中的環(huán)境變量,如 DB_HOST=127.0.0.1,注意到表達(dá)式中有兩個部分被 () 包起來了,這是為了后續(xù)正則匹配的時候方便提取出匹配的字符串,即環(huán)境變量 key,value 的值

          • const RE_NEWLINES = /\\n/g 匹配 \n 字符串,\:前面的 \ 將后面的 \ 轉(zhuǎn)義掉了,所以這里匹配的是 \n 字符串,而不是換行符。

          • const NEWLINES_MATCH = /\r\n|\n|\r/ 匹配換行符:三種換行符是為了兼容各操作系統(tǒng),不同操作系統(tǒng)換行符有所不同:\n: Unix系統(tǒng),\r\n: Windows系統(tǒng),\r: Mac系統(tǒng)

          • 回車 \r 本義是光標(biāo)重新回到本行開頭,r 的英文 return,控制字符為 CR,即 Carriage Return;
          • 換行 \n 本義是光標(biāo)往下一行(不一定到下一行行首),n 的英文 newline,控制字符為 LF,即 Line Feed;

          parse 函數(shù)

          ?? 將 .env 中的字符串轉(zhuǎn)換成 Object

          核心邏輯簡化如下:

          function parse(src{
            const obj = {}
            
            // 用 NEWLINES_MATCH 分割每行表達(dá)式,再 forEach 依次處理
            src.split(NEWLINES_MATCH).forEach(function (line, idx{
              // 用 RE_INI_KEY_VAL 匹配 'KEY=VAL' 中的 'KEY' 和 'VAL'
              const keyValueArr = line.match(RE_INI_KEY_VAL)
              // matched?
              if (keyValueArr != null) {
                const key = keyValueArr[1]
                const val = (keyValueArr[2] || '').trim()
                obj[key] = val
              }
            })

            return obj
          }

          其關(guān)鍵是用了 match 方法匹配 'KEY=VAL' 中的 'KEY' 和 'VAL'。match 方法若匹配到了 line 中的鍵值對則會返回一個數(shù)組,這個數(shù)組的第一項是整個正則表達(dá)式所匹配的字符串,后面會接表達(dá)式中用 () 包圍起來的正則表達(dá)式匹配的字符串。所以 key = keyValueArr[1],val = keyValueArr[2]。

          config 函數(shù)

          ?? 將 .env 中的環(huán)境變量加載到 process.env

          核心邏輯簡化如下:

          function config(options) {
            let dotenvPath = path.resolve(process.cwd(), '.env')

            const parsed = parse(fs.readFileSync(dotenvPath, { encoding: 'utf8' }))

            Object.keys(parsed).forEach(function (key) {
              if (!Object.prototype.hasOwnProperty.call(`process.env`, key)) {
                `process.env`[key] = parsed[key]
              }
            })

            return { parsed }
          }

          config 函數(shù)分三步:

          1. 獲取 .env 文件的路徑并讀取文件
          2. 將文件的字符串傳入 parse 函數(shù)中解析成 Object
          3. 遍歷 Object 將其加載到 process.env

          注意代碼中使用 Object.prototype.hasOwnProperty.call(process.env, key) 判斷 key 是否已經(jīng)存在于 process.env 中,若存在,則不進(jìn)行覆蓋。使用 Object.prototype.hasOwnProperty 是避免原型鏈查找,只判斷 key 是否存在于 process.env 中,而不是其原型鏈上,這樣做可以省去原型鏈查找的耗時。

          總結(jié)

          dotenv 源碼非常簡短只有 118 行,但其有 14.5k star(截止至本文寫稿時間),源碼簡單易懂,建議自己動手看看。

          參考資料

          github 倉庫地址:https://link.juejin.cn/?target=https%3A%2F%2Fgithub.com%2Fmotdotla%2Fdotenv

          Nodejs 環(huán)境下 .env 配置環(huán)境變量:http://www.4k8k.xyz/article/weixin_40817115/86189969

          作者:前端唯一深情 鏈接:https://juejin.cn/post/7040397337138561054

          技術(shù)交流群


          我組建了技術(shù)交流群,里面有很多 大佬,歡迎進(jìn)來交流、學(xué)習(xí)、共建。回復(fù)加群即可。



             “分享、點贊在看” 支持一波??



          瀏覽 150
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  尻尻穴视频 | 北条麻妃 视频 | 色拍拍最新 | 亚洲欧美久久久 | 日本影视91爱爱 |