I am working on an open-source package meant to be used by a Next.js app. One of the components is a replacement for Link. In my package, the APIs are exposed using exports in package.json, like this:
"exports": {
"./link": "./lib/link/index.js",
"./link-ssr": "./lib/link/ssr.js"
}
Because it requires server-side rendering, I have two versions of the Link component, one for the client and the other one for SSR. The way I was able to get SSR to work was to use this special Webpack config (on the app that uses my package) in next.config.js:
webpack(config, { isServer }) {
if (isServer) {
config.resolve.alias['my-package/link'] = require.resolve(
'my-package/link-ssr'
);
});
Because link-ssr is only used internally, I was trying to find a way to avoid exposing its API. One way I thought of using was to use a conditional isServer variable inside the client link component:
const isServer = typeof window === 'undefined'
if (isServer) {
// Do server stuff
} else {
// Do client stuff
}
The server component relies on fs (file server) and when I do this I get a Next.js compilation error when trying to access a page that uses the component:
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 | /**
Is this even feasible or are there other ways to avoid exposing link-ssr as a public component?