serverless-esbuild icon indicating copy to clipboard operation
serverless-esbuild copied to clipboard

Third level peerDependency is not excluded / canvas.node: invalid ELF header

Open mzl-md opened this issue 2 years ago • 6 comments

Describe the bug

We have a lambda with dependency jsdom, which has peerDependency canvas. Until recently, canvas was not installed by npm and not bundled by esbuild. If canvas is present, an error canvas.node: invalid ELF header is thrown at runtime. Since the latest update, our devDependency pdf-visual-diff requires canvas. This leads to canvas beeing included in the bundle and runtime errors. We were hoping to prevent canvas from beeing included by adding it to exclude in the serverless.yml, but that does not work.

To Reproduce

  • clone https://github.com/mzl-md/esbuild-canvas-error
  • run npm i
  • run npm test

Dependencies in package.json:

  "dependencies": {
    "jsdom": "19.0.0"
  },
  "devDependencies": {
    "pdf-visual-diff": "0.6.0",
    "serverless": "3.17.0",
    "serverless-esbuild": "1.27.1"
  }

Config in serverless.yml:

custom:
  esbuild:
    exclude:
      - "aws-sdk"
      - "canvas"
    external:
      - jsdom

Run npx sls package and unzip the bundle => node_modules/canvas exists :(

Expected behavior node_modules/canvas is not included in the bundle.

Versions (please complete the following information):

  • OS: Mac
  • Serverless Framework Version: 3.17.0
  • Plugin Version: 1.27.1

Workaround Deleting the canvas directory works, but all dependencies of canvas stay included in the bundle:

custom:
  esbuild:
    packagerOptions:
      scripts:
        - rm -rf node_modules/canvas

mzl-md avatar May 16 '22 12:05 mzl-md

Ah I think I know the issue but won't have much time this week

https://github.com/floydspace/serverless-esbuild/blob/dc3c6848b35cc711c130cb80c99e3e4b04eaa828/src/helper.ts#L83

This needs the exclude list.

samchungy avatar May 16 '22 12:05 samchungy

Thanks for pointing me in the right direction 👍 I will create a PR if I find some spare time.

mzl-md avatar May 16 '22 16:05 mzl-md

I'd have to test this but I believe this line here:

https://github.com/floydspace/serverless-esbuild/blob/fbf213d47a700debd15202e3f59f852b8edfe2a1/src/helper.ts#L92 you could add an or condition here to return if it's in the exclude list.

samchungy avatar May 17 '22 08:05 samchungy

flatDep() is not called as far as I can tell.

I can't think of a good way to implement the exclude for third level dependencies, since the plugin-internal npm install will always install them and deleting or not including them in the bundle would still keep all fourth level dependencies of the excluded dependencies.

But as I now understand, our problem is caused by the plugin-internal npm install installing the optional peerDependencies of our dependencies. So in our case, the best solution would be to use

    installExtraArgs:
      - '--legacy-peer-deps'

TL;DR: Our problem can be solved with a different solution, but the bug is still valid in my opinion.

mzl-md avatar May 17 '22 09:05 mzl-md

Oh I see because you are not using package individually.

samchungy avatar May 17 '22 10:05 samchungy

I've opened a PR addressing this issue https://github.com/floydspace/serverless-esbuild/pull/481

deathemperor avatar Aug 08 '23 13:08 deathemperor