前端项目中 .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-clicreate-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-clivite 这样的工具,会在构建阶段借助 webpack 的 DefinePlugin (或 Vite 内置的变量替换机制)把 .env 文件里的变量直接替换成具体值,注入到代码里。


总结 & 扩展思考

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

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

扩展思考:

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

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

相关推荐
小高0078 小时前
🚄 前端人必收:5 分钟掌握 ES2025 超实用语法
前端·javascript·面试
程序员海军9 小时前
2025年上半年前端技术圈生态总结分享
前端·vue.js·react.js
记忆怪 bug9 小时前
2025前端面试题及答案(详细)
前端
群联云防护小杜9 小时前
服务器异常负载排查手册 · 隐蔽进程篇
运维·服务器·前端·数据库·笔记·sql·tcp/ip
小小菜鸡ing9 小时前
简单爬一个小说页面 HTML 的title和内容
前端·html
IT_陈寒9 小时前
Spring Boot 3 + GraalVM:5个实战技巧让Java应用启动速度提升300%
前端·人工智能·后端
前端世界10 小时前
前端跨域终极指南:3 种优雅解决方案 + 可运行 Demo
前端·javascript·状态模式
无奈何杨10 小时前
CoolGuard风控系统配置评分卡、权重策略|QLExpress脚本
前端·后端
几度风雨见丹心10 小时前
vue+elementUI 进行表格行内新增及校验,同行其他输入框数据影响当前输入框校验结果
前端·vue.js·elementui
开发者小天10 小时前
在Ant Design Vue 中使用图片预览的插件
前端·javascript·vue.js·前端框架