2019/02/25 くらいに出た Azure Functions Core Tools の 2.4.401 のリリースノートに
- Add TypeScript templates
の文言が。
これは試すしかないでしょう。ということでアップデートして func init
してみます。
C:\Users\kaota\Documents\Labs\TSFunc\Hello>func init Select a worker runtime: node Select a Language: javascript typescript
typescript がちゃんとある。typescript を選択すると package.json には以下のような devDependencies が追加されて
"devDependencies": {"@azure/functions": "^1.0.1-beta1", "typescript": "^3.3.3" }
さらには tsconfig.json も生成されます。
{"compilerOptions": {"module": "commonjs", "target": "es6", "outDir": "dist", "rootDir": ".", "sourceMap": true, "strict": false}}
npm install
しておきます。
func new
で HttpTrigger を選ぶとちゃんと index.ts が追加されました。
import{ AzureFunction, Context, HttpRequest }from"@azure/functions"const httpTrigger: AzureFunction =asyncfunction(context: Context, req: HttpRequest): Promise<void>{ context.log('HTTP trigger function processed a request.');const name =(req.query.name ||(req.body && req.body.name));if(name){ context.res ={// status: 200, /* Defaults to 200 */ body: "Hello " + (req.query.name || req.body.name)};}else{ context.res ={status: 400, body: "Please pass a name on the query string or in the request body"};}};exportdefault httpTrigger;
そして生成された HttpTrigger の function.json を見てみるとこうなってます。
{"disabled": false, "bindings": [{"authLevel": "function", "type": "httpTrigger", "direction": "in", "name": "req", "methods": ["get", "post" ]}, {"authLevel": null, "type": "http", "direction": "out", "name": "res", "methods": null}], "scriptFile": "../dist/Hello/index.js" }
なるほど、scriptFile で dist フォルダーの下に作られるコンパイル後の JavaScript を見るようにしてるんですね。ということで npm run build
をするか、npm run watch
をしてビルドをします。
そうすると dist フォルダーに js が生成されます。あとは func host start
をするとローカルで動くのでアクセスしてみましょう。
動いた!!
Durable Functions も試してみる
ハローワールド動いたので次は、個人的に Azure Functions のキラーコンテンツだと思ってる Durable Functions を試してみます。これが動かないと始まらない。 とりあえず以下のページを参考に…
まず下準備
func extensions install -p Microsoft.Azure.WebJobs.Extensions.DurableTask -v 1.7.0 npm install durable-functions
node_modules の下の durable-functions を見てみたらちゃんと .d.ts
もありますね!
func new
にも、ちゃんと Durable 系のテンプレートが入ってます。いいね。
ということで Starter と Orchestrator と Activity を適当に作ります。
インテリセンス出る。まじ神
ということで、こんな感じに Starter を調整して
import * as df from"durable-functions"import{ AzureFunction, Context, HttpRequest }from"@azure/functions"const httpStart: AzureFunction =asyncfunction(context: Context, req: HttpRequest): Promise<any>{const client = df.getClient(context);const instanceId =await client.startNew('Orchestrator',undefined, req.body); context.log(`Started orchestration with ID = '${instanceId}'.`);return client.createCheckStatusResponse(context.bindingData.req, instanceId);};exportdefault httpStart;
Orchestrator もこんな感じに
import * as df from"durable-functions"const orchestrator = df.orchestrator(function* (context){const outputs =[]; outputs.push(yield context.df.callActivity("Activity1","Tokyo")); outputs.push(yield context.df.callActivity("Activity2","Seattle"));return outputs;});exportdefault orchestrator;
Activity 関数はこんな感じ。
import{ AzureFunction, Context }from"@azure/functions"const activityFunction: AzureFunction =asyncfunction(context: Context): Promise<string>{return`Hello ${context.bindings.name} from Activity1!`;};exportdefault activityFunction;
ではビルドしたら実行しようと思ったのですが以下のエラーが。
node_modules/durable-functions/lib/src/utils.d.ts:1:23 - error TS2688: Cannot find type definition file for 'node'. node_modules/durable-functions/lib/src/utils.d.ts:8:56 - error TS2503: Cannot find namespace 'NodeJS'.
dist に js は生成されてるからビルドは出来てるけど気持ち悪いのでとりあえず以下のコマンドをうったら消えた。
npm i -d @types/node
Azure Storage Emulator を起動して func host start
します。
Azure Storage Emulator は最新にしましょう。少し古いやつだと何か問題が起きた記憶。
そうするとエラーが出ました。
[2019/02/28 4:20:44] A host error has occurred [2019/02/28 4:20:44] Microsoft.WindowsAzure.Storage: Settings must be of the form "name=value". Settings must be of the form "name=value".
そういえば local.settings.json に Azure Storage の接続文字列が初期状態では設定されてないんでした。エミュレーター用の接続文字列をとりあえず追加します。
こんな感じで
{"IsEncrypted": false, "Values": {"FUNCTIONS_WORKER_RUNTIME": "node", "AzureWebJobsStorage": "UseDevelopmentStorage=true" }}
あ、あと func host start
以外にも npm run start
や npm run start:host
とかでも OK。
何やってるかは package.json
にあります。
起動したら Starter のエンドポイントを叩くとばっちり動きます。
statusQueryGetUri を叩くと以下の JSON が返ってきました。
{"instanceId":"28038e30463544ab965db44f9c9ccb1e", "runtimeStatus":"Completed", "input":null, "customStatus":null, "output":["Hello Tokyo from Activity1!","Hello Seattle from Activity2!"], "createdTime":"2019-02-28T04:28:54Z", "lastUpdatedTime":"2019-02-28T04:28:56Z" }
ばっちりですね。適当に Azure に Function App を作ってデプロイもしてみました。とりあえず試すだけなら以下のコマンドで
func azure functionapp publish <作った Function App の名前>
デプロイされました。関数もちゃんと認識されてます。
叩いてみると無事動いた動いた。めでたい。
{"instanceId":"03e27dc7db234991bead2ea369173963", "runtimeStatus":"Completed", "input":null, "customStatus":null, "output":["Hello Tokyo from Activity1!","Hello Seattle from Activity2!"], "createdTime":"2019-02-28T04:36:16Z", "lastUpdatedTime":"2019-02-28T04:36:26Z" }
まとめ
これで Azure Functions の node のほうで開発するときに手軽に TypeScript 始めることが出来るようになりました。 TypeScript 好きな人も是非 Azure Functions 使ってみてね!