Nuxt3 正式发布还不到半年,在投入生产环境使用后,遇到了不少问题,很难找到合适的解决方案,其中环境变量配置就是其中一个,之前一直未能解决,最近要上持续集成,无法绕过这个问题,所以花了点时间研究了一下,最终找到了解决方案,记录一下。

官方文档

面对一个新框架,我们自然是希望官方文档能够详细地说明使用方式,最初开始使用的时候,并没有关于环境变量配置的说明,甚至可能没有相关功能,不过随着版本的更新,文档中添加了相关的内容,但是安装文档的说明进行配置后并没有生效,后来发现有些是理解偏差,另外还有一些问题我仍然没有解决,不过目前的配置方式已经满足我们的需求,所以这里记录一下研究配置的过程。

关于配置的官网文档: Runtime Config

用于持续集成的命令: nuxi build

环境变量文件的说明: .env

配置文件说明: Nuxt Config

基础变量配置

最开始我按照官方文档的说明将环境变量配置在了 nuxt.config.ts 文件中,使用起来还是很简单的。

// nuxt.config.ts
runtimeConfig: {
apiKey: ""; // Default to an empty string, automatically set at runtime using process.env.NUXT_API_KEY
public: {
baseURL: ""; // Exposed to the frontend as well.
}
} // 使用
const config = useRuntimeConfig();
const baseUrl = config.public.baseUrl;

需要暴露在前端的变量写在 public 中,不需要暴露的直接写在 runtimeConfig 下,调用也很方便,但是作为环境变量,仅满足一种环境肯定是不行的,最初我是通过 process.env.NODE_ENV 来判断当前环境,然后根据环境来配置不同的变量,然而上线之后遇到了一个问题,测试环境和正式环境的 NODE_ENV 都是 production ,这样就导致了无法区分环境,所以在很长一段时间内,我都是通过手动修改 nuxt.config.ts 文件来切换环境,这样的方式肯定是不行的,所以我开始寻找解决方案。

.env 文件配置

参考 Vue Cli 项目,每次执行 run build 的时候,自动读取对应的 .env 文件中的变量进行编译,这样就是我的理想情况,而且我发现官方的文档中后来确实新增了相关的内容,我就想当然地进行了配置,结果却没有生效。

"scripts": {
"build": "nuxi build --dotenv .env.production",
"test": "nuxi build --dotenv .env.test",
"dev": "nuxi dev --dotenv .env.development -p 3001",
"generate": "nuxi generate",
"preview": "nuxi preview",
"start": "node .output/server/index.mjs"
},

在这里提前说明一下,这个其实就是最终的解决方案,这种写法现在可以生效,早期版本的时候并不支持。

最开始因为文档不完善,使用的人也不多,我只能在官方 GitHub 的 Issues 中寻找有没有类似的问题,因为毕竟是个很常见的需求,当时找到了一些和我有同样困惑的例子。

--dotenv config doesn’t work in production environment

Deployment Nuxt Application on Linux KO

按照作者的回答,我的理解是 .env 文件并不能在 build 环境生效,这一功能是针对 devpreview的,经过我的测试,dev 环境确实没有问题。

根据这两个 issue,我推论环境变量要在启动项目时添加环境变量,于是我根据文档配置 pm2,使用 source .env && node .output/server/index.mjs 启动,结果仍然无法读取环境变量。

pm2 配置

这里稍微跑个题,虽然没能通过 pm2 成功配置环境变量,但是看到了 pm2 的环境变量配置相关的一些文档,顺便对项目中的配置进行了一些优化。

module.exports = {
apps: [
{
name: "xxx",
exec_mode: "cluster",
instances: "max", // Or a number of instances
script: "npm",
args: "start",
error: "/root/.pm2/logs/xxx-error.log", // 放在系统盘下面-错误日志路径如果不想使用日志 "/root/null"
output: "/root/.pm2/logs/xxx-out.log", // 放在系统盘下面-正常日志路径如果不想使用日志 "/root/null"
combine_logs: false,
merge_logs: false,
log_date_format: "YYYY-MM-DD HH:mm Z", // 指定日志文件的时间格式
env: {
NODE_ENV: "production",
PORT: 3001,
FRONTEND_VERSION: "v1.0.0",
FRONTEND_CLIENTID: "xxx",
},
env_production: {
NODE_ENV: "development",
PORT: 3000,
FRONTEND_VERSION: "v1.0.0",
FRONTEND_CLIENTID: "xxx",
},
},
],
};

环境变量

一开始我以为 pm2 配置中的 env 是项目中环境变量,设置值之后测试仍然没有效果,仔细查看文档后发现 env 中的字段是固定的,主要是用于启动进程的配置,可以配置不同环境的启动端口和 node 的环境值等。详情可以看文档 环境变量

日志

pm2 的日志默认是合在一起的,时间久或者访问量大的情况下,日志会非常大,不方便查看,我们可以将日志分开,这样会更方便通过日志查看项目的启动情况。

  1. 安装 pm2-logrotate
$ pm2 install pm2-logrotate
  1. 配置 pm2-logrotate
// 设置日志文件的最大大小,超过这个大小就会进行分割
pm2 set pm2-logrotate:max_size 4M
// 设置压缩日志文件
pm2 set pm2-logrotate:compress true

通过各种配置可以把日志调整到满足我们需求的形式,详情可以看文档 pm2-logrotate

正确的配置

多次尝试以失败告终之后,我暂时搁置了环境变量的配置问题,但是最近要做持续集成,肯定要通过指令而不是人为修改来完成,所以我又针对环境变量配置进行了测试,最终找到了正确的配置方式。

正如上面 .env 文件配置 一节所说,最终的解决方案就是在 package.json 中配置 run build 的时候指定 .env 文件,这样就可以在编译的时候读取对应的环境变量。不确定是不是最近 nuxt 的版本更新了,这个功能才生效,还是说之前的版本我没有配置正确,总之现在是可以用了。

完整的配置如下:

// package.json
"scripts": {
"build": "nuxi build --dotenv .env.production",
"test": "nuxi build --dotenv .env.test",
"dev": "nuxi dev --dotenv .env.development -p 3001",
"generate": "nuxi generate",
"preview": "nuxi preview",
"start": "node .output/server/index.mjs"
},
// .env.production
NUXT_API_KEY=https://xxx
NUXT_PUBLIC_BASE_URL=https://xxx
// nuxt.config.ts
runtimeConfig: {
apiKey: process.env.NUXT_API_KEY; // Default to an empty string, automatically set at runtime using process.env.NUXT_API_KEY
public: {
baseURL: process.env.NUXT_PUBLIC_BASE_URL; // Exposed to the frontend as well.
}
} // 使用
const config = useRuntimeConfig();
const baseUrl = config.public.baseUrl;

但是,问题并没有完全解决,还存在一个问题和一个疑点。

先说问题,Nuxt 的环境变量是在服务端运行的,在客户端并不能获取到环境变量,我这里主要是用于判断环境使用不同的 key 值,process.env.NUXT_PUBLIC_PAGE_WWW 前面还是 process.env,我的理解是这个值的获取是基于 node 的,客户端无法正确读取,所以我在 .env 文件中增加了一个新的变量 VITE_NUXT_ENV=test 用于判断环境,这样就可以在客户端通过 import.meta.env.VITE_NUXT_ENV 获取到环境变量。

感觉上这样的思路存在一些问题,如果有更好的解决方案,欢迎指教或讨论。

而疑点就在注释里,前面应该也有人注意到,官网文档的注释里写到:

Default to an empty string, automatically set at runtime using process.env.NUXT_API_KEY

意思应该是如果在 runtimeConfig 设置了环境变量,也会自动添加到对应的 process.env 变量中,但是经过我的测试,这个功能并没有生效,不知道是不是哪里有错,如果有人知道,希望能告诉我。

总结

新框架总是有很多坑,在开发过程中我遇到了很多问题,但是都一一解决了,虽然过程很痛苦,但是收获也很大,希望这篇文章能帮助到和我遇到同样问题的人,也为自己做一个记录。

Nuxt3环境变量配置的更多相关文章

  1. 1.JAVA基础复习——计算机基础与环境变量配置

    软件开发的了解 软件开发: 软件:一系列按照特定组织的计算机数据和指令的集合. 开发:制作软件. 程序:一系列有序指令的集合. 人机交互 人机交互的方式有两种:图形化界面和命令行方式. 图形化界面:简 ...

  2. java环境变量配置

    1.打开我的电脑--属性--高级--环境变量 2.新建系统变量JAVA_HOME 和CLASSPATH 变量名:JAVA_HOME 变量值:C:\Program Files\Java\jdk1.7.0 ...

  3. Ant环境变量配置

    Ant环境变量配置 1.新建系统变量ANT_HOME    变量名: ANT_HOME    变量值: D:\biancheng\apache-ant-1.7.1 2.修改PATH    变量值最后面 ...

  4. java、Android SDK、adb环境变量配置,以及JDK1.7换JDK1.8

    最近因项目需要使用将JDK1.7换成JDK1.8,故重新清晰地记录各种环境变量的配置: 这里更改的均是系统变量,不是用户变量 java环境变量配置: 变量名               变量值JAVA ...

  5. ROS学习笔记(四)——环境变量配置

    1.查看环境变量配置情况,其实并没有什么卵用 $ export | grep ROS 或者用 $ printenv | grep ROS2.配置环境变量??$ source /opt/ros/indi ...

  6. java和android的环境变量配置

    Java环境变量配置: 1.新建系统变量 变量名:JAVA_HOME  变量值:F:\JAVA\JDK(自己的JDK文件路径) 2.在系统变量path后面添加:%JAVA_HOME%\bin; And ...

  7. jdk安装和环境变量配置

    jdk的安装和环境变量配置每次换新环境都在做,但是每次都没有认真去想是怎么做的,反正每次打开百度搜索照做就是.这次整理一下,也顺便理清一下其中的原理. 1.第一步当然就是下载jdk,我这边下载的是jd ...

  8. JDK和tomcat环境变量配置

    JDK环境变量配置:   如果你的JDK安装在C盘里,如:C:\Program Files\Java\jdk1.6.0_05, 那么就在系统变量里(当然也可以在用户变量里)点新建: 变量名:JAVA_ ...

  9. Android开发环境变量配置总结

    每次重装系统或者拿到一台新电脑都得重配Android的环境变量,每次都得上网查,索性就记在这儿吧. “系统属性->高级系统设置->环境变量” 打开环境变量配置窗口. JDK配置: 新建JA ...

  10. Java配置----JDK开发环境搭建及环境变量配置

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

随机推荐

  1. 将 Sql Server 表信息 C# 对象化 小工具_ 张光荣 的 正能量

    注: a.此程序所得到的结果是根据本人个人习惯生成,所以,肯定不完全适合所有人使用,重在想法...然后个人根据个人需求作出更进...b.程序中可能会出现数据库连接的错误提示[原因概是在sql 连接过程 ...

  2. 第三章 excel的表合并

    本章内容比较简略,基于行或列进行统计运算 具体操作为:选中某一空白单元格,单击数据--数据工具--合并计算(依据需求选择数据与计算方式)

  3. Windows右键新建菜单中添加md文件

    1.win+r------->regedit 2.找到.md文件夹,双击该文件夹后修改数据的值为".md" 3.在.md文件夹右键新建"项"------& ...

  4. Ubantu12.04安装及离线安装网卡驱动

    一.用软通牒UltarISO写入硬盘映像,制作启动U盘 装机,ubantu安装很简单. 二.安装网卡驱动 1. 下载e1000e:https://downloadcenter.intel.com/De ...

  5. 后端006_登录之后返回Token

    现在开始我们就可以写登录相关的东西了.首先登录相关的流程是这样的,前端输入用户和密码传给后端,后端判断用户名和密码是否正确,若正确,则生成JWT令牌,若不正确,则需要让前端重新输入,前端如果拿到了JW ...

  6. Spring源码分析之注册BeanDefinition

    测试代码 public class ContextApplication { public static void main(String[] args) { ClassPathXmlApplicat ...

  7. Navicat基础教程

    1.安装 可以直接前往官网进行安装,网址如下: https://navicat.com.cn/download/navicat-premium 下载之后将下载后的压缩包解压到当前文件夹,然后根据里面自 ...

  8. Java笔记第三弹

    Map集合的获取功能 V get(Object key);//根据键获取值 Set<K> keySet();//获取所有键的集合 Collection<K> values(); ...

  9. Apk_动态调试方案

    环境准备 安装夜神安卓模拟器 配置好adb[Android 调试桥]环境(这里需要使用官方的adb环境,设置好环境变量)Android 调试桥 (adb) | Android 开发者 | Androi ...

  10. 关于EasyExcel的数据导入和单sheet和多sheet导出

    读写Excel基本代码 直接复制不一定能用 实体类 @ExcelIgnore 在导出操作中不会被导出 @ExcelProperty 在导入过程中 可以根据导入模板自动匹配字段, 在导出过程中可用于设置 ...