Home Google Cloud Functions with TypeScript and Yarn
Post
Cancel

Google Cloud Functions with TypeScript and Yarn

Google’s documentation for getting started with Cloud Functions using JavaScript and NPM is great. The documentation does contain the required information for using TypeScript and Yarn, however it is not as obvious as it might be. The purpose of this post is to consolidate that information in one place. I hope it saves others from the digging that I had to do.

When I Googled this subject, most of the posts were dated or somewhat incomplete. The information in this post is current as of June 2023, but of course, your mileage may vary.

Prerequisites

As of this writing, I used these versions of the following pakages:

  • gcloud CLI (435.0.1)
  • Node.js (18.16.0)
  • Yarn (3.6.0)

You should be able to locate and install these packages without any difficulty.

Initializing the Project Folder

We are going to create the project from scratch, staring with an empty folder, gcftsty, for example.

In the empty folder, intialize the project with yarn:

1
yarn init -i

Adding the Basic Dependencies

For writing a Google Cloud Function using TypeScript, we need to add a minimum of two packages to the projcect:

  • @google-cloud/functions-framework - this package contains the required code so that we can test the function locally as well as deploy it to Google Cloud
  • typescript - this package contains the TypeScript compiler

Add these packages to the project as follows:

1
2
yarn add @google-cloud/functions-framework
yarn add -D typescript

Create tsconfig.json File

With yarn, there is no easy way to run tsc directly from the command line, so we’ll add a script to the package.json file as follows:

1
2
3
"scripts": {
  "tsconfig": "tsc --init"
}

Now we can generate the default tsconfig.json file:

1
yarn tsconfig

We can use the default tsconfig.json file pretty much as is, but we will change the values for rootDir and outDir as follows:

1
2
"rootDir": "./src",
"outDir": "./lib"

The default values for both of these properties is ./ but I like to keep both the TypeScript source files and the compile JavaScript files separate from all of the configuration files in the root folder of the project.

While you are it, you can create the actual ./src directory.

Write the Cloud Function

Create src/index.ts as follows:

1
2
3
4
5
import { HttpFunction } from '@google-cloud/functions-framework';

export const hello: HttpFunction = async (req, res) => {
  res.send('Hello World!');
}

OPTIONAL: If you are using Visual Studio Code and are bothered by the error highlighting, you can generate the proper editor SDKs and settings as follows:

1
yarn dlx @yarnpkg/sdks vscode

Test the Cloud Function Locally

We are now ready to test the Cloud Function locally. We need to add scripts to package.json to compile the TypeScript and run the function using functions-framework as follows:

1
2
3
4
5
"scripts": {
  "gcp-build": "tsc",
  "start": "functions-framework --target hello --port 8081",
  "tsconfig": "tsc --init"
}

You may be wondering why gcp-build and not just build? This seems to be one of the quirks associated with using the yarn package manager. This is important for when we deploy the function later. Google’s documentation for both cloud functions and cloud buildpacks indicate that if you specify a build script in the package.json file, then it will be run during deployment to build the function:

Node.js Runtime - NPM build script

Node.js - Executing custom build steps during deployment

Although the above is specifically talking about NPM, you would expect the same behaviour for yarn and that you could also just use a build script. That is not the case. you must use the custom build script, gcp-build for some reason to get this to work with yarn.

Since the TypeScript is compiled to the ./lib directory, we have to explicitly set the main property in the package.json file so that the index.js file can be found:

1
"main": "lib/index.js"

Once you have added the scripts above, you can build and run the function as follows:

1
2
yarn gcp-build
yarn start

Deploy the Cloud Function

When you deploy a function Goolge uses a buildpack to build a container with your function and then deploys it to Google Cloud Run. The buildpack uses the directory stucture and the contents of the package.json file in order to figure out exactly how to build the container. For plain JavaScript and NPM, there is nothing extra to do. For yarn, the buildpack will use yarn “classic” by defualt which is a problem if you are using a newer version of yarn locally. The Google buildpacks’ documentation explains how to specify a particular version of yarn to use:

Node.js - Installing dependencies - Using Yarn

So, in our example, we would add the following properties to the package.json file:

1
2
3
"engines": {
  "yarn": "^3.6.0"
}

Now we can finally deploy the function using a command similar to the following:

1
2
3
4
5
6
7
8
gcloud functions deploy hello \
    --gen2 \
    --runtime=nodejs18 \
    --region=us-west1 \
    --source=. \
    --entry-point=hello \
    --trigger-http \
    --allow-unauthenticated

Here is the link to the complete repo.

This post is licensed under CC BY 4.0 by the author.