DEV Community

Lorenzo Rivosecchi
Lorenzo Rivosecchi

Posted on

1

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.

Do your career a big favor. Join DEV. (The website you're on right now)

It takes one minute, it's free, and is worth it for your career.

Get started

Community matters

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay