LoginSignup
5
3

More than 3 years have passed since last update.

Nuxt.js + Netlify Functions を TypeScript で構築する

Posted at

この記事の目標

  • Nuxt.js + TypeScriptで実装
  • Netlifyにホスティング
  • Netlify FunctionsをTypeScriptで実装
  • Nuxt.jsからNetlify Functionsを呼び出す

動作確認環境

項目 バージョン
macOS 10.13.6 (High Sierra)
node 13.8.0
npm 6.13.7

ソースコード

1. Nuxt.js

まず、フロントエンド環境から構築していきます。

ボイラーテンプレート生成

create-nuxt-appを使います。

2020年3月18日にリリースされたv2.15.0から、TypeScriptをサポートしているので、質問に答えるだけで、簡単にTypeScript環境を構築できます。

$ npx create-nuxt-app nuxt-netlify-ts
  • 言語はTypeScriptを選択
  • TypeScriptのruntimeは@nuxt/typescript-runtimeを選択
  • Axiosのモジュールを追加
  • レンダリングモードはSPA
  • あとはお好みで
? Project name nuxt-netlify-ts
? Project description My super Nuxt.js project
? Author name nishitaku
? Choose programming language TypeScript
? Choose the package manager Yarn
? Choose UI framework Vuetify.js
? Choose custom server framework None (Recommended)
? Choose the runtime for TypeScript @nuxt/typescript-runtime
? Choose Nuxt.js modules Axios, DotEnv
? Choose linting tools ESLint, Prettier
? Choose test framework None
? Choose rendering mode Single Page App
? Choose development tools jsconfig.json

以下Lintエラーが出力されますが、無視してOKです。

$ eslint --ext .js,.vue --ignore-path .gitignore . --fix

/Users/takuro/workspace/ojthv2/nuxt-netlify-ts/nuxt.config.js
  80:12  error  'config' is defined but never used. Allowed unused a
rgs must match /^_/u  @typescript-eslint/no-unused-vars
  80:20  error  'ctx' is defined but never used. Allowed unused args
 must match /^_/u     @typescript-eslint/no-unused-vars

✖ 2 problems (2 errors, 0 warnings)

error Command failed with exit code 1.

動作確認

開発サーバ起動

$ cd nuxt-netlify-ts
$ yarn dev

http://localhost:3000にアクセスして正常に表示されることを確認。
nuxt.png

2. Netlifyにデプロイ

次に、生成したボイラーテンプレートを、Netlifyにデプロイします。

NetlifyはGitHubリポジトリと紐付けておくことで、PushやMergeをトリガーに、自動的にビルド&デプロイしてくれる機能があるため、それを使っていきます。

GitHubリポジトリ作成

Gitに関してはざっくりとコマンドのみ。

$ git remote add origin (リポジトリURL)
$ git add .
$ git commit -m "generated by create-nuxt-app/2.15.0 darwin-x64 node-v13.8.0"
$ git push origin master

NetlifyとGitHubリポジトリを紐付け

  • Create a new site
    • Continuous Deployment
      • GitHubを選択
    • Continuous Deployment: GitHub App
      • 先程のGitHubリポジトリを選択
    • Basic build settings
      • Build command:yarn build
      • Publish directory:dist

動作確認

デプロイ完了後、独自に割り当てられたhttps://(Netlifyドメイン)にブラウザからアクセスし、開発サーバのときと同じ画面が表示されることを確認。

3. Netlify Functions

Netlifyが提供するFaaS (Function as a Service)

Freeプランで、125,000リクエスト/月100時間/月使えます。

ベースはAWS Lambdaですが、シンプルな設定ですぐに使い始められます。

環境構築

netlify-lambdaを使います。

$ yarn add -D netlify-lambda

次に、TypeScriptで記述するためのライブラリを追加。

$ yarn add -D @babel/preset-typescript @types/aws-lambda

netlify-lambdaのbabelの設定を上書きするために、新たに.babelrcをルートに追加。

.babelrc
{
  "presets": [
    "@babel/preset-typescript",
    "@babel/preset-env"
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-transform-object-assign",
    "@babel/plugin-proposal-object-rest-spread"
  ]
}

開発サーバを起動するためには、netlifyの設定ファイルが必要になります。

また、NetlifyはGitHubリポジトリにnetlify.tomlが存在する場合、GUIでの設定内容よりも優先します。そのため、Functionsの設定だけでなく、ホスティングの設定も合わせて記載しておく必要があります。

netlify.toml
[build]
  Command = "yarn build"
  functions = "functions/dist"
  publish = "dist"

package.jsonに、開発サーバ起動スクリプトを追加。

package.json
{
  "scripts": {
    "dev:functions": "netlify-lambda serve functions/api",
  },
}

実装

ディレクトリfunctions/apiを追加し、サンプル用の関数を実装。

hello.ts
import { Handler, Context, Callback, APIGatewayEvent } from 'aws-lambda'

interface HelloResponse {
  statusCode: number
  body: string
}

export const handler: Handler = (
  event: APIGatewayEvent,
  context: Context,
  callback: Callback
) => {
  console.log(`hello invoked`)
  const params = event.queryStringParameters
  const response: HelloResponse = {
    statusCode: 200,
    body: JSON.stringify({
      msg: `Hello world ${Math.floor(Math.random() * 10)}`,
      requestId: context.awsRequestId || 'dummy',
      params
    })
  }

  callback(undefined, response)
}

動作確認

開発サーバを起動。9000番ポートで起動します。

$ yarn dev:functions

curlでレスポンスを確認。

$ curl "http://localhost:9000/.netlify/functions/hello"
{"msg":"Hello world 0","requestId":"dummy","params":{}}

因みに、http://localhost:9000/helloでも同様の結果が返ってきます。

4. Netlify Functionsのデプロイ

ホスティングと同様、GitHubリポジトリへPushするだけで、自動的にNetlify環境へ反映されます。

GitHubリポジトリへのPush

まず、Functionsのビルド設定を追加。

package.json
{
  "scripts": {
    "build": "netlify-lambda build functions/api && nuxt-ts build",
  },
}

GitHubにPushし、

動作確認

デプロイ完了後、curlでレスポンスを確認。

$ curl "http://(Netlifyドメイン)/.netlify/functions/hello"
{"msg":"Hello world 0","requestId":"dummy","params":{}}

5. Nuxt.jsからNetlify Functionsを呼び出す

NetlifyにデプロイしたNuxt.jsの画面から、Netlify Functionsの関数を呼び出します。

CORSエラー対応

開発環境では、Nuxt.jsのポート番号(3000)とnetlify-lambdaのポート番号(9000)が異なるため、そのままだとCORSエラーが発生します。

回避策として、@nuxtjs/proxyのリバースプロキシ機能を使うことで、http://localhost:3000/.netlify/functions/helloへのアクセスを、http://localhost:9000/.netlify/functions/helloへ転送します。

@nuxtjs/proxyをインストール。

$ yarn add @nuxtjs/proxy

nuxt.config.jsmodules@nuxtjs/proxyを追加

nuxt.config.js
export default {
  modules: [
    '@nuxtjs/proxy'
  ],
}

nuxt.config.jsproxyを追加

nuxt.config.js
export default {
  proxy: {
    '/.netlify/functions': {
      target: 'http://localhost:9000'
    }
  }
}

Axiosの設定

@nuxtjs/axiosbaseURLに何も設定しなかった場合、デフォルトでhttp://localhost:3000となってしまいます。

そのため、https://(Netlifyドメイン)からhttps://(Netlifyドメイン)/.netlify/functionsを呼び出してほしいのに、http://localhost:3000/.netlify/functionsを呼び出してしまいます。

これを回避するため、nuxt.config.jsaxiosbaseURLを設定します。

nuxt.config.js
export default {
  axios: [
    baseURL: '/'
  ],
}

ソースコード修正

動作確認用のコードをindex.vueに埋め込む。

index.vue
<script>
export default {
  // 追加
  async mounted() {
    try {
      const response = await this.$axios.$get('.netlify/functions/hello')
      console.log(`respones=${JSON.stringify(response)}`)
    } catch (err) {
      console.error(err)
    }
  }
}
</script>

動作確認

$ yarn dev // Nuxt.js開発サーバ起動
$ yarn dev:functions // netlify-lambda開発サーバ起動

http://localhost:3000にブラウザからアクセスし、コンソールログにFunctionsを呼び出した結果が表示されていることを確認する。

さらに、GitHubにPushし、デプロイ完了後、ブラウザからNetlifyドメインへアクセスし、同様にコンソールログを確認する。

さいごに

FaaS (Functions as as Service)を使ったサーバレスアーキテクチャは、ここ数年でかなり使いやすくなってきている印象です。

今回のNetlify Functions以外にも
- Google Cloud Functions
- AWS Lambda
- IBM Cloud Functions
- Azure Functions
- Twilio Functions
など、各クラウドベンダが提供しているFaaSもあるので、それらと比較してみると面白そうです。

また、Netlifyには他にも便利な機能があるみたいなので(Formsとか認証とか)、Netlify CLIと一緒に今後使ってみたいと思います。

Reference

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3