SSR踩坑日记

最近在做UI组件开发,我制作的组件会交给Next.js进行SSR渲染。这篇文章用来记录一些SSR的一些坑。

1. document is not defined

这个问题在于,服务端并没有document这个对象。因此,解决方法是判断当前环境在服务端还是客户端。

if (typepf window){
    // Client side code
    // `document` object can be used here
} else {
    // Server side code
}

或者,在React.useEffect里面调用的函数会只在client side运行。

其实next.js官方是推荐把access web API的代码写进useEffect里面的,但是,我实测useEffect的代码里面access document这个对象依然会在服务端运行并报错,所以,加一个判断还是有必要的。(可能升级了next.js就会好了?)

2. React代码压缩引起的命名问题

我在写Orkaui的Motion组件的时候遇到过一个情况:在production环境下child.type.name还是React function/class component的名字,代码可以运行;而到了production环境下便失效了。

这个问题我还处理了很久(因为每次deploy代码都要花25~40分钟),最后发现,原始的React component名字会被压缩掉,使得方法名称无法识别。关于这个问题,有两个解决思路:

  1. 推荐的做法:把child.type.name === [React Component Name]改成child.type === [React Component]
  2. 如果不修改代码的话,需要修改webpack配置。对应到webpack里面的terser-webpack-plugin:需要把terserOptions.keep_fnames改为true。然而,next.js本身是默认隐藏webpack配置的,因此要解决这个问题,需要在next.config.jsmodule.exports.webpack里面进行修改。