How to load server-side libs (like `fs` or `os`) in collections only in case when code runs on the server?

default discord avatar
jmaslast year
1 1

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:

Screenshot 2023-02-16 at 20 22 51

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!

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.