Hello again,
Thanks to @GeorgeyB (#675 (comment)) I moved my custom express endpoint implementation to collection property endpoints
and REST API works ok but there are a lot of errors in server console - see some of these:
ERROR in ./src/collections/Invoices.ts 3:11-24
Module not found: Error: Can't resolve 'fs' in '(...)/src/collections'
...
ERROR in ./node_modules/puppeteer/lib/esm/puppeteer/node/BrowserRunner.js 29:0-46
Module not found: Error: Can't resolve 'child_process' in '(...)/node_modules/puppeteer/lib/esm/puppeteer/node'
ERROR in ./node_modules/puppeteer/lib/esm/puppeteer/node/BrowserRunner.js 30:0-25
Module not found: Error: Can't resolve 'fs' in '(...)/node_modules/puppeteer/lib/esm/puppeteer/node'
ERROR in ./node_modules/puppeteer/lib/esm/puppeteer/node/BrowserRunner.js 32:0-37
Module not found: Error: Can't resolve 'readline' in '(...)/node_modules/puppeteer/lib/esm/puppeteer/node'
ERROR in ./node_modules/puppeteer/lib/esm/puppeteer/node/BrowserRunner.js 34:0-33
Module not found: Error: Can't resolve 'util' in '(...)/node_modules/puppeteer/lib/esm/puppeteer/node'
...
webpack compiled with 73 errors and 5 warnings
I use much more packages and each used in the handler throws such error "Module not found". Surprisingly endpoint works ok and I'm getting a response.
When I used custom express endpoint I hadn't such errors.
Hey @wojciechkrol — this is because you need to use Webpack alias
es to make sure that your custom endpoint code is not loaded into the admin JS bundle. Because the entire Payload config is imported directly in Webpack, and you now have your custom endpoint handlers imported in your Payload code, the admin panel is actually trying to load and execute those modules. And, fs
is a server-side only package built into Node.
Here's an example from one of our projects, where we alias a bunch of server-only modules:
webpack: (config) => ({
...config,
resolve: {
...config.resolve,
alias: [
path.resolve(__dirname, './hookHelperFunctions/stripeFunctions'),
path.resolve(__dirname, './twilio'),
path.resolve(__dirname, './email/sendTemplatedEmail'),
].reduce((alias, aliasPath) => ({
...alias,
[aliasPath]: mockModulePath,
}), config.resolve.alias),
},
}),
We basically tell Webpack that whenever one of those files gets imported, replace that file with the mockModulePath
file.
const mockModulePath = path.resolve(__dirname, './mocks/emptyModule.js');
And then mockModulePath
is a file that just exports an empty object:
module.exports = {};
There are some docs written up for this too here:
https://payloadcms.com/docs/admin/webpack#aliasing-server-only-modules
Give it a shot!
Well, it looks a bit complicated. I will look into this solution. Thank you for the explanation!