Slide 1

Slide 1 text

PagesとFunctionつかってGraphQLをSSR するサイトをNext.jsで作りたい Cloudflare Meetup Sapporo Kick Off! 2023-03-15 株式会社ゆめみ 藤原麻希 1

Slide 2

Slide 2 text

About me maki マキ 札幌生まれ札幌育ち、札幌でフルリモートワーク #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 2

Slide 3

Slide 3 text

Background Web系 サーバーサイドエンジニア PHP PHP / Laravel JSON入出力までが守備範囲 AWS CDK TypeScript DevOps YAMLエンジニア #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 3

Slide 4

Slide 4 text

Next.js React をベースにした Rendering Framework Vercel社が開発 #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 4

Slide 5

Slide 5 text

似た名前のツールがたくさん React - Next.js(フロントエンド) Vue.js - Nuxt.js(フロントエンド) Nest.js (サーバーサイド) #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 5

Slide 6

Slide 6 text

Motivation Webサイトを作りたい 社内では新規案件で標準採用されている Next.js をキャッチアップ 外部API呼び出し 自分でガッツリAPIは作りたくない DBのデータ表示 秘匿情報は安全に管理 #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 6

Slide 7

Slide 7 text

Next.js x レンダリング方法 CSR: Client-side rendering SSR: Server-side rendering ISR: Incremental Static Regeneration SSG: Static-site generation #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 7

Slide 8

Slide 8 text

CSR: Client-side rendering SPA (Single Page Application) webブラウザでJavaScriptでHTTPリクエストを投げるなど 配信はwebサーバー(+CDN) #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 8

Slide 9

Slide 9 text

SSG: Static-site generation ビルド時にDBや外部APIにアクセスしてデータ収集 *.html を生成する ビルド環境のみNode.jsが動けば良い webサーバーから配信(+CDN) #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 9

Slide 10

Slide 10 text

SSR: Server-side rendering 静的な部分はビルド時に生成 一部のデータを動的に生成 本番環境で Node.js | JavaScript が動く必要がある #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 10

Slide 11

Slide 11 text

ISR: Incremental Static Regeneration SSR + Cache キャッシュ期限が切れても一旦古い情報が返る 新しい情報を取得でき次第、表示を差し替える #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 11

Slide 12

Slide 12 text

#CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 12

Slide 13

Slide 13 text

Next.js with Vercel Next.js 開発元 が運営するクラウドサービス Next.js の全機能が使える チーム開発には向かない料金体系 #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 13

Slide 14

Slide 14 text

Next.js with AWS EC2, ECS, EKS, Lightsail, ElasticBeanstalk, App Runner + Node.js AWS Amplify Next.js 12 & 13 一部未対応の機能あり サーバーレス環境 Amazon S3: オブジェクトストレージ Amazon CloudFront: CDN Amazon Lambda (Lambda@Edge): 動的ルーティングに必要 バージニアリージョンにデプロイ #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 14

Slide 15

Slide 15 text

Next.js with Cloudflare Cloudflare Pages #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 15

Slide 16

Slide 16 text

半年ほど前まで すでにSSRは可能ではあった staticなファイル(HTML,CSS,画像)はPages アクセスに応じてスクリプトを動かす部分はWorkers(Edge) #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 16

Slide 17

Slide 17 text

Functions 登場 2022/11 Pages Pages Functions allows you to build full-stack applications by executing code on the Cloudflare network with Cloudflare Workers. https://developers.cloudflare.com/pages/platform/functions/ #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 17

Slide 18

Slide 18 text

Writing your Functions files in the /functions directory will automatically generate a Worker with custom functionality at predesignated routes. /functions ディレクトリにfunctionsを書くと、自動的にWorkerが作られる #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 18

Slide 19

Slide 19 text

Bindings KV Key-Value store Durable Object R2 Object Storage D1 Databases Environment variables Secrets etc #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 19

Slide 20

Slide 20 text

サンプルコード #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 20

Slide 21

Slide 21 text

Confiture the project To use the Edge Runtime next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, experimental: { runtime: 'experimental-edge', } } module.exports = nextConfig 個別ページで設定することも可能 #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 21

Slide 22

Slide 22 text

sample code (1) export default function post({ post }) { return (

POST id: {post.id}

{post.title}

{post.body}

); } #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 22

Slide 23

Slide 23 text

sample code (2) getServerSideProps import {GetServerSideProps} from "next"; export const getServerSideProps: GetServerSideProps = async (context) => { const id = context.params["post"]; const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`, { headers: { "api-key": "thisapikeyissecret", } }); const post = await res.json(); return { props: { post } }; }; #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 23

Slide 24

Slide 24 text

sample code (2) getServerSideProps import {GetServerSideProps} from "next"; export const getServerSideProps: GetServerSideProps = async (context) => { const id = context.params["post"]; const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`, { headers: { "api-key": process.env.API_KEY, } }); const post = await res.json(); return { props: { post } }; }; #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 24

Slide 25

Slide 25 text

Bindings KV Key-Value store Durable Object R2 Object Storage D1 Databases Environment variables Secrets etc #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 25

Slide 26

Slide 26 text

なにが嬉しいのか? Serverless より軽量な Edge Runtime できることが限られている分、シンプル スケーラブル 安全なPreview環境へのアクセス 最近増えてきている Serverless の Database サービス PostgreSQL REST API, GraphQL よりミニマムスタート&スケーラブル #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 26

Slide 27

Slide 27 text

付録 #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 27

Slide 28

Slide 28 text

Cloudflare にデプロイする方法 package追加 npm install -D @cloudflare/next-on-pages vercel #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 28

Slide 29

Slide 29 text

next.config.js next.config.js にruntimeの指定を追加 個別ページでの指定も可能 /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, experimental: { runtime: 'edge', } } module.exports = nextConfig #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 29

Slide 30

Slide 30 text

TypeScript @cloudflare/workers-types@latest tsconfig.js "compilerOptions": { "target": "esnext", "module": "esnext", "lib": ["esnext"], "types": ["@cloudflare/workers-types"] } } #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 30

Slide 31

Slide 31 text

ローカルで動作確認 wrangler pages dev -- npm run dev 解説 ローカルで Pages の Functions を動かす npm run dev で動くNext.jsをProxyする #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 31

Slide 32

Slide 32 text

ローカルから直接デプロイ Build npx @cloudflare/next-on-pages --experimental-minify Publish wrangler pages publish .vercel/output/static https://github.com/cloudflare/pages-action #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 32

Slide 33

Slide 33 text

GitHub Actions # Run a build step here if your project requires - uses: cloudflare/pages-action@1 with: accountId: ${{ vars.CLOUDFLARE_ACCOUNT_ID }} apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} projectName: ${{ vars.CLOUDFLARE_PROJECT_NAME }} directory: ".vercel/output/static" gitHubToken: ${{ secrets.GITHUB_TOKEN }} https://github.com/cloudflare/next-on-pages #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 33

Slide 34

Slide 34 text

Git連携デプロイ 事前に連携しておいたGitリポジトリ(現在GitHubのみ) Frameworkごとにビルドコマンドとdistディレクトリの指定 pushすると自動デプロイ CIが必要なければ一番お手軽で始めやすい #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 34

Slide 35

Slide 35 text

Pages Docs Deploy a Next.js site https://developers.cloudflare.com/pages/framework-guides/deploy-a-nextjs-site/ #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 35

Slide 36

Slide 36 text

参考ページ Cloudflare PagesにNext.jsをデプロイするとSSRが動作するようになったのでどうやって実 現されたのかを調べた https://zenn.dev/laiso/articles/c086dd115f5d4e @cloudflare/next-on-pagesというビルドツールが新規に開発されNext.jsプロジェクト を解析して _worker.js とCloudflare Workersにデプロイする各エンドポイントを生成し てくれるようになった。 #CloudflareUG_cts PagesとFunctionつかってGraphQLをSSRするサイトをNext.jsで作りたい / Cloudflare Meetup Sapporo Kick Off! 36