DEV Community

Lorenzo Rivosecchi
Lorenzo Rivosecchi

Posted on

How to deploy Google Cloud Functions with PNPM workspaces

Are you struggling to deploy your monorepo project because Cloud Build doesn't know what the heck workspace:* means?
You are in the right place! In this blog I'll show you how to trick mister Google into deploying your PNPM monorepo project.

TL;DR

Just bundle everything, and ship the dist folder to Cloud functions with an empty package.json file. Ta-da! 🎩✨

This is how you do it

Create a simple deploy.sh script inside the package that contains the Cloud Function you want to deploy.

#!/bin/bash

# Install dependencies
pnpm install

# Build the project
npx esbuild \
    ./src/index.ts \
    --bundle \
    --platform=node \
    --target=node20 \
    --outfile=./dist/index.js \
    --external:@google-cloud/functions-framework
Enter fullscreen mode Exit fullscreen mode

In this file we simply install the dependencies with PNPM and bundle the source code with esbuild.
The --external:@google-cloud/functions-framework is required because functions-framework should not be bundled for some reason.
If you have some other dependencies that cannot be bundled, for example a module that uses native bindings, you should append another --external flag for that module.

Now, running the deploy.sh script will create a dist folder with the bundled code.
The only thing we are missing now is a package.json, because Cloud Functions pass through Cloud Build, which has trust issues and wants to build everything by itself.
So we are going to trick it with an empty package.json file.
Put this code right after the esbuild command:

jq -n \
  --arg name "@monorepo/functions" \
  --arg version "1.0.0" \
  --arg main "index.js" \
  --arg start "node index.js" \
  --arg build "echo \"No build step\"" \
  --arg ff_version "^3.3.0" \
  '{
    name: $name,
    version: $version,
    main: $main,
    scripts: {
      start: $start,
      build: $build
    },
    dependencies: {
      "@google-cloud/functions-framework": $ff_version
    }
  }' > ./dist/package.json

Enter fullscreen mode Exit fullscreen mode

We use jq to make the code more readable, but you can also use echo to write the JSON directly.
Now we just need to deploy the dist folder to Cloud Functions.
Add this last line to the deploy.sh script:

gcloud functions deploy myFunction \
    --runtime=nodejs20 \
    --trigger-http \
    --source=./dist
Enter fullscreen mode Exit fullscreen mode

And that's it! Now you can deploy your monorepo project to Cloud Functions with PNPM workspaces.

Top comments (0)