A better way of handling server-only modules (Webpack alias) #3389
isaackoz
started this conversation in
Feature Requests & Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
The problem
I've been using PayloadCMS extensively as not only a CMS, but as a backend as well. It's been working great, however separating server-only code from the admin frontend can get tedious very quick. On top of that, PayloadCMS relies heavily on the use of hooks, and to have them bundled in the admin front-end does not make sense. Usually no errors are thrown, but if a library such as fs or stripe is used, webpack will not compile. Since hooks are server-only, they shouldn't be bundled at all.
The current solution to this is to alias server-only modules using the webpack config. While this works, the config becomes super messy after just a couple of aliases. While one could simply create an
aliasConfig.ts
file that contains all the modules to mock, it still is very tedious to have to keep track of which files are and aren't aliased.My solution
To get around this and make the dx easier and better, I made a module that will alias any file ending in
*.server.ts
. For example,getStripeInstance.server.ts
will simply exportexport default {};
without any additional configuration or modification to the webpack. This allows me to very quickly and easily make all my hooks server only modules without any work. I know exactly which files are and aren't bundled into the webpack and on top of that, my bundle size is smaller. I've had zero issues with this so far and it works for default and named exports alike.First create a mock module:
Next, create a file that will find and replace files ending in .server.ts
Then in
payload.config.ts
, set the webpack to ignore the files.Note that you must configure watchOptions to ignore the .server.ts files as well to avoid errors.
Now, any file ending in
*.server.ts
will be aliased to an empty mock module.Alternative solutions
While this has worked for me with no issues, I don't think it's the most ideal solution. Ideally, doing something similar to how React handles 'use client' or 'use server' would be the most ideal in my opinion. Adding something such as
'use-server-only'
to the top of server only files and then using babel to replace any files starting with it with a mock module. I actually managed to get this working, but it only worked with default exports and not named exports so I just decided to stick with the solution above as it worked fine for me with no issues.I would love to hear your opinion on this and if it's something that could be considered in future versions.
Beta Was this translation helpful? Give feedback.
All reactions