- Published on
server-only package is empty?!
Then how can it prevent a client component from using it?
- Authors
- Name
- Nico Prananta
- Follow me: @2co_p
If you've read the Next.js documentation, you'll know about server-only package since it's mentioned a few times in the doc. Using this package, you can keep server-only code out of the client component. I was kinda curious about this package and how it works and my discovery was a bit surprising.
First, I need to find out where the source code for this package is. This happened to be quiet a challenge because the package basically has no information whatsoever in the NPM registry. Not to mention there's no link to the source code. It only has a link to reactjs.org.
I found out later on that the source code is actually in Next.js repository. But to my surprise, this package only has 3 files: a package.json
, index.js
, and empty.js
. Inside the index.js
file, there's only a single error throw statement. In the empty.js
file, there's nothing! So how does this package even work?!
It turns out the key is in the package.json. The package.json has an exports
key with value I have never seen before.
"exports": {
".": {
"react-server": "./empty.js",
"default": "./index.js"
}
}
This is what they called a conditional export. It means that when the package is imported in an environment where the react-server
condition is set, it will load the empty.js
file, in other words, this package does nothing.
On the other hand, if the package is imported in an environment where the react-server
condition is not set, it will load the index.js
file, which will throw an error.
CMIIW, but this condition is set by the bundler when building and running the application. In case of Next.js, I see that it is set in the webpack config.
By the way, I'm making a book about Pull Requests Best Practices. Check it out!