はじめに
この章では以下の内容について説明します。
- TypeScriptの実行方法
-
tsx
を利用して簡単に Cloud Run functionsの TS直接実行 × ホットリロード環境を構築する
TypeScriptを実行する方法として以下の2つがあります。
- TS → JSにトランスパイルしてから実行
- Node.js上でTypeScriptを直接実行できる
ts-node
やtsx
を使用する
それぞれのやり方を紹介します。
0. Node.js関数のTS化
事前準備として、前章で作成した index.js
を index.ts
に名称変更し、TS用に中身を書き換えます。
import * as ff from '@google-cloud/functions-framework';
import type { HttpFunction } from "@google-cloud/functions-framework";
export const helloGET: HttpFunction = (req: ff.Request, res: ff.Response) => {
res.send(`Hello World!`);
};
方法1, 2の最初のディレクトリ構成は以下の状態から始めます。
.
├── node_modules
├── package-lock.json
├── package.json
├── src
│ └── index.ts
└── tsconfig.json
方法1. TS → JSにトランスパイル
TypeScriptはそのままで実行できないため、JavaScriptにトランスパイルする必要があります。
トランスパイルするには tsc
をコマンドラインで実行します。
npx tsc
すると tsconfig.json
の内容に従って dist/index.js
ファイルが出力されます。
import * as ff from '@google-cloud/functions-framework';
export const helloGET = (req, res) => {
res.send(`Hello World!`);
};
//# sourceMappingURL=index.js.map
├── dist
│ ├── index.js
│ └── index.js.map
├── node_modules
├── package-lock.json
├── package.json
├── src
│ └── index.ts
└── tsconfig.json
package.json
の main
は実行されるJSファイルのパスにします。
"main": "dist/index.js",
"type": "module",
"scripts": {
"start": "functions-framework --target=helloGET"
}
これで npm run start
を実行すると、Node.js関数が実行されHTTPで待ち受けるようになります。
お分かりだと思いますが、このやり方には以下2つの欠点があります。
- 変更のたびJSファイルも更新するために毎回
tsc
を打たないといけない -
tsc
に結構時間がかかる
トランスパイルの時間を省略できて、HTTPで待ち受けているプロセスの再起動もファイルの変更のたびによしなに行って欲しい(Hot reload)ですよね。
この2つを解消するのが次に紹介するtsx
を使ったFunctions Frameworkの実行方法です。
方法2. tsx
を使ってTSのまま実行
tsx
とは簡単にいうと、Node.js上でTypescriptファイルをそのまま実行できるライブラリです。
node
コマンドを使うところを tsx
に置き換えたらそのまま使えます。超便利。
node index.js // node JSモジュール
tsx index.ts // tsx TSモジュール
型チェックが走らないという特徴がありますが、型チェックはビルド時にまとめて行うようにする(つもり)なので、無問題です。
まず devDependencies
に tsx
をインスコしましょう。
npm install --save-dev tsx
package.json
の start
を以下のように書き換えましょう。
-
node
→tsx
-
functions-framework
→node_modules/.bin/functions-framework
-
--source=./src/index.ts
オプションの追加
"scripts": {
"start": "tsx node_modules/.bin/functions-framework --target=helloGET --source=./src/index.ts"
}
tsx
コマンドの引数は TS/JS モジュールである必要がありますが、ライブラリの実行ファイルももちろんTS/JSモジュールです。 中身をチラ見してみますと、
#!/usr/bin/env node
"use strict";
// ... 省略
const main = async () => {
// ... 省略
};
exports.main = main;
// Call the main method to load the user code and start the http server.
(0, exports.main)();
//# sourceMappingURL=main.js.map
なので tsx
の引数に指定して使うことができます。
そして Functions Framework には公式ドキュメントに書いていない隠しオプションがあります。--source
オプションです。
このオプションを指定すると、そのファイル内の --target
オプションで指定した関数をエントリーポイントとして実行するようになります。
npm run start
を実行してみましょう。
$ npm run start
> advent-calendar-2024@1.0.0 start
> tsx node_modules/.bin/functions-framework --target=helloGET --source=./src/index.ts
Serving function...
Function: helloGET
Signature type: http
URL: http://localhost:8080/
$ curl http://localhost:8080/
Hello World!
無事、TSファイルのまま実行することができました。
hot reload
先ほどのstart
コマンドの内容に ---watch
オプションをつけるだけです。
"scripts": {
"watch": "tsx --watch node_modules/.bin/functions-framework --target=helloGET --source=./src/index.ts"
}
巷に溢れている Cloud Run functions のホットリロードの記事では nodemon
を使うだの concurrently
を使うだの npm-wacth
を使うだのしているものがほとんどですが、間違いなくこれが一番簡単な方法です。
inspector(デバッグ機能)
tsx
オプションに ---inspect
オプションをつけるだけです。
"debug": {
"start": "tsx --inspect node_modules/.bin/functions-framework --target=helloGET --source=./src/index.ts"
}
おわりに
Node.js上でTSを直接実行する方法、特にFunctions frameworkでTS関数を実行する方法を紹介しました。
次回は --inspect
を使ってデバッグを行う方法を紹介したいと思います。