😂 好久前写了关于
getStaticProps
和getStaticPaths
的内容,然而半年过去了源码解析就一直忘记了,不久前有人提醒才想起来,补下坑。
本文主要是解读下 getStaticProps
、getStaticPaths
相关的源码,不了解这两个 API
的建议先看下之前的文章再看。👀
getStaticProps
首先 getStaticProps
是应用于 SSG
场景,我们先看下 packages/next/server/render.tsx
中相关的代码:
const isSSG = !!getStaticProps;
const pageIsDynamic = isDynamicRoute(pathname);
if (isSSG && !isFallback) {
let data: UnwrapPromise<ReturnType<GetStaticProps>>;
try {
data = await getStaticProps!({
...(pageIsDynamic ? {
params: query as ParsedUrlQuery } : undefined),
...(isPreview ? {
preview: true, previewData: previewData } : undefined),
locales: renderOpts.locales,
locale: renderOpts.locale,
defaultLocale: renderOpts.defaultLocale
});
} catch (staticPropsError: any) {
// ....
}
// ...
}
isFallback
可以先不管。可以看到 getStaticProps
同样可以为异步函数,而是否为 SSG
就是由是否存在 getStaticProps
函数来决定的,SSG
场景下的 pageIsDynamic
则必须配合 getStaticPaths
使用,可以看到 getStaticProps
会接收几个参数:
params
是在动态页面的路由参数previewData
和preview: preview
模式的相关数据locales, locale
和defaultLocale
多语言相关参数
执行完成后 getStaticProps
的返回值会被放入 pageProps
中。
再看看 invalidKeys
相关部分,除了 revalidate
、props
、redirect
和 notFound
外别的属性都会被视为非法。
const invalidKeys = Object.keys(data).filter(
key => key !== 'revalidate' && key !== 'props' && key !== 'redirect' && key !== 'notFound'
);
if (invalidKeys.includes('unstable_revalidate')) {
throw new Error(UNSTABLE_REVALIDATE_RENAME_ERROR);
}
if (invalidKeys.length) {
throw new Error(invalidKeysMsg('getStaticProps', invalidKeys));
}
然后还有关于 notFound
和 redirect
的处理:
if ('notFound' in data && data.notFound) {
if (pathname === '/404') {
throw new Error(`The /404 page can not return notFound in "getStaticProps", please remove it to continue!`);
}
(renderOpts as any).isNotFound = true;
}
if ('redirect' in data && data.redirect && typeof data.redirect === 'object') {
checkRedirectValues(data.redirect