我的设置
我在_app.js
文件上使用getInitialProps
在服务器端预加载数据:
import App from "next/app";
// The problematic import
import nodeFetchCache from "node-fetch-cache";
function MyApp({ Component, pageProps, customProps }) {
return <Component customProps={customProps} {...pageProps} />;
}
MyApp.getInitialProps = async (appContext) => {
const appProps = await App.getInitialProps(appContext);
// When I remove the top import and use a classic "fetch" here, it works fine
const res = await nodeFetchCache(
`${process.env.NEXT_PUBLIC_API_URL}/api/node/last_items`
);
const items = await res.json();
return {
...appProps,
customProps: {
footerArticles: items.data.articles,
footerVideos: items.data.videos,
},
};
};
export default MyApp;
字符串
我的问题
此代码产生一个错误:
未处理的运行时错误TypeError:“原始”参数必须为Function类型
调用堆栈promisify node_modules/util/util.js(614:0)eval node_modules/@npmcli/move-file/index. js(25:0)对象../node_modules/@npmcli/move-file/index。js文件:/Users/dev/app/.next/static/chunks/pages/_app.js(716:1)对象。选择factory/_next/static/chunks/webpack.js(685:31)webpack_requirefile:/Users/dev/app/.next/static/chunks/webpack.js(37:33)fn/_next/static/chunks/webpack.js(354:21)eval node_modules/cache/lib/entry-index.js(16:17)Object../node_modules/cache/lib/entry-index.js文件:/Users/dev/app/.next/static/chunks/pages/_app.js(1598:1)对象。选择factory/_next/static/chunks/webpack.js(685:31)webpack_requirefile:/Users/dev/app/.next/static/chunks/webpack.js(37:33)fn/_next/static/chunks/webpack.js(354:21)eval node_modules/cache/ls.js(3:14)Object../node_modules/cache/ls.js文件:/Users/dev/app/.next/static/chunks/pages/_app.js(1686:1)对象。选择factory/_next/static/chunks/webpack.js(685:31)webpack_requirefile:/Users/dev/app/.next/static/chunks/webpack.js(37:33)fn/_next/static/chunks/webpack.js(354:21)eval node_modules/cache/index.js(3:11)Object../node_modules/cache/index.js文件:///Users/dev/app/.next/static/chunks/pages/_app.js(1543:1)对象。选择factory/_next/static/chunks/webpack.js(685:31)webpack_requirefile:/Users/dev/app/.next/static/chunks/webpack.js(37:33)fn/_next/static/chunks/webpack.js(354:21)eval webpack-internal:/./node_modules/node-fetch-cache/src/classes/caching/file_system_cache.js(5:65)Module../node_modules/node-fetch-cache/src/classes/caching/file_system_cache.js file:///Users/dev/app/.next/static/chunks/pages/_app.js(4513:1)模块。选择factory/_next/static/chunks/webpack.js(685:31)webpack_requirefile:/Users/dev/app/.next/static/chunks/webpack.js(37:33)fn/_next/static/chunks/webpack.js(354:21)eval webpack-internal:/./node_modules/node-fetch-cache/src/index.js(13:95)Module../node_modules/node-fetch-cache/src/index.js file:/Users/dev/app/.next/static/chunks/pages/_app.js(4557:1)模块。选择factory/_next/static/chunks/webpack.js(685:31)webpack_requirefile:///Users/dev/app/.next/static/chunks/webpack.js(37:33)fn/_next/static/chunks/webpack.js(354:21)eval webpack-internal:/./pages/_app.js(10:74)Module../pages/_app.js file:/Users/dev/app/.next/static/chunks/pages/_app.js(40:1)模块。选择factory/_next/static/chunks/webpack.js(685:31)webpack_requirefile:/Users/dev/app/.next/static/chunks/webpack.js(37:33)fn/_next/static/chunks/webpack.js(354:21)eval node_modules/next/dist/build/webpack/loaders/next-client-pages-loader. js?page =%2F_app&absolutePagePath = private-next-pages%2F_app!(5:15)eval node_modules/next/dist/client/route-loader.js(207:48)
从其他开发人员告诉我的情况来看,似乎Next试图在客户端导入服务器端代码。即使我删除了await nodeFetchCache(...)
调用,我在顶部导入'node-fetch-cache'
的唯一事实也会给我一个错误。
我的问题
我想达到的目标有可能实现吗?getInitialProps
不是应该只在服务器端运行吗?难道代码/树抖动不应该消除客户端包中未使用的导入吗?
我有点迷路了。如有任何帮助,我们将不胜感激。
2条答案
按热度按时间14ifxucb1#
getInitialProps
不是应该只在服务器端运行吗?只有在某些情况下。
通常,
getInitialProps
同时在服务器(初始页面加载时)和客户端(客户端导航时)运行。此规则的例外是当您导航到的页面使用getServerSideProps
时。getInitialProps
文档:对于初始页面加载,
getInitialProps
将仅在服务器上运行。然后,当通过next/link
组件或使用next/router
导航到不同的路由时,getInitialProps
将在客户端上运行。但是,如果在自定义_app.js
中使用getInitialProps
,并且导航到的页面实现了getServerSideProps
,则getInitialProps
将在服务器上运行。因此,与
getServerSideProps
/getStaticProps
不同,getInitialProps
的代码不会通过Next.js从客户端包中获取automatically eliminated。这意味着webpack将在客户端包中包含您在getInitialProps
中使用的任何库。理想情况下,您将希望用getInitialProps
编写同构代码,即可以在客户机和服务器上运行的代码。在你的例子中,
node-fetch-cache
是一个Node.js库,不能在浏览器中运行。从我所看到的可能的解决方案是:1使用同构包
简单的解决方案是使用同构库来替换
node-fetch-cache
,如isomorphic-fetch
。这将允许您在客户端和服务器上使用它,而不会带来额外的麻烦。#2使用webpack的
IgnorePlugin
如果你想在服务器上只在
getInitialProps
内部运行node-fetch-cache
代码,你可以使用webpack的IgnorePlugin
来忽略客户端的模块,防止任何潜在的错误。字符串
#3使用webpack的
resolve.alias
与前面的解决方案类似,您可以使用set
resolve.alias
tofalse
来告诉webpack在客户端忽略node-fetch-cache
。型
请注意,对于解决方案**#2和#3**,您需要重构当前代码以正确处理客户端场景,因为
node-fetch-cache
将无法在那里使用。型
a9wyjsp72#
您可以将此参数添加到
package.json
字符串
因此它将从客户端捆绑中排除它