aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.5k stars 3.84k forks source link

aws_lambda_nodejs: bundling with pnpm and Runtime.NODEJS_20_X fails because of pnpm bug #28318

Open keisukekomeda opened 9 months ago

keisukekomeda commented 9 months ago

Describe the bug

In Node.js 20, pnpm has a bug around node-fetch. https://github.com/pnpm/pnpm/issues/6424

This bug leads to the failure in bundling of app using native nodeModuels (like sharp).

Expected Behavior

Successfully synth cdk app.

Current Behavior

Failed to synth cdk app, and show error. pnpm [ERR_INVALID_THIS]: Value of "this" must be of type URLSearchParams

Reproduction Steps

Here is the minumum repro. https://github.com/keisukekomeda/aws-cdk-aws_lambda_nodejs-pnpm-repro

# enbale pnpm
corepack enable
# install node modules
pnpm install
# synth cdk app (should fails)
pnpm cdk synth

Possible Solution

I found that using pnpm 8.12.0 resolves the error.

As a workaround, I use a custom dockerImage for bundling. I think I'd like to update the pnpm version in default docker image.

    new cdk.aws_lambda_nodejs.NodejsFunction(this, "PnpmRepro", {
      runtime: cdk.aws_lambda.Runtime.NODEJS_20_X,
      entry: path.resolve(__dirname, "../src/index.ts"),
      handler: "main",
      bundling: {
        forceDockerBundling: true,
        nodeModules: ["sharp"],
        dockerImage: cdk.DockerImage.fromBuild(path.join(__dirname, "."), {
          buildArgs: {
            IMAGE: cdk.aws_lambda.Runtime.NODEJS_20_X.bundlingImage.image,
            ESBUILD_VERSION: "0",
          },
        }),
      }
    })
# The correct AWS SAM build image based on the runtime of the function will be
# passed as build arg. The default allows to do `docker build .` when testing.
ARG IMAGE=public.ecr.aws/sam/build-nodejs18.x
FROM $IMAGE

# Install yarn
RUN npm install --global yarn@1.22.5

# Install pnpm
RUN npm install --global pnpm@8.12.0 # <--- changed!!!!!

# Install typescript
RUN npm install --global typescript

# Install esbuild
# (unsafe-perm because esbuild has a postinstall script)
ARG ESBUILD_VERSION=0
RUN npm install --global --unsafe-perm=true esbuild@$ESBUILD_VERSION

# Ensure all users can write to npm cache
RUN mkdir /tmp/npm-cache && \
    chmod -R 777 /tmp/npm-cache && \
    npm config --global set cache /tmp/npm-cache

# Ensure all users can write to yarn cache
RUN mkdir /tmp/yarn-cache && \
    chmod -R 777 /tmp/yarn-cache && \
    yarn config set cache-folder /tmp/yarn-cache

# Ensure all users can write to pnpm cache
RUN mkdir /tmp/pnpm-cache && \
    chmod -R 777 /tmp/pnpm-cache && \
    pnpm config --global set store-dir /tmp/pnpm-cache

# Disable npm update notifications
RUN npm config --global set update-notifier false

# create non root user and change allow execute command for non root user
RUN /sbin/useradd -u 1000 user && chmod 711 /

CMD [ "esbuild" ]

Additional Information/Context

No response

CDK CLI Version

2.114.1 (build 02bbb1d)

Framework Version

No response

Node.js Version

v20.10.0

OS

MacOS 14.1.2(23B92)

Language

TypeScript

Language Version

TypeScript (5.2.2)

Other information

No response

keisukekomeda commented 9 months ago

I think pnpm version can be updated to v8 because Node.js 14 has been deprecated.

https://github.com/aws/aws-cdk/pull/24837

pahud commented 9 months ago

Thank you for your report. Please note CDK is not fully tested with pnpm.

keisukekomeda commented 9 months ago

@pahud Thank you for your reply.

I am willing to create PR for this, but I would like to wait for more feedback from the community.

I think we can upgrade pnpm to v8. reasons...

pahud commented 9 months ago

Yeah, I agree this deserves more community discussion and feedback.