项目中常用的 .env 文件原理源码解析

2022-12-26 159阅读 0评论

?=前言

dotenv 是一个用于加载环境变量,在 Node.js 应用程序中可以使用它来简化对环境变量访问。在日常开发中起到了很重要的作用

学习目标:

学会 do.env 原理和实现学会使用 fs模块 获取文件并解析

资源:

源码地址:dotenv

如何使用

使用 dotenv 库,可以在应用程序中创建一个名为 .env 的文件,并在该文件中存储环境变量。然后,可以使用 dotenv 库将这些变量加载到 Node.JS 应用程序中。

例如,您可以在 .env 文件中存储以下内容:

DB_HosT=localhost DB_useRNAME=user DB_PASSWord=password 

使用以下代码将这些变量加载到应用程序中:

reqUIre('dotenv').config(); const dbHost = pROCess.env.DB_HOST; const dbUsername = process.env.DB_USERNAME; const dbPassword = process.env.DB_PASSWORD; 

源码解析

阅读源码之前,可以猜测 dotenv 所做的工作有如下几点。

读取 .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)   if (options) { if (options.path != null) {   dotenvPath = _resolveHome(options.path) } if (options.encoding != null) {   encoding = options.encoding }   } } 

代码中定义了一个变量 dotenvPath,并将其赋值为使用 path.resolve 函数处理后的路径

path.resolve 函数会从右到左依次遍历参数,并返回一个绝对路径。函数的第一个参数是 process.cwd,它返回 Node.js 进程的当前工作目录。第二个参数是字符串 '.env',它表示要在当前工作目录中查找文件名

之后会进行一些参数的判断,如果参数中有path这个变量,则使用_resolveHome函数处理:

function _resolveHome (envPath) {   return envPath[0] === '~' ? path.join(os.homedir(), envPath.Slice(1)) : envPath } 

os.homedir 函数返回当前用户的主目录路径。

_resolveHome 函数可用于将以波浪号开头的路径解析为主目录的实际路径。例如,如果 envPath 等于 '~/documenTS/file.txt',则函数将返回 '/home/user/documents/file.txt'(在基于 Unix 的系统上)或 'C:\Users\user\documents\file.txt'(在 Windows 上)。

解析文件

// 使用 `fs.readFilesync` 函数以指定的编码方式从文件系统中读取文件内容 const parsed = Dotenvmodule.parse(fs.readFileSync(dotenvPath, { encoding })) // 解析文件 function parse (src) {   const obj = {}   // 转为string类型   let lines = src.toString()   // 将换行符转换为相同的格式   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匹配字符lines 中的内容。

const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg 

这个正则表达式的目的是匹配似于环境变量的行。它可以匹配以下格式的行:

VARNAME=value VARNAME: value export VARNAME=value export VARNAME: value 

最后会返回一个含所有变量的对象

赋值操作

  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 }   }  

拿到解析后的对象,使用 Object.keys(parsed) 获取所有的键,然后使用forEach循环将所有的键添加到process.env 中。

总结

dotenv 的功能用一句话来概括就是:解析env文件将其变量添加到process.env中,其中解析部分主要是使用了正则表达式来匹配4种格式的键值对。

以上就是项目中常用的 .env 文件原理源码解析的详细内容,更多关于.env 文件原理的资料请关注云初冀北其它相关文章!

免责声明
本站提供的资源,都来自网络,版权争议与本站无关,所有内容及软件的文章仅限用于学习和研究目的。不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负,我们不保证内容的长久可用性,通过使用本站内容随之而来的风险与本站无关,您必须在下载后的24个小时之内,从您的电脑/手机中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。侵删请致信E-mail:Goliszhou@gmail.com
$

发表评论

表情:
评论列表 (暂无评论,159人围观)

还没有评论,来说两句吧...