type
status
date
slug
summary
tags
category
icon
password
URL
Link
Publish Time
Podcast
前言
留言
Cloudflare pages 可以根據 github commit 建立每個 Pull Request 的 staging 網頁
有這樣的 staging deployment 可以有利於 PR review 及 debug。
我們也可以用 Cloudflare 提供的 pages/workers 建立 serverless framework 處理 API,省去架設伺服器的困難及成本。
並用 D1 database 儲存資料,避免 serverless 狀態被清除。
文件
pages: https://developers.cloudflare.com/pages
d1: https://developers.cloudflare.com/d1
部署 Next.js site
參考 Pages: Deploy a Next.js site
Create 一個 next.js project
npm create cloudflare@latest nextjs-pages-example -- --framework=next
設定 config
接著進入資料夾
cd nextjs-pages-example
原本應該就有個 default 的 api/hello
上傳到 Github
git remote add origin https://github.com/<GITHUB_USER_NAME>/nextjs-pages-example.git
git branch -M main
git push -u origin main
到 Cloudflare Workers 和 Pages
建立應用程式
選擇 Pages 的 tab,並選連線至 Git
選擇 project 的 repository
並按 開始設定
選擇 Next.js 的設定
進到 設定 中的 函數
選擇相容性日期: 2022-11-30 (生產跟預覽)
設定相容性旗標: nodejs_compat (生產跟預覽)
再部署一次
可以在新的 url 下呼叫 api/hello
e.g. https://c030509d.nextjs-pages-example.pages.dev/api/hello
建立 D1 database
參考 D1: Get Started
登入 Cloudflare
npx wrangler login
新增 database 名稱為 prod-d1-tutorial
npx wrangler d1 create prod-d1-tutorial
如果成功會出現 d1 資訊
[[d1_databases]]
binding = "DB" # available in your Worker on env.DB
database_name = "prod-d1-tutorial"
database_id = "<unique-ID-for-your-database>"
在 root 建立一個 wrangler.toml 檔案
[[d1_databases]]
binding = "DB" # available in your Worker on env.DB
database_name = "prod-d1-tutorial"
database_id = "<unique-ID-for-your-database>"
在 root 建立一個 schema.sql 檔案
DROP TABLE IF EXISTS Customers;
CREATE TABLE IF NOT EXISTS Customers (CustomerId INTEGER PRIMARY KEY, CompanyName TEXT, ContactName TEXT);
INSERT INTO Customers (CustomerID, CompanyName, ContactName) VALUES (1, 'Alfreds Futterkiste', 'Maria Anders'), (4, 'Around the Horn', 'Thomas Hardy'), (11, 'Bs Beverages', 'Victoria Ashworth'), (13, 'Bs Beverages', 'Random Name');
執行此 sql 指令
npx wrangler d1 execute prod-d1-tutorial --local --file=./schema.sql
若帶上 --local 的 flag 則表示只在 local 執行,不會變更到 Cloudflare D1 裡的資料
並會在 root 資料夾新增一個 .wrangler 資料夾
儲存 D1 的資料
檢查是否儲存成功
npx wrangler d1 execute prod-d1-tutorial --local --command="SELECT * FROM Customers"
會回傳
🌀 Mapping SQL input into an array of statements
🌀 Executing on local database prod-d1-tutorial (21c8234f-e616-4128-93bc-b65ff78b73f5) from .wrangler/state/v3/d1:
┌────────────┬─────────────────────┬───────────────────┐
│ CustomerId │ CompanyName │ ContactName │
├────────────┼─────────────────────┼───────────────────┤
│ 1 │ Alfreds Futterkiste │ Maria Anders │
├────────────┼─────────────────────┼───────────────────┤
│ 4 │ Around the Horn │ Thomas Hardy │
├────────────┼─────────────────────┼───────────────────┤
│ 11 │ Bs Beverages │ Victoria Ashworth │
├────────────┼─────────────────────┼───────────────────┤
│ 13 │ Bs Beverages │ Random Name │
└────────────┴─────────────────────┴───────────────────┘
若要上傳此 data 到 D1 則把 --local flag 去掉
建立呼叫 D1 的 API
在 root 建立一個 env.d.ts 的檔案
參考 Pages: Use bindings in your Next.js application
declare global {
namespace NodeJS {
interface ProcessEnv {
[key: string]: string | undefined;
DB: D1Database;
}
}
}
export { };
建立一個 src/app/api/db/route.ts 的檔案
回傳 DB 中的資料
import type { NextRequest } from 'next/server'
export const runtime = 'edge'
export async function GET(request: NextRequest) {
const { results } = await process.env.DB.prepare(
"SELECT * FROM Customers WHERE CompanyName = ?"
)
.bind("Bs Beverages")
.all();
return new Response(JSON.stringify(results));
}
設定 D1 資料庫繫結 DB = prod-d1-tutorial(生產和預覽)
此時 push code 到 github,就能看到新 deploy 的 pages 有 api/db 回傳 D1 的資料。 e.g. https://c97ea8ef.nextjs-pages-example.pages.dev/api/db
如何在 local 測試 D1 pages
參考 Pages: Interact with your D1 databases locally
用在 cloudflare 的設定 build:
npx @cloudflare/next-on-pages@1
⚠️ 每次更動 router 都必須執行此指定一次。
也必須重開 server
用 npx wrangler pages dev 啟動 server,並設定以下 flags
npx wrangler pages dev .vercel/output/static \
--compatibility-date 2022-11-30 \
--compatibility-flag nodejs_compat \
--d1 DB=<unique-ID-for-your-database>
e.g. 我的 id = 21c8234f-e616-4128-93bc-b65ff78b73f5
npx wrangler pages dev .vercel/output/static \
--compatibility-date 2022-11-30 \
--compatibility-flag nodejs_compat \
--d1 DB=21c8234f-e616-4128-93bc-b65ff78b73f5
雖然不是真的跟 Cloudflare的 D1 互動,但是還是要用 cloudflare 上的 db id
成果
Github: https://github.com/vivianjeng/nextjs-pages-example
Pages link: https://nextjs-pages-example.pages.dev