sst / ion

SST v3
https://sst.dev
MIT License
1.7k stars 213 forks source link

I'm unable to use sharp on lambda (dev and deploy) #782

Open ajotaos opened 1 month ago

ajotaos commented 1 month ago

I have a pnpm monorepo, with one of the packages making use of the sharp library and a different package importing the first one where the lambda function code is located:

.
--infra
----comicbook
------pages.ts

--packages
----backend
------comicbook
--------files
----------package.json (with sharp)
--------functions

So when I try to run the function without installing sharp, everything is fine and the function runs. But as soon as the function is triggered while importing the sharp library, I get the following message on the console (can't copy / past from the new Ion SST console)

On sst dev Screenshot 2024-07-30 at 9 15 07 AM

And on sst deploy

{
    "errorType": "Runtime.UnhandledPromiseRejection",
    "errorMessage": "Error: Could not load the \"sharp\" module using the linux-arm64 runtime\nPossible solutions:\n- Ensure optional dependencies can be installed:\n    npm install --include=optional sharp\n    yarn add sharp --ignore-engines\n- Ensure your package manager supports multi-platform installation:\n    See https://sharp.pixelplumbing.com/install#cross-platform\n- Add platform-specific dependencies:\n    npm install --os=linux --cpu=arm64 sharp\n- Consult the installation documentation:\n    See https://sharp.pixelplumbing.com/install",
    "reason": {
        "errorType": "Error",
        "errorMessage": "Could not load the \"sharp\" module using the linux-arm64 runtime\nPossible solutions:\n- Ensure optional dependencies can be installed:\n    npm install --include=optional sharp\n    yarn add sharp --ignore-engines\n- Ensure your package manager supports multi-platform installation:\n    See https://sharp.pixelplumbing.com/install#cross-platform\n- Add platform-specific dependencies:\n    npm install --os=linux --cpu=arm64 sharp\n- Consult the installation documentation:\n    See https://sharp.pixelplumbing.com/install",
        "stack": [
            "Error: Could not load the \"sharp\" module using the linux-arm64 runtime",
            "Possible solutions:",
            "- Ensure optional dependencies can be installed:",
            "    npm install --include=optional sharp",
            "    yarn add sharp --ignore-engines",
            "- Ensure your package manager supports multi-platform installation:",
            "    See https://sharp.pixelplumbing.com/install#cross-platform",
            "- Add platform-specific dependencies:",
            "    npm install --os=linux --cpu=arm64 sharp",
            "- Consult the installation documentation:",
            "    See https://sharp.pixelplumbing.com/install",
            "    at 257 (/opt/nodejs/node_modules/sharp/index.js:10166:9)",
            "    at __webpack_require__ (/opt/nodejs/node_modules/sharp/index.js:10497:41)",
            "    at 7300 (/opt/nodejs/node_modules/sharp/index.js:5412:1)",
            "    at __webpack_require__ (/opt/nodejs/node_modules/sharp/index.js:10497:41)",
            "    at 1842 (/opt/nodejs/node_modules/sharp/index.js:5866:15)",
            "    at __webpack_require__ (/opt/nodejs/node_modules/sharp/index.js:10497:41)",
            "    at /opt/nodejs/node_modules/sharp/index.js:10514:37",
            "    at Object.<anonymous> (/opt/nodejs/node_modules/sharp/index.js:10517:12)",
            "    at Module._compile (node:internal/modules/cjs/loader:1358:14)",
            "    at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)"
        ]
    },
    "promise": {},
    "stack": [
        "Runtime.UnhandledPromiseRejection: Error: Could not load the \"sharp\" module using the linux-arm64 runtime",
        "Possible solutions:",
        "- Ensure optional dependencies can be installed:",
        "    npm install --include=optional sharp",
        "    yarn add sharp --ignore-engines",
        "- Ensure your package manager supports multi-platform installation:",
        "    See https://sharp.pixelplumbing.com/install#cross-platform",
        "- Add platform-specific dependencies:",
        "    npm install --os=linux --cpu=arm64 sharp",
        "- Consult the installation documentation:",
        "    See https://sharp.pixelplumbing.com/install",
        "    at process.<anonymous> (file:///var/runtime/index.mjs:1276:17)",
        "    at process.emit (node:events:519:28)",
        "    at emitUnhandledRejection (node:internal/process/promises:250:13)",
        "    at throwUnhandledRejectionsMode (node:internal/process/promises:385:19)",
        "    at processPromiseRejections (node:internal/process/promises:470:17)",
        "    at process.processTicksAndRejections (node:internal/process/task_queues:96:32)"
    ]
}

I'm not sure if this is the correct way to solve this (please advise if not), but I created a lambda layer of sharp with the options like and it seems to work on deploy:

layers: ['arn:aws:lambda:us-east-1:xxxxxxxxxxxxxxxxx:layer:sharp-layer:2'],
nodejs: {
  esbuild: {
    external: ['sharp'],
  },
}

But I can't get it to work on sst dev

I've also tried using:

nodejs: {
  install: ['sharp']
},

Placing this on the root package.json

    "pnpm": {
        "supportedArchitectures": {
            "cpu": ["x64", "arm64"],
            "os": ["linux", "current"]
        }
    }

Install sharp on --no-install=false

Using SST (not Ion) I was able to use sharp without any additional configuration to the function component, how would it be suggested now?

dividenconquer commented 1 month ago

Also experiencing this

fwang commented 1 month ago

This seems to be an issue w/ npm 8.

@ajotaos @dividenconquer Can you update npm to v10 and let me know if sst dev and sst deploy still fail?


^ note for @fwang if verified to be a npm v8 issue, should check users' npm version

ajotaos commented 1 month ago

Hi @fwang, I'm actually using pnpm v9.7.0 and also have npm installed globally v10.8.1

fwang commented 1 month ago

@ajotaos if u try these steps, do u get an error on step 4?

  1. mkdir sharp-test && cd sharp-test
  2. npm init -y
  3. npm install sharp
  4. node -e "console.log(require('sharp'))"
ajotaos commented 1 month ago

@fwang I'm not getting an error, it prints out the sharp object as normal.

[Function: Sharp] {
  align: { left: 'low', center: 'centre', centre: 'centre', right: 'high' },
  gravity: {
    center: 0,
    centre: 0,
    north: 1,
    east: 2,
    south: 3,
    west: 4,
    northeast: 5,
    southeast: 6,
    southwest: 7,
    northwest: 8
  },
  strategy: { entropy: 16, attention: 17 },
  kernel: {
    nearest: 'nearest',
    linear: 'linear',
    cubic: 'cubic',
    mitchell: 'mitchell',
    lanczos2: 'lanczos2',
    lanczos3: 'lanczos3'
  },
  fit: {
    contain: 'contain',
    cover: 'cover',
    fill: 'fill',
    inside: 'inside',
    outside: 'outside'
  },
  position: {
    top: 1,
    right: 2,
    bottom: 3,
    left: 4,
    'right top': 5,
    'right bottom': 6,
    'left bottom': 7,
    'left top': 8
  },
  blend: {
    clear: 'clear',
    source: 'source',
    over: 'over',
    in: 'in',
    out: 'out',
    atop: 'atop',
    dest: 'dest',
    'dest-over': 'dest-over',
    'dest-in': 'dest-in',
    'dest-out': 'dest-out',
    'dest-atop': 'dest-atop',
    xor: 'xor',
    add: 'add',
    saturate: 'saturate',
    multiply: 'multiply',
    screen: 'screen',
    overlay: 'overlay',
    darken: 'darken',
    lighten: 'lighten',
    'colour-dodge': 'colour-dodge',
    'color-dodge': 'colour-dodge',
    'colour-burn': 'colour-burn',
    'color-burn': 'colour-burn',
    'hard-light': 'hard-light',
    'soft-light': 'soft-light',
    difference: 'difference',
    exclusion: 'exclusion'
  },
  colourspace: {
    multiband: 'multiband',
    'b-w': 'b-w',
    bw: 'b-w',
    cmyk: 'cmyk',
    srgb: 'srgb'
  },
  colorspace: {
    multiband: 'multiband',
    'b-w': 'b-w',
    bw: 'b-w',
    cmyk: 'cmyk',
    srgb: 'srgb'
  },
  bool: { and: 'and', or: 'or', eor: 'eor' },
  cache: [Function: cache],
  concurrency: [Function: concurrency],
  counters: [Function: counters],
  simd: [Function: simd],
  format: {
    jpeg: { id: 'jpeg', input: [Object], output: [Object] },
    png: { id: 'png', input: [Object], output: [Object] },
    webp: { id: 'webp', input: [Object], output: [Object] },
    tiff: { id: 'tiff', input: [Object], output: [Object] },
    magick: { id: 'magick', input: [Object], output: [Object] },
    openslide: { id: 'openslide', input: [Object], output: [Object] },
    dz: { id: 'dz', input: [Object], output: [Object] },
    ppm: { id: 'ppm', input: [Object], output: [Object] },
    fits: { id: 'fits', input: [Object], output: [Object] },
    gif: { id: 'gif', input: [Object], output: [Object] },
    svg: { id: 'svg', input: [Object], output: [Object] },
    heif: { id: 'heif', input: [Object], output: [Object] },
    pdf: { id: 'pdf', input: [Object], output: [Object] },
    vips: { id: 'vips', input: [Object], output: [Object] },
    jp2k: { id: 'jp2k', input: [Object], output: [Object] },
    jxl: { id: 'jxl', input: [Object], output: [Object] },
    raw: { id: 'raw', input: [Object], output: [Object] }
  },
  interpolators: {
    nearest: 'nearest',
    bilinear: 'bilinear',
    bicubic: 'bicubic',
    locallyBoundedBicubic: 'lbb',
    nohalo: 'nohalo',
    vertexSplitQuadraticBasisSpline: 'vsqbs'
  },
  versions: {
    aom: '3.8.2',
    archive: '3.7.2',
    cairo: '1.18.0',
    cgif: '0.3.2',
    exif: '0.6.24',
    expat: '2.6.2',
    ffi: '3.4.6',
    fontconfig: '2.15.0',
    freetype: '2.13.2',
    fribidi: '1.0.13',
    gdkpixbuf: '2.42.10',
    glib: '2.80.0',
    harfbuzz: '8.3.0',
    heif: '1.17.6',
    highway: '1.1.0',
    imagequant: '2.4.1',
    lcms: '2.16',
    mozjpeg: '4.1.5',
    pango: '1.52.1',
    pixman: '0.43.4',
    png: '1.6.43',
    'proxy-libintl': '0.4',
    rsvg: '2.57.2',
    spng: '0.7.4',
    tiff: '4.6.0',
    vips: '8.15.2',
    webp: '1.3.2',
    xml: '2.12.6',
    'zlib-ng': '2.1.6',
    sharp: '0.33.4'
  },
  queue: EventEmitter {
    _events: [Object: null prototype] {},
    _eventsCount: 0,
    _maxListeners: undefined,
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false
  },
  block: [Function: block],
  unblock: [Function: unblock]
}
ajotaos commented 1 month ago

@fwang is it possible to know where the lambda code is looking the sharp library in while running in dev?

jayair commented 3 weeks ago

I put an example together for sharp: https://sst.dev/docs/examples/#sharp-image-resizer

And here's the repo for it: https://github.com/sst/ion/tree/dev/examples/aws-sharp