问题描述
在nuxt3项目开发过程中,设置了开发环境变量和生产环境变量,在本地开发时都能正常获取,但打包部署时获取不到,设置如下:
//.env.development文件示例
SERVER_API_PATH='http://192.168.xxx.xxx'
//.env.production文件示例
SERVER_API_PATH='https://api.xxxxxx.com'
在开发时获取自定义的环境变量还需要在package.json文件中加上如下配置:
{
"scripts": {
"build": "nuxt build --dotenv .env.production",
"dev": "nuxt dev --dotenv .env.development",
},
}
当前使用版本为:
"nuxt": "^3.12.2",
"node":"20.12.2",
"vue": "^3.4.29"
比如当需要发送登录请求时,在server文件夹下的api文件可以通过process.env.SERVER_API_PATH 获取:
而在打包后用同等方法获取却没有值,值显示为undefined,通过打印process.env的值可以看出,没有任何自定义的环境变量。
解决方法一
- 将.env.production复制到打包后的.output的server文件夹下,与index.mjs同级;
- 在index.mjs中添加代码;
import path from 'node:path'
process.loadEnvFile(path.resolve(process.cwd(), '.env.production'));
- 重新启动项目。
node .output/server/index.mjs
添加后的index.mjs文件
import process from 'node:process';
globalThis._importMeta_={url:import.meta.url,env:process.env};
import 'node:http';
import 'node:https';
export { L as default } from './chunks/runtime.mjs';
import 'fs';
import 'path';
import 'node:fs';
import 'node:url';
//# sourceMappingURL=index.mjs.map
/*以上为index.mjs原文*/
//这是添加的代码
import path from 'node:path'
process.loadEnvFile(path.resolve(process.cwd(), '.env.production'));
如图所示:
需要注意的是:
使用process.loadEnvFile()方法需要node版本≥20.12.0才能支持,低于此版本可以单独安装dotenv插件去设置获取。
npm i dotenv
解决方法二
在打包后的.output文件夹下的server文件夹下找到index.mjs文件,自行设置环境变量(不用复制.env文件),将.env.production设置的变量在这里全部设置一遍,例如:
import process from 'node:process';
globalThis._importMeta_={url:import.meta.url,env:process.env};
import 'node:http';
import 'node:https';
export { M as default } from './chunks/runtime.mjs';
import 'fs';
import 'path';
import 'node:fs';
import 'node:url';
//# sourceMappingURL=index.mjs.map
process.env.APP_TOKENS="cHJvY2Vzcy5lbnYuU0VSVkVSX0FQSV9QQVRIPSJodHRwczovL2FwaS54eHh4eHguY29tL2FwaSI="
process.env.SERVER_API_PATH="https://api.xxxxxx.com/api"
console.log(process.env)
重启项目后通过输出可以看到,获取自定义环境变量成功。
解决方法三(推荐)
1. 不需要.env文件,直接在runtimeConfig中配置。
1.1 在nuxt.config.ts文件中增加runtimeConfig配置,关于runtimeConfig的详细配置可参阅官网;
export default defineNuxtConfig({
runtimeConfig: {
// 只在服务器端可用的私有键,例如
apiUrl: "https://api.xxxxxx.com",
// public中的键也可以在客户端使用
// public: {
// apiBase: '/api'
// }
},
})
1.2 在需要用到的地方添加如下代码,例如登录:
|--server
|--api
|--login.post.js
login.post.js代码:
//登录
export default defineEventHandler(async (e) => {
const body = await readBody(e);
const { apiUrl }= useRuntimeConfig();
try {
let data = await $fetch(`${apiUrl}/user/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (data) {
return data;
} else {
return {
errno: 1,
msg: "登录失败~",
};
}
} catch (err) {
throw createError({
statusCode: 500,
message: err.message || "服务器繁忙,请稍后再试~",
});
}
});
1.3 如果配置的某个变量需要区分开发环境与生产环境用不同的值,可以这么配置:
export default defineNuxtConfig({
runtimeConfig: {
apiUrl:
import.meta.env.NODE_ENV === "development"
? "http://192.168.xxx.xxx"
: "https://api.xxxxxx.com",
},
})
2. 保留.env文件的情况。
export default defineNuxtConfig({
runtimeConfig: {
// 例如
apiUrl: process.env.SERVER_API_PATH,
}
})