面試官:項目中常用的 .env 文件原理是什么?如何實現?

1. 前言

大家好,我是若川。持續組織了5個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。

本文倉庫 https://github.com/lxchuan12/dotenv-analysis.git,求個star^_^[1]

源碼共讀活動

每周一期,已進行到19期。于是搜尋各種值得我們學習,且代碼行數不多的源碼。dotenv 主文件僅118行[2],非常值得我們學習。

閱讀本文,你將學到:

1.?學會?dotenv?原理和實現
2.?學會使用?fs模塊?獲取文件并解析
3.?等等

2. 環境準備

#?推薦克隆我的項目,保證與文章同步
git?clone?https://github.com/lxchuan12/dotenv-analysis.git
#?npm?i?-g?yarn
cd?dotenv-analysis/dotenv?&&?yarn?i
#?VSCode?直接打開當前項目
#?code?.
#?我寫的例子都在?examples?這個文件夾中,可以啟動服務本地查看調試
#?在?dotenv-analysis?目錄下
node?examples/index.js#?或者克隆官方項目
git?clone?https://github.com/motdotla/dotenv.git
#?npm?i?-g?yarn
cd?dotenv?&&?yarn?i
#?VSCode?直接打開當前項目
#?code?.

如果需要對源碼進行調試,可以看我的這篇文章:新手向:前端程序員必學基本技能——調試JS代碼,這里就不再贅述了。

3. dotenv 的作用

dotenv[3]

Dotenv 是一個零依賴模塊,可將 .env 文件中的環境變量加載到 process.env 中。

如果需要使用變量,則配合如下擴展包使用。

dotenv-expand[4]

眾所周知,.env 文件在我們項目中非常常見,在 vue-clicreate-react-app 中都有使用。

vue-cli .env[5]

create-react-app .env[6]

4. .env 文件使用

我們項目中經常會用到.env 文件寫法:

NAME=若川
AGE=18
BLOG=https://lxchuan12.gitee.io
MP_WEIXIN='若川視野'
ACTIVITY=每周一起學200行左右的源碼共讀活動
WEIXIN=加我微信?ruochuan12?參與

單從這個文件來看,我們可以知道有如下功能需要實現:

  1. 讀取 .env 文件

  2. 解析 .env 文件拆成鍵值對的對象形式

  3. 賦值到 process.env 上

  4. 最后返回解析后得到的對象

5. 簡單實現

根據分析問題,我們最終可以簡單把代碼實現如下:

const?fs?=?require('fs');
const?path?=?require('path');const?parse?=?function?parse(src){const?obj?=?{};//?用換行符?分割//?比如/***?NAME=若川*?AGE=18*?MP_WEIXIN=若川視野*?BLOG=https://lxchuan12.gitee.io*?ACTIVITY=每周一起學200行左右的源碼共讀活動*?WEIXIN=加我微信?ruochuan12?參與*/src.toString().split('\n').forEach(function(line,?index){//?用等號分割const?keyValueArr?=?line.split('=');//?NAMEkey?=?keyValueArr[0];//?若川val?=?keyValueArr[1]?||?'';obj[key]?=?val;});//?{?NAME:?'若川',?...?}return?obj;
}const?config?=?function(){//?讀取?node?執行的當前路徑下的?.env?文件let?dotenvPath?=?path.resolve(process.cwd(),?'.env');//?按?utf-8?解析文件,得到對象//?{?NAME:?'若川',?...?}const?parsed?=?parse(fs.readFileSync(dotenvPath,?'utf-8'));//?鍵值對形式賦值到?process.env?變量上,原先存在的不賦值Object.keys(parsed).forEach(function(key){if(!Object.prototype.hasOwnProperty.call(process.env,?key)){process.env[key]?=?parsed[key];}});//?返回對象return?parsed;
};console.log(config());
console.log(process.env);//?導出?config?parse?函數
module.exports.config?=?config;
module.exports.parse?=?parse;

6. 繼續完善 config 函數

簡版的 config 函數還缺失挺多功能,比如:

可由用戶自定義路徑
可由用戶自定義解析編碼規則
添加?debug?模式
完善報錯輸出,用戶寫的 env 文件自由度比較大,所以需要容錯機制。

根據功能,我們很容易實現以下代碼:

function?resolveHome?(envPath)?{return?envPath[0]?===?'~'???path.join(os.homedir(),?envPath.slice(1))?:?envPath
}const?config?=?function(options){//?讀取?node?執行的當前路徑下的?.env?文件let?dotenvPath?=?path.resolve(process.cwd(),?'.env');//?utf8let?encoding?=?'utf8';//?debug?模式,輸出提示等信息let?debug?=?false;//?對象if?(options)?{if?(options.path?!=?null)?{//?解析路徑dotenvPath?=?resolveHome(options.path)}//?使用配置的編碼方式if?(options.encoding?!=?null)?{encoding?=?options.encoding}//?有配置就設置為?trueif?(options.debug?!=?null)?{debug?=?true}}try?{//?按?utf-8?解析文件,得到對象//?{?NAME:?'若川',?...?}//?debug?傳遞給?parse?函數?便于const?parsed?=?parse(fs.readFileSync(dotenvPath,?{?encoding?}),?{?debug?});//?鍵值對形式賦值到?process.env?變量上,原先存在的不賦值Object.keys(parsed).forEach(function(key){if(!Object.prototype.hasOwnProperty.call(process.env,?key)){process.env[key]?=?parsed[key];}?else?if?(debug)?{console.log(`"${key}"?is?already?defined?in?\`process.env\`?and?will?not?be?overwritten`);}});//?返回對象return?parsed;}catch?(e)?{return?{?error:?e?};}
};

dotenv 源碼中,parse 函數主要是一些正則和單雙引號、跨平臺等細致處理。這里就暫時不闡述,讀者朋友可以查看dotenv 源碼[7]

7. 總結

鑒于文章不宜過長,文章只比較深入的分析了 config 函數。parse 函數目前沒有深入分析。

一句話總結 dotenv 庫的原理。fs.readFileSync 讀取 .env 文件,并解析文件為鍵值對形式的對象,將最終結果對象遍歷賦值到 process.env

我們也可以不看 dotenv 源碼,根據 api 倒推,自己來實現這樣的功能。最終看看和 ?dotenv 源碼本身有什么差別。這樣也許更能鍛煉自己。或者用 ts 重構它。

本文同時也給我們啟發:圍繞工作常用的技術包和庫值得深入學習,做到知其然,知其所以然

值得一提的是:dotenv 源碼使用的是 flow 類型。vue2 源碼也是用的 flow。vue3 源碼改用 ts了。

最后可以持續關注我@若川。歡迎加我微信 ruochuan12 交流,參與 源碼共讀 活動,每周大家一起學習200行左右的源碼,共同進步。

參考資料

[1]

本文倉庫 https://github.com/lxchuan12/dotenv-analysis.git,求個star^_^: https://github.com/lxchuan12/dotenv-analysis.git

[2]

dotenv 主文件僅118行: https://github.com/motdotla/dotenv/blob/master/lib/main.js

[3]

dotenv: https://github.com/motdotla/dotenv

[4]

dotenv-expand: https://github.com/motdotla/dotenv-expand

[5]

vue-cli .env: https://cli.vuejs.org/zh/guide/mode-and-env.html#%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F

[6]

create-react-app .env: https://create-react-app.dev/docs/adding-custom-environment-variables/#what-other-env-files-can-be-used

[7]

dotenv 源碼: https://github.com/motdotla/dotenv/blob/master/lib/main.js


5ebb88e7842f5ce29ac366751857a03a.gif

·················?若川簡介?·················

你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》20余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助3000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。

325f75f3e76e1c1353e4ce2c3cfa2731.png

識別方二維碼加我微信、拉你進源碼共讀

今日話題

略。分享、收藏、點贊、在看我的文章就是對我最大的支持~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/275046.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/275046.shtml
英文地址,請注明出處:http://en.pswp.cn/news/275046.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

語言分類,我接觸和我想學習的

本文信息和數據出自hyperpolyglot,將當前主流編程語言分為11個大類,分別為:解釋型(PHP,Perl,Python,Ruby,Tcl,Lua,JavaScript,Io)、操作系統自動化型(POSIX Shell,AppleScript,PowerShell)、C風格(C,Objective C,Java,C#)、Pascal風格(Pascal…

梯度下降法和隨機梯度下降法

1. 梯度 在微積分里面,對多元函數的參數求?偏導數,把求得的各個參數的偏導數以向量的形式寫出來,就是梯度。比如函數f(x,y), 分別對x,y求偏導數,求得的梯度向量就是(?f/?x, ?f/?y)T,簡稱grad f(x,y)或者▽f(x,y)。對于在點(x…

一張圖看程序媛阿源的2021個人年度流水賬

大家好,我是若川。持續組織了5個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。本文來自讀者阿源小…

案例研究:設計與方法_如何進行1小時的重新設計(案例研究)

案例研究:設計與方法速度設計簡介 (Intro to Speed Designing) I’ve been an advocate of speed redesigning technique for a while. The idea is simple — decrease the hand-eye lag and make super quick decisions, seemingly without thinking. The logic behind it is…

圖文并茂重新認識下遞歸

大家好,我是若川。持續組織了5個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。對于大部分前端(包…

《C和指針》讀書筆記

看過了經典的K&R C,又看了這本Pointers on C,溫習了C語言的基本語法。 在重溫過程中,感覺需要重點把握的知識是指針、結構和動態內存分配。 這對今后的算法和操作系統方面的研究學習很有幫助。 3.2.3 聲明指針int* b, c, d;本以為這條語句…

FPGA設計者的5項基本功

記得《佟林傳》里,佟林練的基本功是“繞大樹、解皮繩”,然后才練成了什么“鬼影隨行、柳葉綿絲掌”。 在我看來,成為一名說得過去的FPGA設計者,需要練好5項基本功:仿真、綜合、時序分析、調試、驗證。 需要強調的一點是…

unity 全息交互ui_UI向3D投影全息界面的連續發展

unity 全息交互uiThe user interface has been natural in its evolution and strategically heading towards the 3D-projection holographic interface (3D-PHI) era.用戶界面在其發展過程中一直很自然,并且在戰略上正朝著3D投影全息界面( 3D-PHI )時代邁進。 Si…

開發工具 快捷鍵整理

快捷鍵大全 JAVA 開發工具 MyEclipse -------------------------------------MyEclipse 快捷鍵1(CTRL)-------------------------------------Ctrl1 快速修復CtrlD: 刪除當前行 CtrlQ 定位到最后編輯的地方 CtrlL 定位在某行 CtrlO 快速顯示 OutLine CtrlT 快速顯示當前類…

前端構建新世代,Esbuild 原來還能這么玩!

大家好,我是若川。持續組織了5個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。今天分享一篇esbui…

大三下學期十四周總結

在小組的學習方面,這周主要是對微信小程序的學習。對JSON格式請求在Spring boot與小程序之間的交互有了一些了解。對微信的接口wx.request、wx.uploadFile、wx.chooseImage的接口的使用。微信開發后臺傳過來的響應數據如果不是標準的json格式,需要在小程…

平面設計師和ui設計師_平面設計師為什么要享受所有樂趣?

平面設計師和ui設計師Graphic designers are pretty cool. We have to admit that. Be it their dressing style, their attitude and most importantly their enviable gadgets. Large Mac monitor, wacom tablet, drawing sets, swatchbooks , iPad pro with pencil, humungo…

轉:Xcode下的GDB調試命令

Xcode的調試器為用戶提供了一個GDB的圖形化界面,GDB是GNU組織的開放源代碼調試器。您可以在Xcode的圖形界面里做任何事情;但是,如果您需要您可以在命令行里使用GDB的命令,且gdb可以在終端運行,也可以在Xcode下的控制臺…

web表單設計:點石成金_設計復雜的用戶表單:12個UX最佳實踐

web表單設計:點石成金It’s been a few years that I’ve been taking interest in designing complex user forms, where a lot of information is requested from users. Here are a few industries where you regularly find such flows:幾年來,我一直對設計復雜…

跨平臺開發框架到底哪家強?5款主流框架橫向對比!

跨平臺開發框架到底哪家強?目前市場上有多個專業做跨平臺開發的框架,那么對開發者來說究竟哪一個框架更符合自己的需求呢?筆者特地總結對比了一下不同框架的特性。國內外筆者選擇了一共5個主流的測評對象,分別是RN,Flu…

【一句日歷】2019年6月

【2019年6月1日兒童節星期六】 人們在協商,解決和處理各種狀況時,若要獲得圓滿的結果,平靜的心和自我控制能力必不可少。任何人都明白。如果我們不能很好地控制自我,反而讓焦躁和嗔怒干擾了我們,那么我們的工作不再具有…

Android學習摘要一之Android歷史

Google與你998年9月7日創立,經過十幾年在搜索引擎方面的精耕細作,成為全球互聯網巨頭,尤其在地圖搜索的應用更是引人注目。Google與2007年11月5日宣布基于Linux平臺的開源手機操作系統,名稱為Android,中文譯為“機器人…

c#創建web應用程序_創建Web應用程序圖標集的6個步驟

c#創建web應用程序I am not great at creating logos or icons, mainly because of the lack of practice. So when I was tasked to create an unique icon set for our web app, I wasn’t confident that things will turn out right. After researching effective and rele…

基于pnpm + lerna + typescript的最佳項目實踐 - 理論篇

本文來自作者金虹橋程序員 投稿原文鏈接:https://juejin.cn/post/7043998041786810398本系列文章分為兩篇:理論篇和實踐篇 理論篇:介紹pnpm(pnpm的特點、解決的問題等)、lerna(lerna的常用命令)…

nginx 多進程 + io多路復用 實現高并發

一、nginx 高并發原理 簡單介紹:nginx 采用的是多進程(單線程) io多路復用(epoll)模型 實現高并發 二、nginx 多進程 啟動nginx解析初始化配置文件后會 創建(fork)一個master進程 之后 這個進程會退出 master 進程會…