nextjs 初体验
最近有个项目转到我这里维护,项目基于 nextjs,刚好之前只有耳闻,未尝使用过,这里简单记录一下。
接手过来的时候项目没有添加 eslint,查看文档后发现添加 eslint 比较简单
npm i eslint eslint-config-next -D
// .eslintrc.json
{
"extends": "next"
}
本次有个调整需要引入一个新的 npm,麻烦就来了。
首先是 next.js 默认不编译 node_modules,具体查看 https://github.com/vercel/next.js/issues/706。解决办法是添加 next-transpile-modules
const withTM = require('next-transpile-modules')(['package-need-transpile']);
module.exports = withTM({
// ...
webpack5: false,
});
项目不是 webpack5,因此置为 false
接着,nextjs 提示我第三方库引入了全局 css。具体查看 https://github.com/fullcalendar/fullcalendar/issues/5393。解决办法我这里就比较粗暴了,fork 出一份第三方库,将里面的全局样式注释掉。
接着,nextjs 提示入门必提示的 window is not defined,这是由于 node 环境还不存在 window。
这时候有几个解决方案:
- 在 didMount / useEffect 中使用 window
- 如果是引入组件,那么通过
next/dynamic引入, 且设置 ssr 为 false - 判断 typeof window !== “undefined” 再使用 window
按上述的方法解决完之后,代码运行,看似没啥问题了。打包,大功告成?等等,又出现了 window is not defined,打包失败。可是我在 dev 的时候确实是编译成功了且没有报错啊。查看提示发现原来是引入的包中使用到了 window
const MyNoSsrCom = dynamic(() => import('./MyCom'), { ssr: false })
// MyCom.jsx
import { sometool } from 'my-package'
// ...
// my-package.js
// 使用到了 window
window.xxxx
这种情况虽然在 dev 是可以的,然而 build 的时候却会报错,原因不详
无奈,只能做如下处理
// MyCom.jsx
const {sometool } = typeof 'window' === undefined ? {} : require('my-package')
// ...
看似没啥问题了,再次 build,依然还是失败了。这次提示 pages 下有文件没有默认导出 react 组件,仔细一看正是我 fork 出来的包文件。不知道为什么将这个文件判断成 react 组件,估计是因为其中存在 Class?只好添加一个默认导出
至此大功告成,但我却陷入怀疑,这个项目本身并没有太多 seo 的痕迹/需求,也只是一个页面,按道理没有首屏幕渲染之类的问题,为什么强行上了个 nextjs,代码中处处都要 typeof 'window' === undefined 这真的好吗?
也许是还没有更深入去了解 nextjs,才会有上述见解。但起码对普通的项目于我而言大概率是不会再有 next 了吧。。