首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Next.js没有将页面构建为SSG,当它应该

Next.js没有将页面构建为SSG,当它应该
EN

Stack Overflow用户
提问于 2021-04-29 09:54:50
回答 2查看 3.9K关注 0票数 9

我试图理解为什么Next.js将我的一些页面构建为SSG,而有些则是静态的,而这些页面都在使用getStaticProps。

让我们以我的404页为例,它使用getStaticProps使用graphql从棱镜中获取数据。在我看来,它是作为一个静态网站呈现为SSG (因为它使用getStaticProps)。

我在我的500页中做了完全相同的事情,但是使用了不同的graphql查询,并且它被呈现为SSG (在我看来是正确的)。

为什么会这样呢?

404页:

代码语言:javascript
复制
const NotFound = ({ data: { page } }) => {
    return (
        <div className={'not-found'}>
            <p className={'not-found__description'}>{RichText.asText(page.description)}</p>
        </div>
    );
};

export const getStaticProps = async (context) => {
    const currentLanguage = getCurrentLocale(context);

    const response = await apolloClient.query({
        query: gql`
            query {
            }
        `
    };

    return {
        props: {
            data: {
                page: response
            }
        }
    }
});

export default NotFound;

500页:

代码语言:javascript
复制
const InternalServerError = ({ data: { page } }) => {
    return (
        <div className={'internal-server-error'}>
             <p className={'internal-server-error__description'}>{RichText.asText(page.description)}</p>
        </div>
    );
};

export const getStaticProps = async (context) => {
    const currentLanguage = getCurrentLocale(context);
    
    const response = await apolloClient.query({
        query: gql`
            query {
            }
        `
    });
    
    return {
        props: {
            data: {
                page: response
            }
        }
    }
};

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-07 04:11:49

Next.js中的404.tsx或404.js页面是唯一的,因为它不依赖服务器,并且始终是静态的--在构建时完全依赖静态html (没有json) --即使在文件中使用GetStaticProps时也是如此。

404页只是一个捕获所有funnel路由,当用户导航到站点作为基本URL时不存在的路径时,用户将被重定向到该路由。因此,它不依赖于初始构建的服务器。这是不存在的路径的退路,而不是其他的。另一方面,500页处理应用程序中的内部错误,因此它确实依赖于.html.json文件类型来确定错误的性质。

有趣的是,如果您在本地检查.next目录的内容,您将注意到使用GetStaticProps的所有页面都具有静态生成的.json.html文件。使用GetStaticPropsrevalidate的页面返回=== Incremental Static RegenerationISRISRSSGSSR的理想混合体,具有扫描生产中传入的更改/更新的后台函数(您指定的数字是在可能的更新之间以秒为单位的时间量)。因此,使用GetStaticProps + ISR的页面在.next目录中生成三种文件类型-- .html.json.js。也就是说,使用GetServerSidePropsGetInitialProps的页面只在.next目录中生成.js文件。最后,没有使用上述任何方法的纯Static页面只生成.html文件。

404页及其静态特性的思想是通过加快自定义oops! that path doesn't exist页面的呈现(或更准确地说是预录制)来增强UX,以便用户能够尽快返回到实际应用程序。

例如,我的404.tsx页面中有以下内容,但在构建时它仍然呈现为静态html

代码语言:javascript
复制
import { Container } from '@/components/UI';
import { initializeApollo, addApolloState } from '@/lib/apollo';
import { NotFound } from '@/components/NotFound';
import { AppLayout } from '@/components/Layout';
import {
    GetStaticPropsContext,
    GetStaticPropsResult,
    InferGetStaticPropsType
} from 'next';
import {
    NotFoundQuery,
    NotFoundDocument,
    NotFoundQueryVariables,
    DynamicNavQuery,
    DynamicNavDocument,
    DynamicNavQueryVariables,
    WordpressMenuNodeIdTypeEnum,
    WordpressMediaItemSizeEnum,
    WordpressPageIdType
} from '@/graphql/generated/graphql';

export function SOS({
    notFound,
    Header,
    Footer
}: InferGetStaticPropsType<typeof getStaticProps>) {
    return (
        <>
            <AppLayout title={'✂ 404 ✂'} Header={Header} Footer={Footer}>
                <Container clean className='fit'>
                    <NotFound notFound={notFound} />
                </Container>
            </AppLayout>
        </>
    );
}

export async function getStaticProps(
    ctx: GetStaticPropsContext
): Promise<
    GetStaticPropsResult<{
        notFound: NotFoundQuery['NotFound'];
        Header: DynamicNavQuery['Header'];
        Footer: DynamicNavQuery['Footer'];
    }>
> {
    const params = ctx.params!;
    console.log(params ?? '');
    const apolloClient = initializeApollo();
    await apolloClient.query<
        DynamicNavQuery,
        DynamicNavQueryVariables
    >({
        query: DynamicNavDocument,
        variables: {
            idHead: 'Header',
            idTypeHead: WordpressMenuNodeIdTypeEnum.NAME,
            idTypeFoot: WordpressMenuNodeIdTypeEnum.NAME,
            idFoot: 'Footer'
        }
    });

    await apolloClient.query<NotFoundQuery, NotFoundQueryVariables>(
        {
            query: NotFoundDocument,
            variables: {
                id: '/404-not-found/' as '/404/',
                idType: WordpressPageIdType.URI,
                size: WordpressMediaItemSizeEnum.LARGE
            }
        }
    );
    return addApolloState(apolloClient, {
        props: {},
        revalidate: 60
    });
}
export default SOS;

有趣的是,由于在我的GetStaticProps页面中使用了ISRrevalidate,所以.next目录的内容反映了这一点,因为404 (.js, .json, .html)提供了所有三种文件类型。如果您在自定义的getInitialProps_app.js文件中使用_app.js,那么整个应用程序都将禁用自动静态优化(静态页面预录制)。尝试一下,如果您好奇的话,它应该会导致404页面在构建日志中的旁边有一个lambda。但是,由于您已经拥有了GetStaticProps,它应该覆盖您的根app页面使用GetInitialProps导致的应用程序范围的静态去优化。

例如,在创建自定义的GetInitialProps页面之前,我在_app.tsx中使用了404.tsx。我决定拉建日志,并采取了一个伴随的屏幕快照。

代码语言:javascript
复制
Warning: You have opted-out of Automatic Static Optimization due to `getInitialProps` in `pages/_app`. This does not opt-out pages with `getStaticProps`.

票数 4
EN

Stack Overflow用户

发布于 2021-05-06 21:41:23

您的代码中的404页缺少括号吗?

代码语言:javascript
复制
const response = await apolloClient.query({
    query: gql`
        query {
        }
    `
};

应该是

代码语言:javascript
复制
const response = await apolloClient.query({
    query: gql`
        query {
        }
    `
});
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67315057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档