通用配置搭建——env环境变量+dotenv库

719 阅读8分钟

🧑‍💻基于env环境变量+dotenv库搭建通用配置-HowieCong

一、背景

  • 项目开发过程中,由于不同的开发环境(如开发环境、测试环境、生产环境)有着不同的配置需求,比如在开发环境中我们可能需要开启详细的调试日志,而在生产环境中则需要关闭这些日志以提高性能和安全性

  • 不同的团队成员可能会在不同的环境下进行开发和测试,这就导致了配置管理的复杂性

  • 如果每次切换环境都需要手动修改大量的配置文件,不仅效率低下,还容易出错、

  • 需要一种能够基于env文件抽离通用配置,实现支持环境快速搭建的方案

二、难点/困惑点

  • 配置文件管理混乱:不同环境的配置分散在各个文件中,没有统一的管理方式,导致在切换环境时很难确保所有配置都被正确修改

  • 环境切换效率低下:手动修改配置文件容易出错,而且每次切换环境都需要花费大量的时间去确认和修改配置,影响开发效率

  • 配置安全性问题:一些敏感信息(如 API 密钥)在不同环境中需要不同的处理方式,但如果管理不当,可能会导致信息泄露

三、技术选型/技术方案

(1)采纳方案

  • 使用dotenv库结合自定义的环境变量文件

  • .env.development.env.test.env.production来管理不同环境的配置

(2)淘汰方案

  • 硬编码配置:直接在代码中写入不同环境的配置,这种方式不利于维护和管理,当需要修改配置时,需要修改多处代码

  • 手动复制粘贴配置文件:每次切换环境时手动复制不同的配置文件,容易出错且效率低下

四、技术实现步骤

(1)安装dotenv

  • 在项目中安装dotenv库,它可以帮助我们从.env文件中加载环境变量
npm install dotenv

(2)创建环境变量文件

  • 在项目根目录下创建不同环境的.env文件,如.env.development.env.test.env.production。这些文件中包含了不同环境的配置信息,例如:
# .env.development
OPENAI_API_KEY=your_dev_api_key
DEBUG=true

# .env.production
OPENAI_API_KEY=your_prod_api_key
DEBUG=false

(3)在项目入口文件中加载环境变量

  • 在项目的入口文件(如main.jsindex.js)中,根据当前的环境加载相应的.env文件
const dotenv = require('dotenv');

// 根据当前环境加载不同的 .env 文件
if (process.env.NODE_ENV === 'development') {
  dotenv.config({ path: '.env.development' });
} else if (process.env.NODE_ENV === 'test') {
  dotenv.config({ path: '.env.test' });
} else {
  dotenv.config({ path: '.env.production' });
}

// 现在可以使用环境变量了
const apiKey = process.env.OPENAI_API_KEY;
const debugMode = process.env.DEBUG === 'true';

(4)在代码中使用环境变量

  • 在需要使用配置的地方,直接使用process.env来获取相应的环境变量
// 示例:使用 API 密钥进行 API 调用
const apiUrl = `https://api.example.com?key=${process.env.OPENAI_API_KEY}`;

(5)配置文件的管理和部署

  • 在开发过程中,不同的开发人员可以根据自己的需要修改本地的.env.development文件

  • 在部署到测试环境或生产环境时,只需要将相应的.env.test.env.production文件部署到服务器上即可

四、实现效果/价值

  • 配置管理统一:所有环境的配置都集中在.env文件中,便于管理和维护

  • 环境切换高效:只需要修改NODE_ENV环境变量,就可以快速切换不同的环境,无需手动修改大量的配置文件

  • 配置安全性提高:敏感信息(如 API 密钥)可以存储在.env文件中,并且可以通过将.env文件加入.gitignore来避免将敏感信息提交到代码仓库中

五、讨论

(1)项目中使用了多个不同的框架,这种方案还可行吗?

  • 这种方案仍然可行

  • 因为dotenv库是一个独立的工具,不依赖于特定的框架。无论使用的是 React、Vue 还是其他框架,都可以通过dotenv来加载环境变量。只需要在项目的入口文件中正确加载.env文件,然后在代码中使用process.env来获取环境变量即可

(2)环境变量非常多,这种方案会不会导致性能问题?

  • 不会

  • dotenv库在项目启动时只会加载一次.env文件,将其中的环境变量存储在内存中。后续在代码中使用process.env获取环境变量时,只是从内存中读取数据,性能开销非常小。而且,将配置信息存储在环境变量中,也有利于代码的可维护性和可扩展性

(3)为什么要使用环境变量来配置这些 URL 和开关?

  • 首先,它可以提高代码的可维护性。例如,在开发、测试和生产环境中,API 的 URL 可能不同,通过环境变量可以轻松切换,而不需要在代码中硬编码这些值

  • 其次,增强了代码的安全性,像 API 密钥这类敏感信息可以存储在环境变量中,避免直接暴露在代码仓库中

  • 最后,方便团队协作,不同的开发人员可以根据自己的环境配置相应的变量,而不会相互影响

(4)在 Vue 项目中,如何在代码里获取这些环境变量的值?

  • 在 Vue 项目中,可以通过 import.meta.env 来获取环境变量的值。例如,要获取 VITE_GLOB_API_URL 的值

  • 注意的是,以 VITE_ 开头的环境变量会被 Vite 自动加载并暴露给客户端代码,而其他的环境变量默认是不会暴露的

const apiUrl = import.meta.env.VITE_GLOB_API_URL;
console.log(apiUrl); // 输出:/api

(5)VITE_APP_API_BASE_URL 配置的是本地地址,如果要部署到生产环境,应该如何修改?

  • 在部署到生产环境时,通常会有专门的生产服务器地址。可以通过修改 .env.production 文件(如果没有则创建)来设置生产环境的 API 地址

  • 在构建生产版本时,Vite 会自动使用 .env.production 中的配置,从而将 API 地址切换到生产环境的地址

#.env.production 文件
VITE_APP_API_BASE_URL=https://your-production-server.com/api

(6)VITE_GLOB_OPEN_LONG_REPLY 这个开关可能会影响哪些方面?

  • VITE_GLOB_OPEN_LONG_REPLY 这个开关用于控制是否支持长回复

  • 在代码中,可能会根据这个开关的值来决定是否允许用户请求长回复或者在服务端是否对长回复进行特殊处理

  • 从 API 费用的角度看,开启长回复可能会导致更多的 API 调用或者更长的响应时间,从而增加 API 费用

if (import.meta.env.VITE_GLOB_OPEN_LONG_REPLY === 'true') {
  // 执行允许长回复的相关逻辑
} else {
  // 执行不允许长回复的逻辑,如提示用户回复长度限制
}

(7)VITE_GLOB_APP_PWA 为 false 时,PWA 相关功能是否会被完全禁用?

  • 当 VITE_GLOB_APP_PWA 为 false 时,通常在代码中会根据这个变量的值来决定是否初始化和启用 PWA 相关功能

  • 例如,在 Vue 项目中,可能会在入口文件 main.ts 中进行如下判断:

  • 所以当 VITE_GLOB_APP_PWA 为 false 时,PWA 相关的初始化和功能启用逻辑会被跳过,相当于 PWA 功能被禁用,但项目本身的其他功能不受影响

import { createApp } from 'vue';
import App from './App.vue';

if (import.meta.env.VITE_GLOB_APP_PWA === 'true') {
  // 初始化 PWA 相关插件和逻辑
  import('@/plugins/pwa').then((pwaModule) => {
    const pwaPlugin = pwaModule.default;
    createApp(App).use(pwaPlugin).mount('#app');
  });
} else {
  // 不启用 PWA,正常挂载应用
  createApp(App).mount('#app');
}

(8)如果要启用 PWA,除了将 VITE_GLOB_APP_PWA 设置为 true ,还需要做哪些配置?

  1. 配置 manifest.json 文件:这个文件包含了 PWA 的元数据,如名称、图标、启动画面等信息。需要确保 manifest.json 文件的配置正确,并且在 HTML 中正确引用

  2. 配置 Service Worker:Service Worker 是 PWA 的核心,用于实现离线缓存、推送通知等功能。需要创建一个 Service Worker 文件,并在项目中进行注册。例如,在 main.ts 中注册 Service Worker:

if ('serviceWorker' in navigator && import.meta.env.VITE_GLOB_APP_PWA === 'true') {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js')
     .then((registration) => {
        console.log('Service Worker registered: ', registration);
      })
     .catch((error) => {
        console.log('Service Worker registration failed: ', error);
      });
  });
}
  1. 配置缓存策略:在 Service Worker 中,需要定义缓存策略,决定哪些文件和资源需要缓存,以及如何更新缓存。例如,使用 workbox 库来简化缓存策略的配置
// service-worker.js
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js');

workbox.routing.registerRoute(
  ({ request }) => request.destination === 'script' || request.destination === 'style',
  new workbox.strategies.StaleWhileRevalidate()
);

workbox.precaching.precacheAndRoute(self.__WB_MANIFEST);

❓其他

1. 疑问与作者HowieCong声明

  • 如有疑问、出错的知识,请及时点击下方链接添加作者HowieCong的其中一种联系方式或发送邮件到下方邮箱告知作者HowieCong

  • 若想让作者更新哪些方面的技术文章或补充更多知识在这篇文章,请及时点击下方链接添加里面其中一种联系方式或发送邮件到下方邮箱告知作者HowieCong

  • 声明:作者HowieCong目前只是一个前端开发小菜鸟,写文章的初衷只是全面提高自身能力和见识;如果对此篇文章喜欢或能帮助到你,麻烦给作者HowieCong点个关注/给这篇文章点个赞/收藏这篇文章/在评论区留下你的想法吧,欢迎大家来交流!

2. 作者社交媒体/邮箱-HowieCong