Hello everyone.
What I want to do?
I have users
collection that has hook beforeOperation
that should check incoming user
data for profile picture
URL, download it by URL into temp location and create new record in collection avatar
with attached temp file
, finally attach record id
as avatar
.
beforeOperation: [
async ({ args, operation }) => {
const { req, data } = args;
if (operation === "create") {
try {
// Here I tried to cheat and load lib via dynamic imports. It doesn't work.
// Also I tried ESM imports and require(). The same story.
const { downloadFile } = await import("../src/utils/downloadFile");
const { default: os } = await import("os");
const filePath = `${os.tmpdir()}/randomfile`;
if (data.picture) {
await downloadFile(data.picture, filePath);
const avatar = await req.payload.create({
collection: "avatars",
filePath,
});
return {
...args,
data: {
...data,
avatar: avatar.id,
},
};
}
} catch (error) {
console.log({ error });
}
return args;
}
},
],
},
Where is the problem?
When I add this code to collection users
and try to open Admin UI - I see following error:
Error as text:
ERROR in ./collections/Users.ts 174:36-48
Module not found: Error: Can't resolve 'os' in '/home/node/app/collections'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "os": require.resolve("os-browserify/browser") }'
- install 'os-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "os": false }
ERROR in ./src/utils/downloadFile.ts 126:0-39
Module not found: Error: Can't resolve 'fs' in '/home/node/app/src/utils'
I'm new with Pyload CMS, so I do not understand properly how it works. But I have assumption that Payload code shares between server-side and client-side, so if I add server-specific lib to collections it cause a problem on client-side.
Question: How to load server-side libs (like fs
or os
) in collections only in case when code runs on the server?
Thank you!
@jmas you're exactly right, you just need to alias your server-only code. Here are the docs that describe this in detail: https://payloadcms.com/docs/admin/webpack#aliasing-server-only-modules and here's a real-world example of this: https://github.com/payloadcms/template-ecommerce/blob/main/src/payload.config.ts#L35. Would this work for you?
So in your case, like this:
export default buildConfig({
admin: {
webpack: config => ({
...config,
resolve: {
...config.resolve,
alias: {
os: 'YOUR_MOCK_MODULE_PATH',
// OR extract your `beforeOperation` function into it's own file and alias THAT
}
}
})
}
})
@jacobsfletch Thank you for operative answer! I soved the problem, also I google better and found that plugin https://www.npmjs.com/package/payload-plugin-resolve-alias that looks like do the same but in more convenient way.
Star
Discord
online
Get dedicated engineering support directly from the Payload team..