为什么在Nextjs的图像组件中需要窗口检查的类型



所以我做一个占位符图像/svg来使用Nextjs图像组件,我从他们的repo复制了这个代码。我对后端开发(主要是前端)不是很有经验,所以我不得不研究缓冲区,流,窗口。bto等等。我不能完全理解的是为什么需要typeof window === "undefined"和随后的代码行。如果我删除它,它也能工作

我可以理解这是一个边缘情况,就像"如果"一样。但我不明白为什么需要它。它总是会呈现给浏览器。为什么要检查window是否未定义?

提前感谢,对不起,英语不好,这不是我的主要语言。

<<p>Nextjs代码/em>
const shimmer = (w, h) => `
<svg width="${w}" height="${h}" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="g">
<stop stop-color="#333" offset="20%" />
<stop stop-color="#222" offset="50%" />
<stop stop-color="#333" offset="70%" />
</linearGradient>
</defs>
<rect width="${w}" height="${h}" fill="#333" />
<rect id="r" width="${w}" height="${h}" fill="url(#g)" />
<animate xlink:href="#r" attributeName="x" from="-${w}" to="${w}" dur="1s" repeatCount="indefinite"  />
</svg>`
const toBase64 = (str) =>
typeof window === 'undefined'
? Buffer.from(str).toString('base64')
: window.btoa(str)
const Shimmer = () => (
<div>
<ViewSource pathname="pages/shimmer.js" />
<h1>Image Component With Shimmer Data URL</h1>
<Image
alt="Mountains"
src="/mountains.jpg"
placeholder="blur"
blurDataURL={`data:image/svg+xml;base64,${toBase64(shimmer(700, 475))}`}
width={700}
height={475}
/>
</div>

我在组件上的实现

<Image
src={props.src}
layout={props.layout}
width={props.width}
height={props.height}
placeholder="blur"
blurDataURL={`data:image/svg+xml;base64,${toBase64(shimmer(300, 300))}`}
/>

Next.js是一个用于React的框架,它可以帮助开发者在React中管理服务器端渲染。

服务器端呈现有很多好处,包括:缓存特定的页面(或者只缓存公共页面,并保留用户特定的数据或需要授权的数据,以便在前端加载)。

由于Next.js正在做服务器端渲染,这意味着有时他们在Node.js中使用reactDOMServer.renderToString()函数。他们将整个页面构建为HTML,并将其发送给正在浏览网站的用户。Next.js生成页面HTML的目的是最大化cdn的功能,并改善页面的SEO。因此,它们不仅将React页面呈现为HTML。它们使API请求和await为它们返回,允许它们呈现API响应的元素列表。

这可以让开发人员利用React的动态方面,并在渲染代码中运行JavaScript函数(如:{products.length <= 0 && <EmptyStateDiv type='products' />}),但遗憾的是,你不能使用JavaScript/功能,它存在于客户端/用户的浏览器中(与JavaScript/跨平台Node.js/browser相对)。

因此,虽然JS中内置的所有功能(如Array原型方法)都可以不加思考地使用。其他功能,如fetch,可以在Node.js和Frontend/React上跨平台使用,但这只能归功于像isomorphic-fetch这样的跨平台库。最后,其他功能只存在于浏览器中,而不是JavaScript的原生功能。这尤其包括从特定用户的浏览器访问的方法/属性,比如document.innerWidth is > 1600,但这是不可能的,因为这个函数在特定客户端呈现页面之前运行。Next.js在服务器端构建页面,像document/window这样的东西没有定义,并且它们存在没有意义。(虽然你可以通过阅读一些客户端标题来优化和缓存移动和桌面用户的不同体验。)

当它在Node.js(服务器端渲染)的服务器上运行时,窗口没有在Node.js运行时定义,它可能在渲染之前崩溃。在服务器上定义窗口也没有意义,因为窗口通常包含浏览器特定的属性,如clienttheight/clientWidth,或者允许用户使用window.location.assign进行客户端重定向,这在服务器上是不可能的。

如果此代码作为预渲染的一部分在服务器上运行(无论是服务器端渲染还是静态渲染),由于没有浏览器,将没有window(因此没有base64-encoding的window.btoa),而是可以利用node.js的Buffer

最新更新