前端项目中 .env 文件的原理和实现

为什么要用 .env?

在前端开发中,我们经常需要区分不同环境下的配置,比如:

  • 开发环境(开发调试用的 API 地址、本地调试开关);
  • 测试环境(给测试同学用的接口域名、测试账号);
  • 生产环境(线上稳定接口、CDN 域名、是否启用 mock 数据等)。

如果把这些配置直接写死在代码里,不仅管理麻烦,还容易出现「改配置 → 重新打包 → 发错环境」的坑。

这时候 .env 文件就派上用场了。

👉 它能把不同环境的变量抽离出来,统一放在一个文件里,通过工具在打包或运行时注入到代码中,大大提升了项目的可维护性。


环境准备

我们先来简单准备下环境。

如果想直接看 dotenv 的源码,可以克隆官方项目:

bash 复制代码
git clone https://github.com/motdotla/dotenv.git
# cd dotenv && yarn i
# VSCode 打开当前项目
code .

dotenv 的作用

官方项目地址:

👉 github.com/motdotla/do...

dotenv 是一个零依赖模块,用来把 .env 文件中的环境变量加载到 process.env 中。

如果需要进一步使用变量展开,还可以配合 dotenv-expand 一起使用。

在前端项目里,.env 文件非常常见,比如 vue-cli 和 create-react-app 都支持它。


.env 文件写法示例

ini 复制代码
NAME=gengyun
AGE=18
VITE_APP_ENV=production
VITE_ROUTER_BASE_URL=/ai-form
VITE_APP_PRO_USE_MOCK=true

从上面这个 .env 文件就能看出来,.env 的主要用途就是:

  1. 读取 .env 文件;
  2. 解析成 key=value 形式的对象;
  3. 挂载到 process.env 上;
  4. 最后返回解析好的对象,方便使用。

一个简易版实现

下面写一个简单的实现,核心就是 用 Node.js 读取文件,解析成对象,然后赋值给 process.env。

javascript 复制代码
const fs = require('fs');
const path = require('path');

const parse = function (src) {
  const obj = {};
  src.toString().split('\n').forEach(function (line) {
    const keyValueArr = line.split('=');
    const key = keyValueArr[0];
    const val = keyValueArr[1] || '';
    obj[key] = val;
  });
  return obj;
}

const config = function () {
  const dotenvPath = path.resolve(process.cwd(), '.env');
  const parsed = parse(fs.readFileSync(dotenvPath, 'utf-8'));

  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);

module.exports.config = config;
module.exports.parse = parse;

虽然能用,但这个 config 函数还很简陋,缺少一些常见功能,比如:

  • 支持用户自定义 .env 文件路径;
  • 支持自定义编码;
  • 添加 debug 模式,方便输出提示;
  • 更友好的报错信息(毕竟 .env 文件写法很随意)。

升级版实现

官方的 dotenv 库在源码里对这些功能做了处理,比如路径解析、编码设置、调试日志等。我们也可以稍微扩展一下:

ini 复制代码
const fs = require('fs');
const os = require('os');
const path = require('path');

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

const config = function (options) {
  let dotenvPath = path.resolve(process.cwd(), '.env');
  let encoding = 'utf8';
  let debug = false;

  if (options) {
    if (options.path != null) {
      dotenvPath = resolveHome(options.path);
    }
    if (options.encoding != null) {
      encoding = options.encoding;
    }
    if (options.debug != null) {
      debug = true;
    }
  }

  try {
    const parsed = parse(fs.readFileSync(dotenvPath, { encoding }), { debug });

    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 函数还处理了更多细节,比如:

  • 正则匹配;
  • 支持单双引号;
  • 跨平台兼容(Windows/Linux 换行符不同)。

一句话总结

dotenv 的原理很简单:

👉 用 fs.readFileSync 读取 .env 文件,解析成 key=value 对象,然后把对象里的变量挂到 process.env 上。


前端项目里的额外说明

不过要注意:

在 Node.js 环境 (如服务端)下,直接挂到 process.env 就能用了。

但在 前端项目 (浏览器环境)里,浏览器本身是访问不到 process 的。

所以像 vue-cli 或 vite 这样的工具,会在构建阶段借助 webpack 的 DefinePlugin (或 Vite 内置的变量替换机制)把 .env 文件里的变量直接替换成具体值,注入到代码里。


总结 & 扩展思考

.env 文件的核心价值在于:

  • 配置解耦:不用把不同环境的配置写死在代码里;
  • 方便管理:一套代码,多套环境;
  • 安全性:敏感信息可以集中管理,避免硬编码到仓库。

扩展思考:

  • 在 前端项目 中,哪些变量适合放在 .env?哪些不能?(比如 API 地址 可以,秘钥 一定不要!)
  • 在 多人协作 时,如何管理不同成员的本地 .env 文件?(比如 .env.local 不要提交到 git)
  • 除了 dotenv,有没有类似的工具?

这些问题都值得在实际项目中思考和总结。

相关推荐
2601_9499506311 分钟前
练题簿在线免费刷题 从资料整理到考前自测
面试·职场和发展·pdf·word·刷题
福兮说1 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
时间的拾荒人2 小时前
Qt 多线程详解:从 QThread 到实战
开发语言·qt·面试
海绵宝宝转agent2 小时前
MySql高频面试八股开源笔记总结
mysql·面试·开源
郑州光合科技余经理2 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆6663 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)3 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
lsc_blog3 小时前
远程和居家办公的经历,技术简历上怎么摆
面试·职场和发展·重构·pdf·求职招聘
码艺-Alimjan4 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_4 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线