nft: `@vercel/nft` does not pick up platform-specific binaries for `sharp`

Related:

@vercel/nft does not pick up platform-specific binary files while tracing dependencies.

For example, sharp@0.33.0 depends on @img/sharp-{arch} package, but the traced result only contains below paths.

node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/package.json
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/index.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/constructor.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/input.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/resize.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/composite.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/colour.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/channel.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/utility.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/operation.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/output.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/is.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/sharp.js
node_modules/.pnpm/sharp@0.33.0/node_modules/sharp/lib/libvips.js
node_modules/.pnpm/sharp@0.33.0/node_modules/color
node_modules/.pnpm/sharp@0.33.0/node_modules/detect-libc
node_modules/.pnpm/sharp@0.33.0/node_modules/semver

This currently breaks every build on Vercel and any deployments that uses @vercel/nft as its tree shaking library.

About this issue

  • Original URL
  • State: closed
  • Created 7 months ago
  • Reactions: 26
  • Comments: 21 (5 by maintainers)

Commits related to this issue

Most upvoted comments

@styfle I’d like to understand what’s going on here. From my understanding @vercel/nft will only strip dependencies that are not used during runtime. During build-time, everything should be there.

We are seeing people having issues with our platform-specific binary on Vercel: https://github.com/getsentry/sentry-cli/issues/1849 However, this binary is only used during build-time. What is going on here? Is there something we can do from our end? Special casing sounds kinda dangerous to me because we need to avoid having the binary deployed because of size concerns.

I just ran into this issue. For anyone stuck, downgrading to 0.32.6 works.

From my understanding, this is causing all app deployments that require sentry to fail on Vercel. Is there any workaround for this issue?

I see that this issue was renamed to be sharp specific. The issue isn’t specific to sharp, and is breaking every Sveltekit app on Vercel using Sentry as mentioned above.

Building onto this comment, considering this issue was renamed should we open a separate issue for the Sentry CLI issue? IMO it would be a step in the wrong direction since this issue affects pretty much all packages that ship their binaries in optional dependencies. It would probably even affect swc.

Indeed, the quickest path forward is to add a special case for sharp like the one for esbuild in special-cases.ts:


A proper fix would be updating the static analysis to handle the dynamic require.

We already support simple dynamic requires, such as:

const path = '@img/sharp-darwin-arm64/sharp.node';
const sharp = require(path);

Ideally, we could update that static analysis to handle the case of a for-loop, such as:

const paths = ['@img/sharp-darwin-arm64/sharp.node'];
for (const path of paths) {
  const sharp = require(path);
}

Source: https://github.com/lovell/sharp/blob/c80e92fa16b90a05ca604df17a3d58a87238b3ec/lib/sharp.js#L13-L30

@styfle Would you be able to respond to these comments from @lforst? There’s a bigger issue here than what you’ve acknowledged. We can create a reproduction, but I’m concerned that’s only going to lead to another special case that doesn’t address the underlying issue.

I’d like to understand what’s going on here. From my understanding @vercel/nft will only strip dependencies that are not used during runtime. During build-time, everything should be there.

We are seeing people having issues with our platform-specific binary on Vercel: getsentry/sentry-cli#1849 However, this binary is only used during build-time. What is going on here? Is there something we can do from our end? Special casing sounds kinda dangerous to me because we need to avoid having the binary deployed because of size concerns.

I see that this issue was renamed to be sharp specific. The issue isn’t specific to sharp, and is breaking every Sveltekit app on Vercel using Sentry as mentioned above.

Building onto this comment, considering this issue was renamed should we open a separate issue for the Sentry CLI issue? IMO it would be a step in the wrong direction since this issue affects pretty much all packages that ship their binaries in optional dependencies. It would probably even affect swc.

@styfle This seems to have been closed because the sharp special case PR was merged. This issue is still much larger than sharp.

I’ll see if I can whip up a simple repro in the upcoming days!

It’s breaking all Astro deployments as well… I had to downgrade sharp…

The logic used for esbuild should solve this:

https://github.com/vercel/nft/blob/37811197975fef8a3cda7d17e436d217a510398c/src/utils/special-cases.ts#L32-L41

I guess it might be worth extracting this logic as a common helper function as the use of optionalDependencies for native binaries is an increasingly common pattern.