前言
最近将后端代码部署到服务器了。服务器环境的配置和开发时的配置通常不会一样,所以每次部署后端代码到服务器上的时候都要去修改配置。
使用 .env 文件编写不同环境的配置文件,然后在启动项目的指令中携带上对应文件中的环境变量,即可方便地省去频繁修改配置文件的麻烦。
需求
- 实现动态加载配置文件
- 在项目中可以方便地调用配置文件中的变量
实现
Electron
前端使用的框架是 Electron-Vite,文档中有环境变量配置的说明,如下:
环境变量和模式 | electron-vite
第一步
在前端项目的根目录(与package.json文件在同一目录)新建配置文件:.env.development 和 .env.production (分别代表 开发环境 和 生产环境),前面的 .env. 是固定的,后面的名字可以自定。
第二步
在配置文件中写入键值对式的配置。在development中写入开发环境中你用到的变量,在production文件中写入生产环境你用到的变量。
当然,你还可以创建更多的env文件用来存放更多场景需要用到的变量
注意:键值对中,键名前缀一定要加,具体规则如下:
默认情况下,以MAIN_VITE_
为前缀的变量暴露给主进程,PRELOAD_VITE_
用于预加载脚本,RENDERER_VITE_
则用于渲染器,VITE_
则所有进程共用。我这里图方便就直接用 VITE_ 作为前缀了,实际上我这些变量都只在渲染进程中使用,应该用 RENDERER_VITE_ 更规范
第三步
在项目中调用变量
const testConfig = import.meta.env.VITE_TEST
通过 import.meta.env 对象即可访问到配置文件中的变量,不需要进行导入和其它操作,直接用。
第四步
修改 package.json 中的启动命令,以方便在对应的环境中携带对应的配置文件
"scripts": {
"format": "prettier --write .",
"lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix",
"start": "electron-vite preview",
"dev": "electron-vite dev --watch --mode=development",
"build": "electron-vite build --mode=production",
"postinstall": "electron-builder install-app-deps",
"build:unpack": "npm run build && electron-builder --mode=production --config=electron-builder.config.js --dir",
"build:win": "npm run build && electron-builder --mode=production --config=electron-builder.config.js --win",
"build:mac": "npm run build && electron-builder --mode=production --config=electron-builder.config.js --mac",
"build:linux": "npm run build && electron-builder --mode=production --config=electron-builder.config.js --linux"
}
- 开发环境中,我使用 npm run dev 来启动项目,在对应指令后添加 --mode=development 可以让其在执行时携带 .env.development 文件中的配置
- 打包后的文件用于生产环境,故在 build 指令后添加 --mode=production 可以让打包后的程序中使用 .env.production 文件中的配置
第五步
.env 文件中通常存放了一些敏感数据,比如数据库密码,服务器ip等,我们在向仓库中推送时是不需要将这些配置文件一并上传的
所以你还需要在 .gitignore 中将 .env 文件包括在内
node_modules
dist
out
.DS_Store
*.log*
.vscode
.env*
Node
Node 原生是无法较好地实现 env 变量的携带的,我们需要用到两个插件
第一步
安装插件
npm install cross-env
npm install dotenv
第二步
编写配置文件 .env.development 和 .env.production
PROTOCOL=http
IP=127.0.0.1
PORT=8080
DB_HOST=127.0.0.1
DB_PORT=27017
DB_NAME=FChat
第三步
在入口程序中使用 dotenv 插件动态载入配置文件
// 加载环境变量
require('dotenv').config({ path: `.env.${process.env.NODE_ENV || 'development'}`})
这里通过 process.env.NODE_ENV 这个变量来动态引入了对应的配置文件,不过这个变量我们是没有的,需要在启动node项目的时候将这个变量传入。
第四步
修改package.json文件,在启动项目时提供 NODE_ENV 变量
"scripts": {
"start": "cross-env NODE_ENV=development nodemon app.js",
"serve": "cross-env NODE_ENV=production node app.js"
}
这里使用了 cross-env 这个插件来传入参数
之前我用 set NODE_ENV=development && nodemon app.js 来启动项目,试图通过这种方式来传参。理论上应该是能行的,不过到项目里面去调用的时候,访问 process.env 对象,里面只有默认提供的一些环境变量,和我传入的 NODE_ENV ,没有配置文件中的变量。
直接使用nodemon app.js作为指令而不传入 NODE_ENV 时,虽然能通过dotenv加载配置文件中的变量,不过只能手动指定去加载哪一个文件。所以最后还是又另加了cross-env这个插件来在脚本中插入NODE_ENV变量
第五步
在项目中调用环境参数
const test = process.env.TEST
process 模块不需要进行导入即可使用
后记
electron里面配这个还挺方便的,node里面倒是费了我好长时间,一直获取不到文件里面的变量。
后来了解到Node在新版本中已经开始尝试去支持原生的env环境参数载入了,类似这样:
node --env-file=config.env index.js。
感兴趣可以去了解一下