【发布时间】:2021-08-30 08:39:45
【问题描述】:
我正在开发一个旨在供 Next.js 应用程序使用的开源包。其中一个组件是Link 的替代品。在我的包中,API 在package.json 中使用exports 公开,如下所示:
"exports": {
"./link": "./lib/link/index.js",
"./link-ssr": "./lib/link/ssr.js"
}
因为它需要服务器端渲染,所以我有两个版本的Link 组件,一个用于客户端,另一个用于 SSR。我能够让 SSR 工作的方法是在 next.config.js 中使用这个特殊的 Webpack 配置(在使用我的包的应用程序上):
webpack(config, { isServer }) {
if (isServer) {
config.resolve.alias['my-package/link'] = require.resolve(
'my-package/link-ssr'
);
});
因为link-ssr 仅在内部使用,所以我试图找到一种方法来避免暴露其 API。我想到的一种使用方法是在客户端link 组件中使用条件isServer 变量:
const isServer = typeof window === 'undefined'
if (isServer) {
// Do server stuff
} else {
// Do client stuff
}
服务器组件依赖于fs(文件服务器),当我这样做时,在尝试访问使用该组件的页面时出现 Next.js 编译错误:
event - compiled successfully
event - build page: /
wait - compiling...
error - ../lib/Links.js:5:0
Module not found: Can't resolve 'fs'
3 | exports.Links = void 0;
4 | const path_1 = require("path");
> 5 | const fs_1 = require("fs");
6 | /** Local rewrite cache to avoid non-required file system operations. */
7 | let linksCache;
8 | /**
这是否可行,或者是否有其他方法可以避免将 link-ssr 公开为公共组件?
【问题讨论】:
-
你的构建/编译错误是什么?
-
我刚刚编辑了问题并添加了错误的详细信息。
-
如果模块依赖fs,那你怎么能在浏览器中使用呢?听起来可能模块可能会溢出到单独的模块中。那或者你可以使用依赖注入来提供 fs 模块。
-
是的,
fs不应该在浏览器中使用,这就是isServer变量存在的原因——我希望 Webpack 可以自动拆分客户端和服务器文件,而无需使用alias配置。 -
因此,依赖注入方法将从您的链接模块中删除
fs导入,而是将模块导入调用模块中。然后调用模块将 fs 作为变量传递给函数。在浏览器中,您可以传入存根或undefined,在这种情况下,您不需要isServer检查。如果fs未定义,您只需跳过fs逻辑。这有意义吗?