上下文:使用 React/Typescript/Vite/Yarn
我有一个项目,我在 .env 文件中定义后端 URL,以在整个项目中用作常量。然而,它并没有得到高层的认可,我不知道为什么。我的前端在端口 3036 上运行,后端在端口 8080 上运行,但无论我做什么,前端都会向 localhost:3036 发出请求。
例如,我有这样的 .env 文件(位于根目录中):
NODE_ENV=development
VITE_BACKEND_URL=http://localhost:8080
我最初将其设置为 BACKEND_URL,但通过故障排除,我发现解决方案是在其前面加上 VITE 前缀。这并没有解决问题。
我还按照文档中的说明进行操作,并将其放入我的 vite.config.ts 文件中:
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ command, mode }) => {
// Load env file based on `mode` in the current working directory.
// Set the third parameter to '' to load all env regardless of the `VITE_` prefix.
const env = loadEnv(mode, process.cwd(), '')
return {
// vite config
define: {
VITE_BACKEND_URL: JSON.stringify(env.VITE_BACKEND_URL),
},
}
})
然而,这也不起作用。
这是我加载它的地方:
const {
NODE_ENV,
VITE_BACKEND_URL,
} = process.env;
console.log('BACKEND_URL from process.env:', VITE_BACKEND_URL)
const env = {
NODE_ENV: NODE_ENV || 'development',
BACKEND_URL: VITE_BACKEND_URL,
};
export type ProjectEnv = typeof env;
export default () => ({
data: env,
});
我在故障排除中看到,也许我需要使用
import.meta.env.VITE_BACKEND_URL
,但当我这样做时,它说
import.meta.env
未定义,我不知道为什么,与 process.env 相同,它给了我BACKEND_URL from process.env: undefined
对于上下文,以下是我如何使用后端 url 发出请求:
export const baseClient = (
accessToken?: string | null,
baseURL: string = '',
): AxiosInstance => {
const headers: Record<string, string> = {};
if (accessToken) {
headers.Authorization = `Bearer ${accessToken}`;
}
return axios.create({
// When BACKEND_URL is set, always use it.
baseURL: isURL(BuildConfig.BACKEND_URL) ? BuildConfig.BACKEND_URL : baseURL,
headers,
transformResponse: [maybeParseJSON],
});
};
export default (getState: () => RootState, authType: string = 'user'): AxiosInstance => {
const state = getState();
const accessToken = getToken(state, authType);
const me = state.me;
const baseURL = me ? getAuthBaseURL(state, me) : '';
return baseClient(accessToken, baseURL);
};
当我运行这个时:
NODE_ENV="development" BACKEND_URL="http://localhost:8080" yarn build
NODE_ENV="development" BACKEND_URL="http://localhost:8080" yarn dev
它按预期工作(减去一些我尚未处理的 CORS 问题),但看起来它正确使用了
BACKEND_URL
,所以我认为它在最顶层出现了问题,其中 .env vite 正在加载文件。
另外,当我echo $VITE_BACKEND_URL
时,它也会输出我所期望的内容,但只有在我运行
source .env
之后。我在这里有点不知所措,任何帮助将不胜感激。
假设您有一个环境文件:
VITE_BACKEND_URL=http://localhost:8080
您可以加载此在配置中使用环境变量全局常量替换
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ command, mode }) => {
// Load env file based on `mode` in the current working directory.
// Set the third parameter to '' to load all env regardless of the `VITE_` prefix.
const env = loadEnv(mode, process.cwd(), '')
return {
// vite config
define: {
__VITE_BACKEND_URL__: JSON.stringify(env.VITE_BACKEND_URL),
},
}
})
根据文档,如果您使用 TypeScript,则需要声明全局常量
// vite-env.d.ts
declare const __VITE_BACKEND_URL__: string
process.env
不同的方法。如果已设置环境变量,您也可以通过
访问环境变量。process.env
当你做这样的事情时:NODE_ENV="development" BACKEND_URL="http://localhost:8080" yarn dev
您可以通过
process.env
提供环境变量,但这与使用 vite 声明全局常量不同。
你的代码做了什么(我怀疑)
// destructure process.env and shadow the global variables defined by vite
const {
NODE_ENV,
VITE_BACKEND_URL,
} = process.env;
// Where loadEnv was used, and environment variables not explitily set, this will be undefined
console.log('BACKEND_URL from process.env:', VITE_BACKEND_URL)
// everything below will just use what was set above
const env = {
NODE_ENV: NODE_ENV || 'development',
BACKEND_URL: VITE_BACKEND_URL,
};
export type ProjectEnv = typeof env;
export default () => ({
data: env,
});
相反,您可以简单地使用全局环境变量
console.log('BACKEND_URL from process.env:', __VITE_BACKEND_URL__)
为了避免混淆,在定义全局变量时使用双下划线约定。
如果您想使用
process.env
那么您需要一些方法来确保
.env
中的变量在流程环境中设置。使用
import.meta
是另一种方法,但我必须再次查看它以提醒自己细节,而且我认为它无法解释当前设置中发生的情况。