gpt4 book ai didi

reactjs - 为什么 .env.development 不能在我的 Next.js 应用程序中运行?

转载 作者:行者123 更新时间:2023-12-05 03:26:11 25 4
gpt4 key购买 nike

<分区>

我正在编写 Jest/测试库测试。

假设我们有一个名为 BenchmarksPage 的组件。

请看它的返回语句的第一行。

import {
Box,
capitalize,
Container,
FormControl,
InputLabel,
MenuItem,
Select,
} from '@material-ui/core';
import { NextPage } from 'next';
import React, { useCallback, useEffect, useState } from 'react';
import { Helmet } from 'react-helmet-async';
import RequireScope from 'src/components/authentication/RequireScope';
import BenchmarkTable from 'src/components/benchmark/BenchmarkTable';
import DashboardLayout from 'src/components/dashboard/DashboardLayout';
import Heading from 'src/components/Heading';
import useSettings from 'src/hooks/useSettings';
import gtm from 'src/lib/gtm';
import { useDispatch, useSelector } from 'src/store';
import { getAllRollingTwelveCalcs } from 'src/store/rolling-twelve/rolling-twelve.thunk';
import { Timeframe, timeframeMap } from 'src/types/benchmark';

const BenchmarksPage: NextPage = () => {
const { settings } = useSettings();
const dispatch = useDispatch();

const [selectedTimeframe, setSelectedTimeframe] = useState<Timeframe>(
Timeframe.Monthly,
);

const company = useSelector((state) => state.company.current);

useEffect(() => {
gtm.push({ event: 'page_view' });
}, []);

useEffect(() => {
dispatch(getAllRollingTwelveCalcs());
}, [company]);

const handleTimeframeChange = useCallback(
(
event: React.ChangeEvent<{
name?: string;
value: Timeframe;
event: Event | React.SyntheticEvent<Element, Event>;
}>,
) => {
setSelectedTimeframe(event.target.value);
},
[],
);

return (
<RequireScope scopes={['query:benchmark-calcs']}>
<DashboardLayout>
<Helmet>
<title>Benchmarks</title>
</Helmet>
<Container maxWidth={settings.compact ? 'xl' : false}>
<Box
sx={{
display: 'flex',
alignItems: 'flex-end',
justifyContent: 'space-between',
mb: 4,
}}
>
<Heading>Benchmarks</Heading>
<FormControl sx={{ width: 300 }}>
<InputLabel>Timeframe</InputLabel>
<Select
sx={{ background: '#ffffff', maxWidth: 400 }}
value={selectedTimeframe}
label="Timeframe"
onChange={handleTimeframeChange}
>
{[...timeframeMap.keys()].map((timeframe) => (
<MenuItem key={timeframe} value={timeframe}>
{capitalize(timeframe)}
</MenuItem>
))}
</Select>
</FormControl>
</Box>
<BenchmarkTable timeframe={selectedTimeframe} />
</Container>
</DashboardLayout>
</RequireScope>
);
};

export default BenchmarksPage;

注意它的返回值是用RequireScope包裹的

RequireScope 只会在用户通过身份验证时呈现其子项

RequireScope:

import React, { useEffect, useState } from 'react';
import useAuth from 'src/hooks/useAuth';

export interface RequireScopeProps {
scopes: string[];
}

const RequireScope: React.FC<RequireScopeProps> = React.memo((props) => {
const { children, scopes } = props;
const { isInitialized, isAuthenticated, permissions } = useAuth();
const [isPermitted, setIsPermitted] = useState(false);

useEffect(() => {
if (process.env.NEXT_PUBLIC_IS_LOCAL) {
setIsPermitted(true);
}
}, []);

useEffect(() => {
if (isAuthenticated && isInitialized) {
(async () => {
const hasPermissions = scopes
.map((s) => {
return permissions.includes(s);
})
.filter(Boolean);

if (hasPermissions.length === scopes.length) {
setIsPermitted(true);
}
})();
}
}, [isAuthenticated, isInitialized, scopes, permissions]);

if (isPermitted) {
return <>{children}</>;
}

return null;
});

export default RequireScope;

我们只需要将isPermitted设置为true

(顺便说一句,useAuth 使用 JWT 登录用户)

现在,当我使用测试库的 render 方法呈现 BenchmarksPage 时,

它不会在 jsdom 上呈现,因为

'isPermitted'RequireScope 中仍然是 false。

所以,为了让isPermitted = true

我已经设置了

NEXT_PUBLIC_IS_LOCAL=true

.env.development

根据 RequireScope 中的第一个 useEffectisPermitted 现在应该是 true

然而,组件仍然没有渲染,返回

<body></div></body> 

这仍然意味着 isPermitted 为假。

我尝试了什么:

我也尝试过使用 .env.local

我可以向您保证我的设置都是正确的(jest.config,使用 MockProvider 包装 BenchmarksPage 等)

为什么 .env.development 不工作,并使 isPermitted = true

根据我的理解,一切在逻辑上都是正确的。

编辑:我试过写

NEXT_PUBLIC_IS_LOCAL=true

也在 .env.test 文件中

编辑 - 回答:

必须设置

import { loadEnvConfig } from '@next/env';

export default async (): Promise<void> => {
loadEnvConfig(process.env.PWD);
};

在 setupEnv.ts 文件中。

然后在 package.json 中添加 globalSetup(因为我不使用 jest.config.js -> eslint 与 tsconfig 一起搞乱了它)

"jest": {
"moduleNameMapper": {
"^src/(.*)$": "<rootDir>/src/$1"
},
"testEnvironment": "jsdom",
"globalSetup": "<rootDir>/test/setupEnv.ts"
},

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com