如何最好地在 Next.js 中导入“仅服务器”代码?

Sam*_*kai 8 javascript node.js isomorphic-javascript next.js

getServerSideProps我的索引页的功能中,我想使用一个foo从另一个本地文件导入的功能,该功能依赖于某个节点库。所述库不能在浏览器中运行,因为它依赖于“仅限服务器”模块,例如fsrequest

我一直在使用以下模式,但想对其进行优化。定义foo为可变以使其在范围内是笨拙的并且似乎可以避免。

let foo;
if (typeof window === "undefined") {
  foo =  require("../clients/foo");
}

export default function Index({data}) {
  ...
}

export async function getServerSideProps() {
  return {
    props: {data: await foo()},
  }
}
Run Code Online (Sandbox Code Playgroud)

这里的最佳做法是什么?是否有可能以某种方式利用 ES6 的动态导入功能?动态导入什么范围内 getServerSideProps

我正在使用 Next.js 版本9.3.6

谢谢。

更新:

似乎 Next.js 自己的动态导入解决方案就是这个问题的答案。我仍在测试它,并会在完成后相应地更新这篇文章。这些文档对我来说似乎很混乱,因为他们提到禁用 SSR 的导入,但反之亦然。

https://nextjs.org/docs/advanced-features/dynamic-import

jul*_*ves 9

当使用getServerSideProps/getStaticProps时,Next.js 将自动删除这些函数内的任何代码,并从客户端包中导入它们专门使用的代码。在浏览器上运行服务器代码没有风险。

然而,为了确保代码消除按预期进行,需要考虑一些因素。

  • 不要在客户端代码(如 React 组件)中使用用于服务器端的导入。
  • 确保这些文件中没有未使用的导入。Next.js 将无法判断导入是否仅适用于服务器,并将其包含在服务器和客户端包中。

您可以使用Next.js 代码消除工具来验证为客户端捆绑的内容。您会注意到getServerSideProps/getStaticProps和它使用的导入一样被删除。


D0m*_*0m3 5

getServerSideProps除了/之外getStaticProps,我发现了 2 个相当相似的解决方案。

依靠死代码消除

next.config.js

config.plugins.push(
    new webpack.DefinePlugin({
      'process.env.RUNTIME_ENV': JSON.stringify(isServer ? 'server' : 'browser'),
    }),
  );
Run Code Online (Sandbox Code Playgroud)
export const addBreadcrumb = (...params: AddBreadcrumbParams) => {
  if (process.env.RUNTIME_ENV === 'server') {
    return import('./sentryServer').then(({ addBreadcrumb }) => addBreadcrumb(...params));
  }
  return SentryBrowser.addBreadcrumb(...params);
};
Run Code Online (Sandbox Code Playgroud)

async await请注意,有些原因我不明白,如果您使用,或者使用变量来存储 的结果,则死代码消除效果不佳process.env.RUNTIME_ENV === 'server'。我在 nextjs github 中创建了一个讨论。

告诉 webpack 忽略它

next.config.js

if (!isServer) {
    config.plugins.push(
      new webpack.IgnorePlugin({
        resourceRegExp: /sentryServer$/,
      }),
    );
  }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您需要确保永远不会在客户端中导入此文件,否则您会在运行时收到错误。